HtmlAgilityPack是一个开源的html解析器,底层是通过将html格式转成标准的xml格式文件来实现的(使用dot net里的XPathDocument等xml相关类),可以从这里下载:http://htmlagilitypack.codeplex.com。可以通过指定xpath路径提取需要的内容,上面那个网站也提供了一个自动生成xpath路径的工具HAP Explorer。缺点和上面使用mshtml com组件一样,内存占用非常大,会耗光所有物理内存。

3、使用SgmlReader

SgmlReader也是一个开源的解析器,可以从这里下载(微软自己网站上的那个不完整,缺少一些文件)。用这个工具先将html文件转成标准的xml格式文件,再通过制定xpath路径来提取所需要的内容(xpath路径可以通过上面的那个工具生成)。下面一个简单的示例代码:
XPathDocument pathDoc = null;
using (SgmlReader sgmlReader = new SgmlReader())
{
sgmlReader.DocType = "HTML";
sgmlReader.InputStream = new StringReader(html);
using (StringWriter stringWriter = new StringWriter())
{
using (XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter))
{
while (!sgmlReader.EOF)
{
xmlWriter.WriteNode(sgmlReader, true);
}
string xml = stringWriter.ToString().Replace("xmlns=\"http://www.w3.org/1999/xhtml\"", "");
pathDoc = new XPathDocument(new StringReader(xml));
}                    
}
}
//提取出整个table
string xpath = "//div[@class=\"infoList\"]/table";//xpath表达式
XPathNavigator nav = pathDoc.CreateNavigator();
XPathNodeIterator nodes = nav.Select(xpath);
if (!nodes.MoveNext())
{
return;
}
nodes = nodes.Current.Select("//tr");
if (!nodes.MoveNext()) return;
string str = "";
while (nodes.MoveNext())
{
//遍历所有行
XPathNodeIterator tdNode = nodes.Current.Select("./td");
while (tdNode.MoveNext())
{
//遍历列
str += tdNode.Current.Value.Trim() + " ";
}
str += "\r\n";  
}
//输出结果
Console.WriteLine(str);

如果要提取图片的src,xpath写成这样://div[@class=\"infoList\"]/img/@src

注意:

上面的这行 stringWriter.ToString().Replace("xmlns=\"http://www.w3.org/1999/xhtml\"", "");

使用SgmlReader转换后的html会在根元素<html>自动加上命名空间http://www.w3.org/1999/xhtml,变成这样:
<html xmlns="http://www.w3.org/1999/xhtml">

如果不把这个xmlns="http://www.w3.org/1999/xhtml"移走,那么

XPathNodeIterator nodes = nav.Select(xpath);

这条语句将取不出来内容,也即是nodes.MoveNext()的值将会是false,网上很多例子里都没有提到这点

例子中的html样本:
<html>
<head>
<title>示例Test</title>
</head>
<body>
<div id="a1" class="a1">
<div class="infoList" id="infoList">
<div class="clearit"></div>
<table cellspacing="0">
<tr>
<td>甲A</td>
<td class="td2">09-25 00:00</td>
</tr>
<tr>
<td>德乙</td>
<td class="td2">09-26 10:10</td>
</tr>
</table>
<img src="http://www.aaaa.com/images/b234.jpg" alt="图片1" title="图片1">
</div>
</div>
</doby>
</html>

使用SgmlReader的好处就是内存占用稳定,在俺实际使用中内存上下浮动不会超过20M(2个线程,间隔60秒抓取一个新页面,7*24小时不间断的后台服务程序)。不足就是html转成xml格式耗时间

SgmlReader使用方法的更多相关文章

  1. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  2. 解析HTML文件 - 运用SgmlReader类来解析HTML文件

    运用.NET Framework类来解析HTML文件.读取数据并不是最容易的.虽然你可以用.NET Framework中的许多类(如StreamReader)来逐行解析文件,但XmlReader提供的 ...

  3. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  4. 【.net 深呼吸】细说CodeDom(6):方法参数

    本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...

  5. IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法

    直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...

  6. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  7. [C#] C# 基础回顾 - 匿名方法

    C# 基础回顾 - 匿名方法 目录 简介 匿名方法的参数使用范围 委托示例 简介 在 C# 2.0 之前的版本中,我们创建委托的唯一形式 -- 命名方法. 而 C# 2.0 -- 引进了匿名方法,在 ...

  8. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

  9. [BOT] 一种android中实现“圆角矩形”的方法

    内容简介 文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式,四个角可以分别指定为圆角.思路是利用"Xfermode + Path"来进行 ...

随机推荐

  1. Eclipse环境下配置spket中ExtJS5.0提示

    使用eclipse编写extjs时,一定会用到spket这个插件,spket可以单独当作ide使用,也可以当作eclipse插件使用,我这里是当作eclipse的插件使用的,下面来一步步图解说明如何配 ...

  2. Web应用程序系统的多用户权限控制设计及实现-用户模块【7】

    前五章均是从整体上讲述了Web应用程序的多用户权限控制实现流程,本章讲述Web权限管理系统的基本模块-用户模块.用户模块涉及到的数据表为用户表. 1.1用户域 为了更规范和方便后期系统的二次开发和维护 ...

  3. android创建自定义控件

    新建一个布局title.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xm ...

  4. C语言-07-预处理、typedef、static和extern

    预处理 1> 使用注意 以#开头 在代码被翻译成0和1之前执行 预处理指令可以出现在任何位置 作用域是从编写指令那一行开始到文件结束 2> 宏定义 基本使用 ① 使用#define定义 ② ...

  5. 手动方式安装 eclipse 的svn插件 Subversive和 Subversive SVN Connectors

      0.下载配置jdk 链接:http://pan.baidu.com/s/1miIVuic 密码:mwo7 配置 JAVA_HOME .JRE_HOME 1 下载eclipse       ecli ...

  6. eval 为什么加括号

    <!DOCTYPE html> <html> <head> <title>eval学习</title> <script type=&q ...

  7. java web中日期Date类型在页面中格式化显示的三种方式

    一般我们经常需要在将服务器端的Date类型,传到页面进行显示,这就涉及到一个如何格式化显示Date类型的问题,一般我们有三种方式进行: 1)在服务端使用SimpleDateFormat等类格式化成字符 ...

  8. thumbnailator图片处理

    一.简介 thumbnailator是一个用来对图片对象进行操作的Java类库.通过它我们可以很方面的使用代码的方式,对图片进行一些操作.如缩放,裁减,旋转,水印等.thumbnailator项目主页 ...

  9. ubuntu下ROS安装时sudo rosdep init和rosdep update的解决方法

    问题: 在ubuntu上多次安装matlab选择合适的版本来调用摄像头,终于把系统搞坏了,重装系统后,ROS无法安装,每次安装到sudo rosdep init和rosdep update报错的问题, ...

  10. HTTP详解1-工作原理

    1. HTTP简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议.它可以使浏览器更加高效,使网络传输减少. ...