IHTMLDOMNode的删除操作

大狗狗 2011-08-11 08:56:02
环境:VS2005 C# WinForm IE8

当网页加载完后,我遍历网页的DOM树,找到position属性为fixed的div节点。如果该节点下还包括img、object或iframe节点,就删除掉div节点。用处你们懂的--过滤右下角和两侧广告。

为稳妥起见,我使用IE的开发人员工具做为参考。运行结果是,符合要求的div标签被捕获到了,然后调用IHTMLDOMNode的removeNode(true)删除。

让我不解的是,有些网站的广告div过滤掉了,有些则不行。换成parentNode.removeChild(node)--如果有父结点,也删不掉。比如说金山在线翻译,你查询一个单词后,右下角会出来一个广告窗口。网页比较简单,用IE开发人员工具一看,那个广告div一目了然,也就是说不可能存在我捕获错误的情况。我确实捕获到了那个div,而且,removeNode没有返回null,说明执行成功了,但广告div就是不消失。

请指教

private void button2_Click(object sender, EventArgs e)//点击按钮进行过滤测试
{
IHTMLDocument3 HTMLDocument = (IHTMLDocument3)this.webBrowser1.Document.DomDocument;
IHTMLDOMNode rootDomNode = (IHTMLDOMNode)HTMLDocument.documentElement;
IHTMLDOMNode bodyNode = null;

if (rootDomNode.hasChildNodes())
{
IHTMLDOMChildrenCollection allchild = (IHTMLDOMChildrenCollection)rootDomNode.childNodes;
int length = allchild.length;
for (int i = 0; i < length; i++)
{
IHTMLDOMNode child_node = (IHTMLDOMNode)allchild.item(i);
if (string.Equals(child_node.nodeName,"body",StringComparison.OrdinalIgnoreCase))
{
bodyNode = child_node;
break;
}
}
}

ArrayList del = new ArrayList();

if (bodyNode != null && bodyNode.hasChildNodes())
{
IHTMLDOMChildrenCollection allchild = (IHTMLDOMChildrenCollection)bodyNode.childNodes;
int length = allchild.length;
for (int i = 0; i < length; i++)
{
IHTMLDOMNode child_node = (IHTMLDOMNode)allchild.item(i);
if (string.Equals(child_node.nodeName, "div", StringComparison.OrdinalIgnoreCase))
{
IHTMLDOMNode fix = GetFixedDiv(child_node);

if(fix != null)
{
if (NeedFilter(fix))
{ del.Add(fix); }
}
}
}

for (int i = 0; i < del.Count;++i )
{
IHTMLDOMNode node = (IHTMLDOMNode)del[i];
if (node.hasChildNodes())
{
IHTMLDOMChildrenCollection allchild0 = (IHTMLDOMChildrenCollection)node.childNodes;
int length0 = allchild0.length;

for (int j = 0; j < length0; j++)
{
IHTMLDOMNode child_node = (IHTMLDOMNode)allchild.item(j);
child_node.removeNode(true);
}
}

//if(node.parentNode != null)
//{ node.parentNode.removeChild(node); }

node.removeNode(true);
}
}
}

private IHTMLDOMNode GetFixedDiv(IHTMLDOMNode div)
{
if(div != null)
{
IHTMLStyle style = ((IHTMLElement)div).style;
if (string.Equals("fixed", style.position, StringComparison.OrdinalIgnoreCase))
{
return div;
}

if (div.hasChildNodes())
{
IHTMLDOMChildrenCollection allchild = (IHTMLDOMChildrenCollection)div.childNodes;
int length = allchild.length;

for (int i = 0; i < length; i++)
{
IHTMLDOMNode child_node = (IHTMLDOMNode)allchild.item(i);
if (string.Equals(child_node.nodeName, "div", StringComparison.OrdinalIgnoreCase))
{
IHTMLDOMNode re = GetFixedDiv(child_node);
if(re != null)
{ return re; }
}
}
}
}
return null;
}

private bool NeedFilter(IHTMLDOMNode node)
{
if (node != null && node.hasChildNodes())
{
//this.textBox1.Text += "\n\n";

IHTMLDOMChildrenCollection allchild = (IHTMLDOMChildrenCollection)node.childNodes;
int length = allchild.length;
for (int i = 0; i < length; i++)
{
IHTMLDOMNode child_node = (IHTMLDOMNode)allchild.item(i);
//this.textBox1.Text += (child_node.nodeName + "\n");

if (string.Equals(child_node.nodeName, "img", StringComparison.OrdinalIgnoreCase) ||
string.Equals(child_node.nodeName, "object", StringComparison.OrdinalIgnoreCase) ||
string.Equals(child_node.nodeName, "iframe", StringComparison.OrdinalIgnoreCase))
{
return true;
}

if (NeedFilter(child_node))
{ return true; }
}
}
return false;
}
...全文
180 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
Windows api up!!!!
独自听枫 2011-08-12
  • 打赏
  • 举报
回复
通过LZ的条件,真的可以完全判断出该标签为广告吗?

如果div属性是全受javascript控制的广告呢?
小弟菜鸟 2011-08-12
  • 打赏
  • 举报
回复
我来排队
yann2 2011-08-12
  • 打赏
  • 举报
回复
我来接分的
大狗狗 2011-08-12
  • 打赏
  • 举报
回复
还是自己回答吧:

原先代码有一个缺陷:就是除了div,span也可能做为层的容器。知道了这一点,问题就解决了。
大狗狗 2011-08-11
  • 打赏
  • 举报
回复
经测试 广告div确实从dom列表里消失了,但网页上它却还在显示,搞不懂。

110,532

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧