黄聪:C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用
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);
} }
}
黄聪:C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用的更多相关文章
- 【转】C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用
Html Agility Pack下载地址:http://htmlagilitypack.codeplex.com/ Html Agility Pack 源码中的类大概有28个左右,其实不算一个很复杂 ...
- 黄聪:基于jQuery+JSON的省市区三级地区联动
查看演示:http://www.helloweba.com/demo/cityselect/ 源码下载:http://files.cnblogs.com/files/huangcong/citysel ...
- 黄聪:C#操作xml SelectNodes,SelectSingleNode通过 xPath 定位class包含Contains的DIV
一. SelectNodes,SelectSingleNode总是返回NULL 下面以一个简单的xml为例: <?xml version="1.0"?> <mes ...
- jQuery Ajax 全解析
转自:http://www.cnblogs.com/qleelulu/archive/2008/04/21/1163021.html 本文地址: jQuery Ajax 全解析 本文作者:QLeelu ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block 开发人员经常编写需要安全功能的应用程序.这些应用程序 ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block 代理对象(Proxy Object) ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception 依赖注入容器Uni ...
- jQuery Ajax 全解析(转载)
本文地址: jQuery Ajax 全解析 本文作者:QLeelulu 转载请标明出处! jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写Java ...
- 黄聪:如何使用Add-on SDK开发一个自己的火狐扩展
火狐开放了扩展的开发权限给程序员们,相信很多人都会希望自己做一些扩展来方便一些使用. 我最近做一些项目也需要开发一个火狐扩展,方便收集自己需要的数据,因此研究了几天怎么开发,现在已经差不多完成了,就顺 ...
随机推荐
- Fis3的前端模块化之路[基础篇]
Fis3版本:v3.4.22 fis3是一个构建工具 解决前端开发中自动化工具.性能优化.模块化框架.开发规范.代码部署.开发流程等问题. 安装 npm install -g fis3 运行 fis3 ...
- LDR详解
ARM指令集中,LDR通常都是作加载指令的,但是它也可以作伪指令. LDR伪指令的形式是"LDR Rn,=expr".下面举一个例子来说明它的用法. COUNT EQU ...
- TODO:即将开发的第一个小程序
TODO:即将开发的第一个小程序 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验.个人理解小程序是寄宿在微信平台上的一个前端框架,具有跨平台功能, ...
- eclipse 快捷键大全
注:因eclipse版本.电脑配置等原因 有些快捷键可能导致不可用(遇到些许问题可在下方评论) [Ct rl+T] 搜索当前接口的实现类 1. [ALT +/] 此快捷键为用户编辑的好帮手,能为 ...
- 从零开始编写自己的C#框架(28)——建模、架构与框架
文章写到这里,我一直在犹豫是继续写针对中小型框架的设计还是写些框架设计上的进阶方面的内容?对于中小型系统来说,只要将前面的内容进行一下细化,写上二三十章具体开发上的细节,来说明这个通用框架怎么开发的就 ...
- [C#] C# 知识回顾 - 学会使用异常
学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...
- ASP.NET MVC一次删除多笔记录
批量删除数据记录,如下面的截屏: 先选中想删除的记录,然后点一下删除铵钮,系统将把选中的记录一次性删除.在此,Insus.NET不想每删除一笔记录连接一次数据库. 因此需要把选择的记录一次上传至服务器 ...
- 水平可见直线 bzoj 1007
水平可见直线 (1s 128M) lines [问题描述] 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆 ...
- PHP static静态属性和静态方法
这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...
- TCP/IP基础
TCP/IP 是用于因特网 (Internet) 的通信协议. 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述. 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的 ...