本文介绍了.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. PHP SPL使用方法和他的威力

    什么是SPL,如何使用,他有什么作用,下面我我们就讲讲PHP SPL的用法 SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,并且从 PH ...

  2. MySQL协议分析(2)

    MySQL协议分析(2) 此阶段是在压缩传输无加密条件下进行的协议分析 思路 结合Oracle官网的说明和自己用wireshark加python进行数据包分析 步骤 客户端与服务器端是否压缩的协商阶段 ...

  3. PAT 1086 Tree Traversals Again[中序转后序][难]

    1086 Tree Traversals Again(25 分) An inorder binary tree traversal can be implemented in a non-recurs ...

  4. testng日志 ITestListener

    上一节我们写一个日志类 extends   TestListenerAdapter ----------TestListenerAdapter 是 ITestListener 实现的一个类 这一节,我 ...

  5. windows 常用cmd命令

    为了减少使用鼠标的频次,熟记一些常用应用的快捷键与系统本身常用的命令是必须的,以下记录一些常用的windows系统命令. 查看网络端口占用情况 :netstat -ano | findstr 8080 ...

  6. Spring AOP (事务管理)

    一.声明式事务管理的概括 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一. Spring的声明式事务顾名思义就是采用声明 ...

  7. JMS--消息头

    一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...

  8. Oracle中的substr()函数详解案例

    1)substr函数格式   (俗称:字符截取函数) 格式1: substr(string string, int a, int b); 格式2:substr(string string, int a ...

  9. JS知识点简单总结

    JS(JavaScript) 是一种解释性语言 是弱/动态 最开始用于表单验证的 JS的五个部分: 1.核心语言定义 2.原生对象和内置对象 5boolean 3.BOM 4.DOM 5.事件处理模型 ...

  10. 从toString()方法到Object.prototype.toString.call()方法

    一.toString方法和Object.prototype.toSting.call()的区别 var arr=[1,2]; 直接对一个数组调用toString()方法, console.log(ar ...