向HtmlAgilityPack道歉:解析HTML还是你好用

简介:

原文:http://www.cnblogs.com/rupeng/archive/2012/02/07/2342012.html

 

去年写过一篇文章《解析HTML最好的类还是微软自己的》,回复中有朋友提到可以使用HtmlAgilityPack来进行HTML的解析。当时只是匆匆的测试了一下,发现HtmlAgilityPack得到的InnerText中有很多的不干净的script、样式内容,就断定“不是很满意,解析DiscuzNT!论坛的帖子页面的时候有问题,没法正确得到Body.InnerText的内容,有很多残留html、js代码夹杂在其中,解析的不是很好。”

 

传智播客.net培训学院内部有一个工具是我开发的,其中的HTML解析部分就是我使用MSHTML完成的,但是今天发现这个软件一个Bug,是MSHTML的HTMLDocumentClass在多线程并发时候有时候会造成死锁。MSHTML是工作在UI线程中的(如果不把DesignMode设置为On,则HTML中的javascript会被执行就是证明),并不是一个干净的、独立的HTML解析组件,因此出现这样的问题很难调试。因此决定还是换用向HtmlAgilityPack实现。


那么如何解决HtmlAgilityPack得到的InnerText中有残留的script、样式的问题呢,在google上搜索“HtmlAgilityPack script innerText”找到了stackoverflow上的这篇文章《C#: HtmlAgilityPack extract inner text》

代码如下:

复制代码
foreach(var script in doc.DocumentNode.Descendants("script").ToArray())
script.Remove();
foreach(var style in doc.DocumentNode.Descendants("style").ToArray())
style.Remove();

string innerText = doc.DocumentNode.InnerText;
复制代码

 

原来这样简单呀,就是把所有的script、style标签从dom树中去掉(为了解决迭代器在工作时不能从集合中Remove元素的问题,使用ToArray()转换为数组再遍历)。

这样操作发现还是有残留的script:

复制代码
<!--[if IE]>
<script language="JavaScript"> var objmain = document.getElementById("main"); function updatesize(){ var bodyw = window.document.body.offsetWidth; var w=(bodyw<=790?"790px":"100%"); objmain.style.width=w; } updatesize(); window.onresize = updatesize; </script>
<![endif]-->
复制代码

 

仔细一看原来是带条件注释的script,因此用下面的方法去掉所有的注释节点:

代码如下:

复制代码
foreach(var script in doc.DocumentNode.Descendants("script").ToArray())
script.Remove();
foreach(var style in doc.DocumentNode.Descendants("style").ToArray())
style.Remove();

foreach (var comment in doc.DocumentNode.SelectNodes("//comment()").ToArray())
comment.Remove();//新增的代码

string innerText = doc.DocumentNode.InnerText;
复制代码

 

解释:HtmlAgilityPack是使用XPath语法,"//comment()"在XPath中表示“所有注释节点”,关于XPath的详细用法请参考XPath的资料。

其他可能有用的技术点:
1、获取网页title:doc.DocumentNode.SelectSingleNode("//title").InnerText; 
解释:XPath中“//title”表示所有title节点。SelectSingleNode用于获取满足条件的唯一的节点。


2、获取所有的超链接:doc.DocumentNode.Descendants("a")


3、获取name为kw的input,也就是相当于getElementsByName():
            var kwBox = doc.DocumentNode.SelectSingleNode("//input[@name='kw']");

解释:"//input[@name='kw']"也是XPath的语法,表示:name属性等于kw的input标签。

 

经过这次使用HtmlAgilityPack得出结论:还是HtmlAgilityPack强大!!!再见MSHTML!


本文转自火地晋博客园博客,原文链接:http://www.cnblogs.com/yelaiju/archive/2012/02/13/2349213.html,如需转载请自行联系原作者

目录
相关文章
|
2月前
|
JavaScript 前端开发 数据可视化
html解析过程
html解析过程【2月更文挑战第26天】
23 6
|
2月前
|
XML 前端开发 数据格式
请描述如何使用`BeautifulSoup`或其他类似的库来解析 HTML 或 XML 数据。
【2月更文挑战第22天】【2月更文挑战第67篇】请描述如何使用`BeautifulSoup`或其他类似的库来解析 HTML 或 XML 数据。
|
4月前
|
小程序 JavaScript 数据库
小程序解析富文本html内容
小程序解析富文本html内容
|
4天前
|
前端开发 JavaScript
浏览器通过构建DOM树来解析HTML代码
【4月更文挑战第30天】浏览器通过构建DOM树来解析HTML代码
19 1
|
15天前
|
数据采集 XML 数据挖掘
使用Python打造爬虫程序之HTML解析大揭秘:轻松提取网页数据
【4月更文挑战第19天】本文介绍了HTML解析在爬虫技术中的重要性,并通过Python的BeautifulSoup库展示了如何解析和提取数据。文章涵盖了HTML文档结构、使用BeautifulSoup的基本方法,如`find_all()`、选择器(标签、类、ID选择器)以及提取文本、属性和链接。此外,还讨论了遍历和处理嵌套元素的技巧。
|
27天前
|
数据采集 JavaScript 前端开发
使用 cheerio 解析本地 html 文件
使用 cheerio 解析本地 html 文件
24 1
|
28天前
|
前端开发 JavaScript
HTML深度解析:更改文本颜色
【4月更文挑战第1天】
43 0
HTML深度解析:更改文本颜色
|
28天前
|
前端开发 JavaScript C++
HTML深度解析:掌握换行的艺术
【4月更文挑战第1天】
38 0
HTML深度解析:掌握换行的艺术
|
5天前
|
缓存 Java 开发者
10个点介绍SpringBoot3工作流程与核心组件源码解析
Spring Boot 是Java开发中100%会使用到的框架,开发者不仅要熟练使用,对其中的核心源码也要了解,正所谓知其然知其所以然,V 哥建议小伙伴们在学习的过程中,一定要去研读一下源码,这有助于你在开发中游刃有余。欢迎一起交流学习心得,一起成长。
|
6天前
|
安全 网络协议 Java
Netty核心NioEventLoop源码解析(下)
Netty核心NioEventLoop源码解析(下)
19 0

推荐镜像

更多