下载地址HtmlParser.Net.rar

帮助文档:htmlparser.rar

背景:

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

(一)Filter类
Filter一看就知道,肯定是对结果进行过滤,取得需要的内容。HTMLParser在org.htmlparser.filters包之内一共界说了16个差别的Filter,也可以分为几类。
判定类Filter:
TagNameFilter
HasAttributeFilter
HasChildFilter
HasParentFilter
HasSiblingFilter
IsEqualFilter
逻辑运算Filter:
AndFilter
NotFilter
OrFilter
XorFilter
其他Filter:
NodeClassFilter
StringFilter
LinkStringFilter
LinkRegexFilter
RegexFilter
CssSelectorNodeFilter

所有的Filter类都实现了org.htmlparser.NodeFilter接口。这个接口只有一个主要函数:
boolean accept (Node node);
各个子类分别实现这个函数,用于判定输入的Node是否相符这个Filter的过滤条件,假如相符,返回true,不然返回false。

(二)判定类Filter
2.1 TagNameFilter
TabNameFilter是最轻易理解的一个Filter,凭据Tag的名字进行过滤。

下面是用于测试的HTML文件:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>新灵感网站自动更新系统-www.xinlg.com</title>< /head>
<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释-->
新灵感网站自动更新系统-www.xinlg.com
<a href="http://www.xinlg.com">新灵感网站自动更新系统-www.xinlg.com</a>
</div>
新灵感网站自动更新系统-www.xinlg.com
</div>
</body>
</html>
测试源代码:(这里只列出了Main函数,全部源代码请参考 HTMLParser使用入门(2)- Node内容,自己添加import局部)
public static void main(String[] args) {

try{
Parser parser = new Parser( (HttpURLConnection) (new URL("http://127.0.0.1:8080/HTMLParserTester.html")).openConnection() );

// 这里是控制测试的局部,后面的例子修改的就是这个地方。
NodeFilter filter = new TagNameFilter ("DIV");
NodeList nodes = parser.extractAllNodesThatMatch(filter);

if(nodes!=null) {
for (int i = 0; i < nodes.size(); i++) {
Node textnode = (Node) nodes.elementAt(i);

message("getText:"+textnode.getText());
message("=================================================");
}
}
}
catch( Exception e ) {
e.printStackTrace();
}
}
输出结果:
getText:div id="top_main"
=================================================
getText:div id="logoindex"
=================================================
可以看出文件中两个Div节点都被取出了。下面可以针对这两个DIV节点进行操纵.

2.2 HasChildFilter
下面让我们看看HasChildFilter。方才看到这个Filter的时候,我想虽然地认为这个Filter返回的是有Child的Tag。直接初始化了一个
NodeFilter filter = new HasChildFilter();
结果挪用NodeList nodes = parser.extractAllNodesThatMatch(filter);的时候HasChildFilter内部直接产生 NullPointerException。读了一下HasChildFilter的源代码,才发觉,实际HasChildFilter是返回有相符条件的子节点的节点,需要另外一个Filter作为过滤子节点的参数。缺省的结构函数虽然可以初始化,但是由于子节点的Filter是null,所以使用的时候产生了Exception。从这点来看,HTMLParser的源代码还有很多可以优化的的地方。呵呵。

修改源代码:
NodeFilter innerFilter = new TagNameFilter ("DIV");
NodeFilter filter = new HasChildFilter(innerFilter);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:body
=================================================
getText:div id="top_main"
=================================================
可以看到,输出的是两个有DIV子Tag的Tag节点。(body有子节点DIV "top_main","top_main"有子节点"logoindex"。

注重HasChildFilter还有一个结构函数:
public HasChildFilter (NodeFilter filter, boolean recursive)
假如recursive是false,则只对第一级子节点进行过滤。好比前面的例子,body和top_main都是在第一级的子节点里就有DIV节点,所以匹配上了。假如我们用下面的要领挪用:
NodeFilter filter = new HasChildFilter( innerFilter, true );
输出结果:
getText:html xmlns="http://www.w3.org/1999/xhtml"
=================================================
getText:body
=================================================
getText:div id="top_main"
=================================================
可以看到输出结果中多了一个html xmlns="http://www.w3.org/1999/xhtml",这个是整个HTML页面的节点(根节点),虽然这个节点下直接没有DIV节点,但是它的子节点body下面有DIV节点,所以它也被匹配上了。

2.3 HasAttributeFilter
HasAttributeFilter有3个结构函数:
public HasAttributeFilter ();
public HasAttributeFilter (String attribute);
public HasAttributeFilter (String attribute, String value);
这个Filter可以匹配出包括制命名字的属性,或者制定属性为指定值的节点。还是用例子说明比较轻易。

挪用要领1:
NodeFilter filter = new HasAttributeFilter();
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:

什么也没有输出。

挪用要领2:
NodeFilter filter = new HasAttributeFilter( "id" );
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:div id="top_main"
=================================================
getText:div id="logoindex"
=================================================

挪用要领3:
NodeFilter filter = new HasAttributeFilter( "id", "logoindex" );
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:div id="logoindex"
=================================================

很简单吧。呵呵

2.4 其他判定列Filter
HasParentFilter和HasSiblingFilter的效用与HasChildFilter类似,大众自己试一下就应该了解了。

IsEqualFilter的结构函数参数是一个Node:
public IsEqualFilter (Node node) {
mNode = node;
}
accept函数也很简单:
public boolean accept (Node node) {
return (mNode == node);
}
不需要过多说明了。

(三)逻辑运算Filter
前面介绍的都是简单的Filter,只能针对某种简单类型的条件进行过滤。HTMLParser支持对付简单类型的Filter进行组合,从而实现纷乱的条件。原理和一般编程语言的逻辑运算是一样的。
3.1 AndFilter
AndFilter可以把两种Filter进行组合,只有同时满足条件的Node才会被过滤。
测试源代码:
NodeFilter filterID = new HasAttributeFilter( "id" );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new AndFilter(filterID, filterChild);
输出结果:
getText:div id="logoindex"
=================================================

3.2 OrFilter
把前面的AndFilter换成OrFilter
测试源代码:
NodeFilter filterID = new HasAttributeFilter( "id" );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new OrFilter(filterID, filterChild);
输出结果:
getText:div id="top_main"
=================================================
getText:div id="logoindex"
=================================================

3.3 NotFilter
把前面的AndFilter换成NotFilter
测试源代码:
NodeFilter filterID = new HasAttributeFilter( "id" );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new NotFilter(new OrFilter(filterID, filterChild));
输出结果:
getText:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
=================================================
getText:

=================================================
getText:head
=================================================
getText:meta http-equiv="Content-Type" content="text/html; charset=gb2312"
=================================================
getText:title
=================================================
getText:新灵感网站自动更新系统-www.xinlg.com
=================================================
getText:/title
=================================================
getText:/head
=================================================
getText:

=================================================
getText:html xmlns="http://www.w3.org/1999/xhtml"
=================================================
getText:

=================================================
getText:body
=================================================
getText:

=================================================
getText:

=================================================
getText:

=================================================
getText:这是注释
=================================================
getText:
新灵感网站自动更新系统-www.xinlg.com

=================================================
getText:a href="http://www.xinlg.com"
=================================================
getText:新灵感网站自动更新系统-www.xinlg.com
=================================================
getText:/a
=================================================
getText:

=================================================
getText:/div
=================================================
getText:
新灵感网站自动更新系统-www.xinlg.com

=================================================
getText:/div
=================================================
getText:

=================================================
getText:/body
=================================================
getText:

=================================================
getText:/html
=================================================
getText:

=================================================

除了前面3.2中输出的几个Tag,其余的Tag都在这里了。

3.4 XorFilter
把前面的AndFilter换成NotFilter
测试源代码:
NodeFilter filterID = new HasAttributeFilter( "id" );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new XorFilter(filterID, filterChild);
输出结果:
getText:div id="top_main"
=================================================

(四)其他Filter:
4.1 NodeClassFilter
这个Filter用于判定节点类型是否是某个特定的Node类型。在HTMLParser使用入门(2)- Node内容中我们已经了解了Node的差别类型,这个Filter就可以针对类型进行过滤。
测试源代码:
NodeFilter filter = new NodeClassFilter(RemarkNode.class);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:这是注释
=================================================
可以看到只有RemarkNode(注释)被输出了。

4.2 StringFilter
这个Filter用于过滤显示字符串中包括制定内容的Tag。注重是可显示的字符串,不可显示的字符串中的内容(例如注释,链接等等)不会被显示。
修改一下例子源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>新灵感网站自动更新系统-title-www.xinlg.com</title>& lt;/head>
<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释 新灵感网站自动更新系统-www.xinlg.com -->
新灵感网站自动更新系统-字符串1-www.xinlg.com
<a href="http://www.xinlg.com">新灵感网站自动更新系统-链接文本-www.xinlg.com</a>
</div>
新灵感网站自动更新系统-字符串2-www.xinlg.com
</div>
</body>
</html>

测试源代码:
NodeFilter filter = new StringFilter("www.xinlg.com");
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:新灵感网站自动更新系统-title-www.xinlg.com

=================================================
getText:
新灵感网站自动更新系统-字符串1-www.xinlg.com

=================================================
getText:新灵感网站自动更新系统-链接文本-www.xinlg.com

=================================================
getText:
新灵感网站自动更新系统-字符串2-www.xinlg.com
=================================================
可以看到包括title,两个内容字符串和链接的文本字符串的Tag都被输出了,但是注释和链接Tag自己没有输出。

4.3 LinkStringFilter
这个Filter用于判定链接中是否包括某个特定的字符串,可以用来过滤出指向某个特定网站的链接。
测试源代码:
NodeFilter filter = new LinkStringFilter("www.xinlg.com");
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:a href="http://www.xinlg.com"
=================================================

4.4 其他几个Filter
其他几个Filter也是凭据字符串对差别的域进行判定,与前面这些的区别主要就是支持正则表达式。这个不在本文的讨论范畴以内,大众可以自己实验一下。

黄聪:C#解析HTML DOM解析类 HtmlParser.Net 下载的更多相关文章

  1. Java---XML的解析(1)-DOM解析

    本章只讲DOM解析.接下来还会学习Dom4j和StAX 解析技术 DOM解析: DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档: <user> <name>Ja ...

  2. SAX解析与DOM解析

    SAX解析实例:http://www.iteye.com/topic/763895 Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类 ...

  3. java拾遗1----XML解析(一) DOM解析

    XML解析技术主要有三种: (1)DOM(Document Object Model)文档对象模型:是 W3C 组织推荐的解析XML 的一种方式,即官方的XML解析技术. (2)SAX(Simple ...

  4. XML解析(一) DOM解析

    XML解析技术主要有三种: (1)DOM(Document Object Model)文档对象模型:是 W3C 组织推荐的解析XML 的一种方式,即官方的XML解析技术. (2)SAX(Simple ...

  5. xml解析之----DOM解析

    DOM模型(documentobject model) •DOM解析器在解析XML文档时,会把文档中的全部元素.依照其出现的层次关系.解析成一个个Node对象(节点). •在dom中.节点之间关系例如 ...

  6. android XML解析之DOM解析方式

    DOM 解析方式步骤: 第一步:首选需要获得DOM解析器工厂实例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ...

  7. React源码解析-Virtual DOM解析

    前言:最近一直在研究React,看了陈屹先生所著的深入React技术栈,以及自己使用了这么长时间.对React应该说有比较深的理解了,正好前阵子也把两本关于前端设计模式的书看完了,总感觉有一种知识错综 ...

  8. XML解析之DOM解析技术案例

    Java代码: package com.xushouwei.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; im ...

  9. xml的SAX解析和dom解析的区别

    一,区别 DOM解析 SAX解析 原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点.适合大容量文件的读取 DOM解析可以任意进行增删改成 SAX解析只能读取 ...

  10. XML文件解析之DOM解析

    XML文件是一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.基本的解析方式包括DOM解析和SAX解析,具体来说包括DOM解析,SAX解析,DOM4J解 ...

随机推荐

  1. 论XCODE工程里使用的宏定义.

    在XCODE开发过程中,经常会遇到引用头文件,引用库路径的问题,如果不是直接的源码引入,则需要在工程中增加设置.虽然现在有了Pod这类集合管理工具,但有时为了一个很小的lib引入Pod这尊大神还是有点 ...

  2. java List 排序 Collections.sort()

    用Collections.sort方法对list排序有两种方法  第一种是list中的对象实现Comparable接口,如下: /** * 根据order对User排序 */ public class ...

  3. boot/setup.S

    !!    setup.S        Copyright (C) 1991, 1992 Linus Torvalds!! setup.s is responsible for getting th ...

  4. Blob 构造函数

    Blob 构造函数使 Web 开发人员可直接在客户端上创建或操作 Blob(经常等效于一个文件). 该构造函数在 W3C 的文件 API 规范中进行定义,该规范目前尚处于工作草案阶段.在较早版本的文件 ...

  5. LeetCode()Substring with Concatenation of All Words 为什么我的超时呢?找不到原因了!!!

    超时代码 class Solution { public: vector<int> findSubstring(string s, vector<string>& wo ...

  6. 黑马程序员——JAVA基础之包,权限

    ------- android培训.java培训.期待与您交流! ---------- 包(package) 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是:包 ...

  7. PHP-关于$_SERVER

    类似于Nginx中的请求头,所有header,都可以使用 $http_xxx来使用,比如$http_accept,甚至包括自定义的,比如,$http_x_forwarded_host proxy_se ...

  8. [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)

    http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...

  9. 如何使用投影看着备注分享自己的PPT

    1.  设置多屏幕 一般你的笔记本就是1,   投影是2 2. 设置幻灯片的放映方式 设置幻灯片显示于另外一个监视器  并勾选显示演示者视图 3.  点击放映 就会出现 左上角是ppt本身, 右上角是 ...

  10. css设置透明度

    使用新的CSS3的"RGBA"声明,不仅仅让我们像通常一样设置RGB颜色,而且还可以设置其透明度. RGBA像RGB一样设置颜色,而这个"A"--RGBA中的最 ...