本文介绍了.net 版的一个HTMLParser网页解析开源类库(Winista.HTMLParser)的功能特性、工作原理和使用方法。对于使用.net进行Web信息提取的开发人员进行了一次HTMLParser的初步讲解。应用实例将会在日后的文中介绍,敬请关注。

一、背景知识
HTMLParser原本是一个在sourceforge上的一个Java开源项目,使用这个Java类库可以用来线性地或嵌套地解析HTML文本。他的功能强大和开源等特性吸引了大量Web信息提取的工作者。然而,许多.net开发者朋友一直在寻找一种能在.net中使用的HTMLParser类库,笔者将介绍Winista.HTMLParser类库,对比于其他原本数量就非常少的.net版HTMLParser类库,Winista的版本的类库结构可以说更接近于原始Java版本。
该类库目前分为Utltimate、Pro、Lite和Community四个版本,前三个版本都是收费的。只有Community版本可以免费下载并查看所有的源码。
当前Community最新版本1.8 下载。
该版本的类库文档下载。

二、功能和特性
1.可以在任何.net语言中使用(C#,VB.net,J#等)
2.可以解析几乎所有的Html标签,并且可以通过标签类别、属性或正则表达式来搜索标签。有些甚至在Java版本中无法支持的标签也在这个版本中得到了支持。
3.设置可扩展的过滤器来过滤结果集中不需要的标签。
4.高性能的API接口使得你能处理许多常见的问题,如:哪些是页面中的外部链接?哪些是图片?哪些是不同的表格?页面中有错误的链接吗等等问题。
5.一个基于Http协议引擎的配置文件使得你能通过一个指定的URL地址来获得该页面内容。该爬虫可以遵循robot.txt协议文件来获得组织和允许访问的列表。
6.Http协议引擎能够完整地处理来自任何站点的反馈。

三、词法分析的工作原理
HTMLParser的词法分析器对HTML进行了4级封装,从低级到高级的顺序为:ParserStream、Source、Page、Lexer。ParserStream负责从文件中获取二进制数据,但不做任何处理。Source把二进制文件转换成相应的字符序列,存储一组未加工的字符序列。Page可以看成是一个string数组,按行存储一个Source文本的每一行第一个字符开始的位置索引。Lexer包含了词法分析的代码,从Page里读取字符串,用Cursor记录当前字符所在位置,通过状态机来生成Nodes节点。
Lexer中真正执行词法分析的是NextCode()方法,它每次词都查找返回下一个Node节点,直到Page结束。算法描述如下:
1.读入一个字符,判断是否已是页尾,是则返回null。
2.判断是否是"<",如果是,则可能是标签入口,需读取下一字符确认。
3.如果都不是,ParserString状态机开始解析一个StringNode,如果是"<",继续读取下一字符。
4.判断是否到页尾,是则产生一个StringNode返回。
5.如果读取到"%",则说明是JSP标签,进入JSP状态机去解析。
6.如果读取到"?",则说明是XML标签,进入XML状态机去解析。
7.如果读取到"/"或任何字母,说明是Tag标签,进入Tag标签状态机去解析。
8.如果读取到"!",则说明进入了一个注释标签,需要再读取一个字符,如果到页尾,则产生一个StringNode返回,如果字符为">"则生成一个RemarkNode返回,否则 回退一个字符,再判断字符如果是"-"则回退一个字符,进入Remark状态机去解析,如果不是,则回退一个字符进入Tag状态机去解析。

四、三种使用方法的比较
1.使用Lexer词法分析器直接解析HTML。
这样的方法较为底层,只能返回一个线性的Node节点序列,通过Lexer.NextNode()方法获得下一个Node的信息。虽然不够方便,但有时可完成一些较为灵活的工作。
调用的方法是(传入string类型的html代码):

Lexer lexer = new Lexer(htmlcode);
INode node = lexer.NextNode();
Console.Write(node.ToString());

返回结果是该页面的第一个标签"html"的Node结点信息。

2.使用Filter结点过滤模式。
如果你有一些很明确的结点需要提取,那么就该使用Filter结点过滤模式。系统定义了17种具体的Filter,根据不同的过滤条件来获得需要的结点。包括依据结点父子关系的Filter,连接Filter组合的Filter,依据网页内容匹配情况的filter,等等。我们也可以继承 Filter做自己的Filter来提取节点。

NodeList nodeList = myParser.parse(someFilter);
解析之后,我们可以采用:
INode[] nodes = nodeList.toNodeArray();

来获取节点数组,也可以直接访问:
INode node = nodeList.elementAt(i);
来获取Node。
另外,在Filter后得到NodeList以后,我们仍然可以使用nodeList.extractAllNodesThatMatch(someFilter)来进一步过滤,同时又可以用nodeList.visitAllNodesWith(someVisitor)来做进一步的访问。

3.使用Visitor结点访问模式
如果你希望HTMLParser遍历所有的结点,并按结点的不同类型(StringNode、RemarkNode、TagNode)和不同的访问过程来进行不同操作的话,可以使用Visitor模式。NodeVisitor是一个抽象类,分别定义了如下方法:
BeginParsing():解析前进行的操作
VitisTag():访问到开始标签时的操作
VisitEndTag():访问到结束标签时的操作
VisitStringNode():访问到文本结点时的操作
VisitRemarkNode():访问注释结点时的操作
自己定义一个类并继承NodeVisitor类,实现以上几个方法,即完成Visitor模式的访问类。系统也提供了7个具体的结点访问类,具体见上文提供的类库文档。不过这7个类并不实用,大多数的功能还需要自己来扩充定义。调用方法:
Parser parser = Parser.CreateParser((htmlcode), "GBK");//传入string类型的html代码
NodeVisitor visitor = new LinkFindingVisitor(linktext); //以链接查找的Visitor举例
parser.VisitAllNodesWith(visirot);

灵活使用以上三种模式的结合,相信就可以提取到任何我们所需要的信息了。

在.net中运用HTMLParser解析网页的原理和方法的更多相关文章

  1. python--爬虫入门(八)体验HTMLParser解析网页,网页抓取解析整合练习

    python系列均基于python3.4环境  基本概念 html.parser的核心是HTMLParser类.工作的流程是:当你feed给它一个类似HTML格式的字符串时,它会调用goahead方法 ...

  2. Python爬虫解析网页的4种方式 值得收藏

    用Python写爬虫工具在现在是一种司空见惯的事情,每个人都希望能够写一段程序去互联网上扒一点资料下来,用于数据分析或者干点别的事情. ​ 我们知道,爬虫的原理无非是把目标网址的内容下载下来存储到内存 ...

  3. JAVA中生成、解析二维码图片的方法

    JAVA中生成.解析二维码的方法并不复杂,使用google的zxing包就可以实现.下面的方法包含了生成二维码.在中间附加logo.添加文字功能,并有解析二维码的方法. 一.下载zxing的架包,并导 ...

  4. 使用Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)(转)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  5. Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  6. 【python】使用HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies

    一.从HTML文档中提取链接 模块HTMLParser,该模块使我们能够根据HTML文档中的标签来简洁.高效地解析HTML文档. 处理HTML文档的时候,我们常常需要从其中提取出所有的链接.使用HTM ...

  7. 使用Python中的urlparse、urllib抓取和解析网页(一)(转)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过Python 语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  8. asp自动解析网页中的图片地址,并将其保存到本地服务器

    程序实现功能:自动将远程页面的文件中的图片下载到本地. 程序代码 <% '将本文保存为 save2local.asp '测试:save2local.asp?url=http://ent.sina ...

  9. 【python】使用Python中的urlparse、urllib抓取和解析网页

    一.解析URL 函数urlparse(urlstring [, default_scheme [, allow_fragments]])的作用是将URL分解成不同的组成部分,它从urlstring中取 ...

随机推荐

  1. 关于websocket通讯

    var ws = { init:function(callback){ var _this = this; _this.callback = callback; }, websocket:functi ...

  2. linux用户 群组权限

    用户及passwd文件 /etc/passwd文件的功能 /etc/passwd文件每个字段的具体含义 shadow文件 /etc/shadow文件的功能 /etc/shadow文件每个字段的具体含义 ...

  3. AtCoder Regular Contest 080 E - Young Maids

    地址:http://arc080.contest.atcoder.jp/tasks/arc080_c 题目: E - Young Maids Time limit : 2sec / Memory li ...

  4. TOSCA自动化测试工具--Log defect

    1.执行完用例后,对于失败的用例进行分析,如果有缺陷,可以提对应的缺陷 2.在issues模块, 右键创建自己需要的文件夹,然后在文件夹上右键找到虫子图形点下,就可以创建缺陷了,填上对应的内容 3.如 ...

  5. C#基础--多线程

    一.微软早期操作系统中的问题 在早期的操作系统中,应用程序都是在同一个地址空间中运行的,每个程序的数据其它程序都是可见的,并且因为早期CPU是单内核 的所以所有的执行都是线性的.这就引出两个问题: 第 ...

  6. iis原理介绍

    它是一个程序,负责对网站的内容进行管理,以及对客户的请求(就是Http请求)做出反应.当用户对一个页面提出请求时,IIS做如下反应(忽略权限):1.把对方请求的虚拟路径转换成物理路径2.根据物理路径搜 ...

  7. 摄像头PIN脚功能作用

    摄像头PIN脚功能作用,Camera硬件系统分析 9 f  E+ E2 b  N. j4 M2 U- a. q9 A) T# c& O& C% x+ l5 l! q           ...

  8. 在python3下使用OpenCV 抓取摄像头图像并实时显示3色直方图

    以下代码为在Python3环境下利用OpenCV 抓取摄像头的实时图像, 通过OpenCV的 calHist函数计算直方图, 并显示在3个不同窗口中. import cv2 import numpy ...

  9. Python面试题之Python生成器

    首先说明一下生成器也是迭代器,也有迭代器的那些优点. 那为什么要生成器呢?因为到目前为止都 不是你写的迭代器,都是别人定义好的.那如何自己去造一个迭代器呢?下面的内容就会给你答案. 想要自己造一个迭代 ...

  10. RESTful风格与RESTful Api

    REST(representational state transfer)(表述性状态转移),词汇解析: 1.representational 表述性:指资源以用各种形式来表述,包括 XML.JSON ...