【转】 HTML解析:基于XPath的C#类库HtmlAgiliytyPack

【转】 HTML解析:基于XPath的C#类库HtmlAgiliytyPack

最近处于毕业设计开始阶段,前期工作需要去国外的一些专业数据库网站比对一些所需TF家族信息,为了快捷方便,想到用程序去帮助实现。前期实现了一系列的尝试,使用C#的的网络编程类库,获取查询结果,但是为了分析其中的结果并进行比对,我最开始尝试了两天之久的正则表达式,最后发现在解析这样的HTML文档的时候,花费时间太多,因此开始改变策略,最后得知MSHTML和HAP这两个.NET解析html的类库,出于对HAP这个轻量级类库兴趣,决定使用它来解析获取信息。

一、HAP简介

HAP是codeplex公司的一个解析html的.NET开源项目,支持XPath查询。官网(http://htmlagilitypack.codeplex.com/)给出的介绍是:

What is exactly the Html Agility Pack (HAP)?

This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don‘t HAVE to understand XPATH nor XSLT to use it, don‘t worry...). It is a .NET code library that allows you to parse "out of the web" HTML files. The
parser is very tolerant with "real world" malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams).

目前最新版本为HAP1.4.6,推出的新特性是支持Linq语言。

二、XPath

为了更好的使用HAP,必须了解XPath语言。维基百科介绍如下:

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。

XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初XPath的提出的初衷是将其作为一个通用的、介于XPointer与XSL间的语法模型。但是XPath很快的被开发者采用来当作小型查询语言。

XPath中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释、根节点。节点关系有:Parent、Children、Sibling、Ancestor、Descendent。

路径表达式用来选取节点或节点集,通过路径(path)步(steps)进行选取。

节点表达式:

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。
路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore
选取根元素 bookstore。

注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性

谓语:用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中

路径表达式 结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=‘eng‘] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

通配符:

通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

选取多个路径时,使用 “ | ”符号。

步(Step):语法为  轴名称::节点测试[谓语]

轴(axis)-------------------------------定义所选节点与当前节点之间的树关系

节点测试(node-test)----------------识别某个轴内部的节点

零个或多个谓语(predicate)--------更深入提炼所选的节点集

XPath轴:

轴名称 结果
ancestor 选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute 选取当前节点的所有属性。
child 选取当前节点的所有子元素。
descendant 选取当前节点的所有后代元素(子、孙等)。
descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following 选取文档中当前节点的结束标签之后的所有节点。
namespace 选取当前节点的所有命名空间节点。
parent 选取当前节点的父节点。
preceding 选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling 选取当前节点之前的所有同级节点。
self 选取当前节点。

XPath可以使用运算符:

运算符 描述 实例 返回值
| 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
+ 加法 6 + 4 10
- 减法 6 - 4 2
* 乘法 6 * 4 24
div 除法 8 div 4 2
= 等于 price=9.80
如果 price 是 9.80,则返回 true。

如果 price 是 9.90,则返回 false。

!= 不等于 price!=9.80
如果 price 是 9.90,则返回 true。

如果 price 是 9.80,则返回 false。

< 小于 price<9.80
如果 price 是 9.00,则返回 true。

如果 price 是 9.90,则返回 false。

<= 小于或等于 price<=9.80
如果 price 是 9.00,则返回 true。

如果 price 是 9.90,则返回 false。

> 大于 price>9.80
如果 price 是 9.90,则返回 true。

如果 price 是 9.80,则返回 false。

>= 大于或等于 price>=9.80
如果 price 是 9.90,则返回 true。

如果 price 是 9.70,则返回 false。

or price=9.80 or price=9.70
如果 price 是 9.80,则返回 true。

如果 price 是 9.50,则返回 false。

and price>9.00 and price<9.90
如果 price 是 9.80,则返回 true。

如果 price 是 8.50,则返回 false。

mod 计算除法的余数 5 mod 2 1

XPath有一百多个函数,常用在谓语中选择的函数有

position() 表示当前节点的序号

last() 表示取最后一个节点

name() 表示当前节点名字

在.NET中可以使用XPath处理XML文档,此处的html解析就是运用XPath查询选择。

三、HAP使用

1、下载HtmlAgilityPack最新压缩包,http://htmlagilitypack.codeplex.com/releases/view/90925,官方下载地址。

2、加压后,在所需项目中添加引用HtmlAgilityPack.dll文件,其中还附带了xml文件用于文档说明。然后添加using HtmlAgilityPack说明。如下图所示:

3、实际使用中,都是以HtmlDocument类为主线。HAP提供了两种不同方式加载HtmlDocument类的实例:从html字符串构造(可以使用LoadHtml方法和Load方法),从html文档流构造实例(使用Load方法)。从而就可以实例化一个DOM实例,对于客户端脚本语言JavaScript熟悉的开发者来说这是非常熟悉的。这些操作也与.net framework中的XmlDocument类对于XML文档的操作非常类似,而且XML操作中也支持使用XPath表达式的查询使用,不同的是HtmlDocument强化了GetElementById方法,可以直接使用定位。示例代码如下:

            HtmlDocument hd = new HtmlDocument();
            hd.LoadHtml(fileStr);
            HtmlNode root = hd.DocumentNode;
            HtmlNodeCollection hNodes = root.SelectNodes("//tr[@class=‘odd‘]|//tr[@class=‘even‘]/td[@class=‘rowNum‘]");

4、后续的使用需要依照自己的实际需求来设计。对于html文档的解析主要就是使用XPath表达式进行选择定位,可以参考http://www.w3school.com.cn/xpath/xpath_syntax.asp

5、去除script和style等标签。当使用document.DocumentNode.InnerText获取文档内容时会包含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();

6、在下载的HtmlAgilityPack压缩包中还找到了关于WindowsPhone开发需要的dll文件,因此对于开发WP手机应用也是非常的有效。

HtmlAgilityPack对于html页面的解析、信息采集的准确度和效率都优于使用正则表达式,而且对开发者非常友好,特别是正则表达式的学习曲线较陡,而且其中包含了很多的技巧,特别是对高效的正则表达式的书写是非常需要经验的。HtmlAgilityPack获取html文档时对原文本的结构要求是非常宽松的,这与XmlDocument的严格要求是不同的。基本上熟悉了XPath的语法之后,大部分应用都可以满足要求了。

参考资料:

1、HAP:简单好用的html解析器:http://msdn.microsoft.com/zh-tw/ee787055.aspx

2、XPath维基百科:http://zh.wikipedia.org/zh-cn/XPath

3、W3C school:http://www.w3school.com.cn/xpath/xpath_syntax.asp

4、C#:HtmlAgilityPack extract inner text:http://stackoverflow.com/questions/2785092/c-htmlagilitypack-extract-inner-text

时间: 2024-11-05 02:17:52

【转】 HTML解析:基于XPath的C#类库HtmlAgiliytyPack的相关文章

Csharp调用基于Opencv编写的类库文件

现在将Csharp调用基于Opencv编写的类库文件(Dll)的方法定下来,我取名叫做GreenOpenCsharpWarper,简称GOCW. 一.CLR编写的DLL部分 1.按照正常方法引入Opencv; 2.提供接口函数,进行图像处理(这里只是实现了cvtColor,实际过程中可以用自己编写的复杂函数) String^  Class1::Method(cli::array<unsigned char>^ pCBuf1){     pin_ptr<System::Byte> p

PHP-ExcelReader:用于解析excel文件的PHP类库

PHP-ExcelReader是一个基于PHP的开源项目,其作用在于解析excel文件. PHP-ExcelReader的官方网张如下: http://phpexcelreader.sourceforge.net/ 下载下来的文件结构如下图所示: 其中,Excel目录下的两个文件reader.php和oleread.inc是excel解析必须包含的文件,解析所需要的类与方法分别写在这两个文件之中.其它的,example.php和example2.php两个文件是示例程序,jxlwtest.xls

爬虫之解析库Xpath

简介 XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言. XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力.起初XPath的提出的初衷是将其作为一个通用的.介于XPointer与XSL间的语法模型.但是XPath很快的被开发者采用来当作小型查询语言. 语法 选取节点 XPath 使用路径表达式在 XML 文档中选取节点.节点是通过沿着路径或者 step 来选取的. [1] 下面列出了最有用的路径表达式: 表达式 描述

解析库Xpath使用

简介 XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言. XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力.起初XPath的提出的初衷是将其作为一个通用的.介于XPointer与XSL间的语法模型.但是XPath很快的被开发者采用来当作小型查询语言. 语法 选取节点 XPath 使用路径表达式在 XML 文档中选取节点.节点是通过沿着路径或者 step 来选取的. [1] 下面列出了最有用的路径表达式: 表达式 描述

Java XML DOM解析(xPath)

(一) XML概念 在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等.它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据.是Internet环境中跨平台的.依赖于内容的技术,也是当今处理分布式结构信息的有效工具.早在1998年,W3C就发布了XML1.0规范,使用它来简化Internet的文档信息传输. (二)XML作用 1.

基于rollup搭建JavaScript类库开发环境

平时开发过程中,积累了不少的经验和技巧都应用到项目中,而下次用到的时候却又开始到处翻. 有时也想自己搭建个类库或工具包什么的来积累自己的经验技巧,又没有专门的时间去搭建各种 环境,像rollup或者webpack这样的打包工具.ES6转码工具Babel.Eslint.Jest测试工具等等. 这里就特意做了一个起始项目,将rollup.ES6转码.Eslint.Jest都集成起来,平时用的时候只需要 积累模块和方法即可. 本文参考:基于Webpack和ES6打造Javascript类库 http:

爬虫的两种解析方式 xpath和bs4

1.xpath解析 from lxml import etree 两种方式使用:将html文档变成一个对象,然后调用对象的方法去查找指定的节点 (1)本地文件 tree = etree.parse(文件名) ===>保存的本地文件路径放入 (2)网络文件 tree = etree.HTML(网页字符串) ==>直接把得到的网页字符串作为参数传入 ret = tree.xpath(路径表达式) [注]ret是一个列表,所以要用ret需要对之进行处理 参考文献:w3c  xpath - 安装xpa

非结构化数据与结构化数据提取----XPath与lxml类库

什么是XML XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 的标签需要我们自行定义. XML 被设计为具有自我描述性. XML 是 W3C 的推荐标准 W3School官方文档:http://www.w3school.com.cn/xml/index.asp XML 和 HTML 的区别 数据格式 描述 设计目标 XML Extensible Markup Langu

Python3编写网络爬虫05-基本解析库XPath的使用

一.XPath 全称 XML Path Language 是一门在XML文档中 查找信息的语言 最初是用来搜寻XML文档的 但是它同样适用于HTML文档的搜索 XPath 的选择功能十分强大,它提供了非常简洁的路径选择表达式,另外还提供了超过100个内置函数,用于字符串,数值,时间的匹配以及节点和序列的处理 XPath 于1999年11月16日成为W3C标准 被设计为供XSLT.XPointer.以及其它XML解析软件使用 1 <<< 2 常用规则 3 4 表达式 描述 5 6 node