Html Agility Pack下载地址:http://htmlagilitypack.codeplex.com/

Html Agility Pack 源码中的类大概有28个左右,其实不算一个很复杂的类库,但它的功能确不弱,为解析DOM已经提供了足够强大的功能支持,可以跟jQuery操作DOM媲美:)

基础类和基础方法介绍

Html Agility Pack最常用的基础类其实不多,对解析DOM来说,就只有HtmlDocument和HtmlNode这两个常用的类,还有一个 HtmlNodeCollection集合类。

HtmlDocument类

当然在解析DOM前需要加载html原始文件或者html的字符串,HtmlDocument类封装了支持此功能的方法,下面是加载html的方法介绍。

HtmlDocument类定义了多个重载的Load方法来实现以不同方式加载html,其实主要分为两种,一种是从Stream中加载html,另外一种是从物理路径加载html,分别见下面:

方法:public void Load(TextReader reader)
说明:从指定的 TextReader对象中加载Html
示例

HtmlDcument doc =new HtmlDocument();

StreamReader sr = File.OpenText("file path");

doc.Load(sr);

基于上面方法,衍生出了几个不同重载方法。

以指定的Stream对象为主的有:

(1)public void Load(Stream stream)    ///从指定的Stream对象中加载html;

(2)public void Load(Stream stream, bool detectEncodingFromByteOrderMarks)    ///指定是否从顺序字节流中解析编码格式

(3)public void Load(Stream stream, Encoding encoding)    ///指定编码格式

(4)public void Load(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)

(5)public void Load(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int buffersize)

以指定的物理路径为主的有:

(1)public void Load(string path)

(2)public void Load(string path, bool detectEncodingFromByteOrderMarks)    ///指定是否从顺序字节流中解析编码格式

(3)public void Load(string path, Encoding encoding)    ///指定编码格式

(4)public void Load(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks)

(5)public void Load(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int buffersize)

HtmlDocument类中还定义了直接从html字符串中加载Html,如下:

方法:public void LoadHtml(string html)
说明:从指定的html字符串中加载html
示例

HtmlDocument doc =new HtmlDocument();

string html ="<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span></div>";

doc.LoadHtml(html);

HtmlDocument类还有其他写DOM方法的定义,这里不作详细介绍,留作以后专门介绍Html Agility Pack写DOM章节介绍吧,这里着重介绍Html Agility pack解析DOM的细节。

HtmlNode类和HtmlNodeCollection类

通过HtmlDocument把html加载进来后,接着是要做什么呢?当然是对html解析了,解析DOM就需要提到HtmlNode类
了。 HtmlDocument类由属性DocumentNode属性返回当前Html解析后的一个全局的HtmlNode对象;如果想获取某一个元素的
HtmlNode,可以通过HtmlDocument类的GetElementbyId(string
Id)方法来获取,返回指定某一个html元素的HtmlNode对象。如何通过HtmlNode对象来访问DOM呢?介绍之前先对它的功能了解下。

HtmlNode类实现了IXPathNavigable接口,这说明了它可以通过xpath来查询DOM了,如果对System.Xml
命名空间下的
XmlDocument类了解的,特别是使用过了SelectNodes()和SelectSingleNode()方法的朋友对使用HtmlNode类
将会很熟悉。其实Html Agility
Pack内部是把html解析成xml文档格式了的,所以支持xml中的一些常用查询方式。下面对HtmlNode的一些主要的常用成员作简要的说明。

HtmlNode类的主要属性

1)Attributes属性

获取当前Html元素的属性的集合,返回的是一个HtmlAttributeCollection对象。如一个div元素,它可能会定义一些属性,
如:<div id="title" name="title" class="class-name" title="title
div">***</div>,那Attributes返回的HtmlAttributeCollection就包含了
“id,name,class,title”的信息。HtmlAttributeCollection类是实现了接口
IList<HtmlAttribute>的一个集合类,故此可以通过下面代码方式访问每一个成员。

HtmlNode node = doc.GetElementbyId("title");

string titleValue = node.Attributes["title"].Value;

或者

 
foreach(HtmlAttribute attr in node.Attributes) { Console.WriteLine("{0}={1}",attr.Name,attr.Value); }
 

在获取属性值时,如果某一个属性名称不存在的话,Attributes["name"]返回的是null值。

2)FirstChild,LastChild,ChildNodes,ParentNode属性

FirstChild属性:返回所有子节点的第一个节点,如下面代码:

string html ="<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span><div id="innerDiv">inner div</div></div>";

FirstChild则返回的是“<span style="color:red;"><h1>Hello World!</h1></span>” 的节点。

LastChild属性:返回所有子节点的最后一个节点,以上面的html为例,则返回“<div id="innerDiv">inner div</div>”节点。

ChildNodes属性:返回当前节点所有直接一代的子节点的集合,不包括跨代子节点,以上面的html为例,则返回“<span
style="color:red;"><h1>Hello World!</h1></span>”
和“<div id="innerDiv">inner div</div>”两个节点。

ParentNode属性:返回当前节点的直接父节点。

3)获取Html源码和文本

HtmlNode类设计了OuterHtml属性和InnerHtml属性用于获取当前节点的Html源码。两者不同之处
是,OuterHtml属性返回的是包含当前节点的Html代码在内的所有Html代码,而InnerHtml属性返回的是当前节点里面子节点的所有
Html代码。如下面:


HtmlDocument doc =new HtmlDocument();

string html ="<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span></div>";

doc.LoadHtml(html);

HtmlNode node = doc.HtmlDocument;

Console.WriteLine(node.OuterHtml); /// return "<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span></div>";
Console.WriteLine(node.InnerHtml); /// return "<span style="color:red;"><h1>Hello World!</h1></span>";

如要获取节点的文本值,通过InnerText属性来获取,InnerText属性过滤掉了所有的Html标记代码,只返回文本值,如下面:

Console.WriteLine(node.InnerText);/// return "Hello World!";

HtmlNode类的主要方法

HtmlNode类提供了足够丰富的方法供查询当前节点下的子节点(元素),当然也包括查询当前节点的父节点(元素)的方法,下面列出主要的方法和使用说明。

获取父节点的系列方法:

1)public IEnumerable<HtmlNode> Ancestors()

获取当前节点的父节点列表(不包含自身)。

2)public IEnumerable<HtmlNode> Ancestors(string name)

以指定一个名称来获取父节点的列表(不包含自身)。

3)public IEnumerable<HtmlNode> AncestorsAndSelf()

获取当前节点的父节点列表(包含自身)。

4)public IEnumerable<HtmlNode> AncestorsAndSelf(string name)

以指定一个名称来获取父节点的列表(包含自身)。

获取子节点的系列方法:

1)public IEnumerable<HtmlNode> DescendantNodes()

获取当前节点下的所有子节点的列表,包括子节点的子节点(不包含自身)。

2)public IEnumerable<HtmlNode> DescendantNodesAndSelf()

获取当前节点下的所有子节点的列表,包括子节点的子节点(包含自身)。

3)public IEnumerable<HtmlNode> Descendants()

获取当前节点下的直接子节点的列表(不包含自身)。

4)public IEnumerable<HtmlNode> DescendantsAndSelf()

获取当前节点下的直接子节点的列表(包含自身)。

5)public IEnumerable<HtmlNode> Descendants(string name)

获取当前节点下的以指定名称的子节点列表。

6)public IEnumerable<HtmlNode> DescendantsAndSelf(string name)

获取当前节点下的以指定名称的子节点的列表(包含自身)。

7)public HtmlNode Element(string name)

获取第一个符合指定名称的直接子节点的节点元素。

8)public IEnumerable<HtmlNode> Elements(string name)

获取符合指定名称的所有直接子节点的节点列表。

9)public HtmlNodeCollection SelectNodes(string xpath)

获取符合指定的xpath的子节点列表。

10)public HtmlNode SelectSingleNode(string xpath)

获取符合指定的xpath的单个字节点元素。

查询节点的方法主要是上面10个方法,该类还有其他写节点的系列方法,这里不详细介绍写操作的方法,留作以后详细介绍。

结合Xpath进行查询节点是功能比较强大,这像操作xml那样方便。

简单例子的代码

下面例子是把博客园的精华区博客列表查询出来。执行结果如下面:

代码

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using HtmlAgilityPack; namespace DemoCnBlogs
{
class Program
{
staticvoid Main(string[] args)
{
HtmlWeb web =new HtmlWeb();
HtmlDocument doc = web.Load("http://www.cnblogs.com/pick/"); HtmlNode node = doc.GetElementbyId("post_list"); StreamWriter sw = File.CreateText("log.txt"); foreach(HtmlNode child in node.ChildNodes)
{
if (child.Attributes["class"] ==null|| child.Attributes["class"].Value !="post_item")
continue;
HtmlNode hn = HtmlNode.CreateNode(child.OuterHtml); ///如果用child.SelectSingleNode("//*[@class=\"titlelnk\"]").InnerText这样的方式查询,是永远以整个document为基准来查询,
///这点就不好,理应以当前child节点的html为基准才对。 Write(sw, String.Format("推荐:{0}", hn.SelectSingleNode("//*[@class=\"diggnum\"]").InnerText));
Write(sw, String.Format("标题:{0}", hn.SelectSingleNode("//*[@class=\"titlelnk\"]").InnerText));
Write(sw, String.Format("介绍:{0}", hn.SelectSingleNode("//*[@class=\"post_item_summary\"]").InnerText));
Write(sw, String.Format("信息:{0}", hn.SelectSingleNode("//*[@class=\"post_item_foot\"]").InnerText)); Write(sw, "----------------------------------------"); } sw.Close(); Console.ReadLine();
} staticvoid Write(StreamWriter writer, string str)
{
Console.WriteLine(str);
writer.WriteLine(str);
} }
}

转自:http://www.cnblogs.com/huangcong/p/3408309.html

【转】C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用的更多相关文章

  1. 黄聪:C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用

    Html Agility Pack下载地址:http://htmlagilitypack.codeplex.com/ Html Agility Pack 源码中的类大概有28个左右,其实不算一个很复杂 ...

  2. JQuery源码解析(一)

    写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...

  3. HTML解析类 ,让你不使用正则也能轻松获取HTML相关元素 -C# .NET

    功能: 1.轻松获取指元素HTML元素. 2.可以根据属性标签进行筛选 3.返回的都是Llist强类型无需转换 用过XElement的都知道 用来解析XML非常的方便,但是对于HTML的格式多样化实在 ...

  4. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  5. jQuery Ajax 全解析

    转自:http://www.cnblogs.com/qleelulu/archive/2008/04/21/1163021.html 本文地址: jQuery Ajax 全解析 本文作者:QLeelu ...

  6. JQuery中的工具类(五)

    一:1.serialize()序列表表格内容为字符串.返回值jQuery示例序列表表格内容为字符串,用于 Ajax 请求. HTML 代码:<p id="results"&g ...

  7. jQuery Ajax 全解析(转载)

    本文地址: jQuery Ajax 全解析 本文作者:QLeelulu 转载请标明出处! jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写Java ...

  8. jquery源码解析:代码结构分析

    本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94)     定义了一些变量和函数,   jQuery = function() ...

  9. 自己用的框架写了一个PHP模版解析类

    <?php if(!defined('IS_HEARTPHP')) exit('Access Denied'); /** * template.class.php 模板解析类 * * @copy ...

随机推荐

  1. 一个App完成入门篇(四)- 完成反馈页面

    上一节中我们学会了如何通过点击不同按钮切换页面,这节专注于完成反馈页面的功能以及细节动画. 导入项目 添加新组件 同步新组件 完成页面布局 输入时加动画效果 弹出日期选择 直接引用UI页面 将要学习的 ...

  2. 走进AngularJs(八) ng的路由机制

    在谈路由机制前有必要先提一下现在比较流行的单页面应用,就是所谓的single page APP.为了实现无刷新的视图切换,我们通常会用ajax请求从后台取数据,然后套上HTML模板渲染在页面上,然而a ...

  3. 关于Windows高DPI的一些简单总结

    我们知道,关于高DPI的支持, Windows XP时代就开始有了, 那时关于高DPI的支持比较简单, 但是从Vista/Win7 到现在Win8 /Win8.1, Windows关于高DPI的支持已 ...

  4. 2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~

    本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...

  5. 【重要更新】Senparc.Weixin SDK v4.4 升级说明

    本次更新同时影响以下所有Senparc.Weixin相关版本的dll: Senparc.Weixin.dll 升级到 v4.4.2(重要) Senparc.Weixin.MP.dll 升级到 v13. ...

  6. MVVM架构~knockoutjs实现简单的购物车

    返回目录 概念相关 购物车相信大家都用过,很方便,可以将多个商品添加到购物车,并且可以修改购买商品的数据,当然为了用户体验好,在修改数据时,你的价格也会出现变化的,这使用JS可以实现,但我认为,代码量 ...

  7. 理解nginx的配置

    Nginx配置文件主要分成四部分:main(全局设置).server(主机设置).upstream(上游服务器设置,主要为反向代理.负载均衡相关配置)和 location(URL匹配特定位置后的设置) ...

  8. Java程序员的日常 —— 多进程开发IO阻塞问题

    本篇仍旧是源于最近的工作,总结一下纪念那些年埋下的坑... 背景故事 需求:"使用进程方式启动另一个程序!" 开发:"OK! Runtime.getRuntime().e ...

  9. 删除顽固node_modules

    在工作中有用到gulp,webpack,使用他们需用依赖node的一些模块包,于是会在目录下生成一个node_modules文件夹.有一次想删掉它重新生成模块包的时候发现根本不太可能,无穷无尽的报一个 ...

  10. salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建

    VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的标签相对简单,如果需要深入了解VF相关知识以及标签, 可以通过以下链接查看或下载 ...