例子1:

using System;
using System.IO;
using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser.Util;
using Winista.Text.HtmlParser.Tags;

private void button1_Click(object sender, EventArgs e)
{
    //we can use the stream to load a html file from the local disk
    // or use the uri to load a web page from the internet
    //byte[] htmlBytes = Encoding.UTF8.GetBytes(this.textBox1.Text);
    //MemoryStream memsteam = new MemoryStream(htmlBytes);
    //InputStreamSource input = new InputStreamSource(memsteam, "utf-8");
    //Page page = new Page(input);
    //Lexer lex = new Lexer(page);

if (this.textBox1.Text.Length <= 0)
        return;
    //here I read the html from the textbox
    Lexer lexer = new Lexer(this.textBox1.Text);
    Parser parser = new Parser(lexer);
    NodeList htmlNodes = parser.Parse(null);
    this.treeView1.Nodes.Clear();
    this.treeView1.Nodes.Add("root");
    TreeNode treeRoot = this.treeView1.Nodes[0];
    for (int i = 0; i < htmlNodes.Count; i++)
    {
        this.RecursionHtmlNode(treeRoot, htmlNodes[i], false);
    }
}

private void RecursionHtmlNode(TreeNode treeNode, INode htmlNode, bool siblingRequired)
{
    if (htmlNode == null || treeNode == null) return;

TreeNode current = treeNode;
    //current node
    if (htmlNode is ITag)
    {
        ITag tag=(htmlNode as ITag);
        if (!tag.IsEndTag())
        {
            string nodeString = tag.TagName;
            if (tag.Attributes != null && tag.Attributes.Count > 0)
            {
                if (tag.Attributes["ID"] != null)
                    nodeString = nodeString + " { id=\"" + tag.Attributes["ID"].ToString() + "\" }";
                if (tag.Attributes["CLASS"] != null)
                    nodeString = nodeString + " { class=\"" + tag.Attributes["CLASS"].ToString() + "\" }";
                if (tag.Attributes["STYLE"] != null)
                    nodeString = nodeString + " { style=\"" + tag.Attributes["STYLE"].ToString() + "\" }";
                if (tag.Attributes["HREF"] != null)
                    nodeString = nodeString + " { href=\"" + tag.Attributes["HREF"].ToString() + "\" }";
            }
            current = new TreeNode(nodeString);
            treeNode.Nodes.Add(current);
        }
    }

//the children nodes
    if (htmlNode.Children!=null && htmlNode.Children.Count > 0)
    {
        this.RecursionHtmlNode(current, htmlNode.FirstChild, true);
    }

//the sibling nodes
    if (siblingRequired)
    {
        INode sibling = htmlNode.NextSibling;
        while (sibling != null)
        {
            this.RecursionHtmlNode(treeNode, sibling, false);
            sibling = sibling.NextSibling;
        }
    }
}

htmlparser是一个纯的java写的html解析的库,它不依赖于其它的java库文件,主要用于改造或提取html。它能超高速解析html,而且不会出错。
毫不夸张地说,htmlparser就是目前最好的html解析和分析的工具。

无论你是想抓取网页数据还是改造html的内容,用了htmlparser绝对会忍不住称赞。

C#版本htmlparser下载    java版本htmlparser下载

简单的教程:

(1)、数据组织分析:

HtmlParser主要靠Node、AbstractNode和Tag来表达Html,因为Remark和Text相对简单 ,此处就将其忽略了。

Node是形成树结构表示HTML的基础,所有的数据表示都是接口Node的实现,Node定义了与页面树结构所表达的页面Page对象,定义了获取父、子、兄弟节点的方法,定义了节点到对应html文本的方法,定义了该节点对应的起止位置,定义了过滤方法 ,定义了Visitor访问机制。 
AbstractNode是Node的一种具体的类实现,起到构成树形结构的作用,除了同具体Node相关的accetp方法,toString,toHtml,toPlainTextString方法以外,AbstractNode实现了大多基本的方 法,使得它的子类,不用理会具体的树操作。 
Tag是具体分析的主要内容。Tag分成composite的Tag和不能包含其他Tag的简单Tag两类,其中前者的基类是CompositeTag,其子类包含BodyTag,Div,FrameSetTag,OptionTag,等27个子类 ;而简单Tag有BaseHrefTag、DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag这八类。 
Node分成三类:

RemarkNode:代表Html中的注释 
TagNode:标签节点,是种类最多的节点类型,上述Tag的具体节点类都是TagNode的实现。 
TextNode:文本节点 
(2)、Visitor方式访问Html:
1,整体解析过程
用一个URL或页面String做一个Parser 
用这个Parser做一个Visitor 
使用Parser.visitAllNodeWith(Visitor)来遍历节点 
获取Visitor遍历后得到的数据 
2,Visit过程
做解析之前做的事情:visitor.beginParsing(); 
每次取到一个节点Node,让该Node接受accept该Visitor 
做解析后做的事情:visitor.finishedParsing(); 
3,获取节点的过程:逐步遍历Html,分析出Node。此部分较为复杂,且对于我们应用来说无需很多了解,暂跳过。
4,节点访问
节点访问采用Visitor模式,Node的accept方法和具体Visitor的visit方法是关键。
首先三类Node来accept的方式各不相同:
对于所有TagNode都使用一个accept方法,即TagNode的accept方法。首先判断是否是标签结尾,如果是就visitor.visitEndTag (this);否则visitor.visitTag (this); 
如果是TextNode,那就visitor.visitStringNode (this);就可以了。 
如果是RemarkNode,那就visitor.visitRemarkNode (this);就可以了。

实际上NodeVisitor里边这四种visit方法都是空的,因为在不同的Visitor中对于这三类节点的处理是不同的 ;对于需要处理的节点,只要重载对应的visit方法就行了,如果不处理那就不理会就可以了;另外,如果用户用自己的Visitor,那么还可以灵活的处理不同类型的节点了。

系统为我们实现了下面我要介绍的8种Visitor,实际上可以看作是系统给我们演示了如何做各种各样的Visitor来访问Html,因为实际上我们要真正来用HtmlParser的话,还需要特定的Visitor,而通过简单的这些系统提供的Visitor组合是难以做成什么事情的。
(3)、系统Visitor功能简介:
ObjectFindingVisitor:用来找出所有指定类型的节点,采用getTags()来获取结果。 
StringBean:用来从一个指定的URL获取移除了<SCRIPT></SCRIPT>和<PRE></PRE>之间代码的Html代码,也可以用做Visitor,用来移除这两种标签内部的代码,采用StringBean.getStrings()来获取结果。 
HtmlPage:提取Title,body中的节点和页面中的TableTag节点。 
LinkFindingVisitor:找出节点中包含某个链接的总个数。 
StringFindingVisitor:找出遍历的TextNode中含有指定字符串的个数。 
TagFindingVisitor:找出指定Tag的所有节点,可以指定多种类型。 
TextExtractingVisitor:从网页中把所有标签去掉来提取文本,这个提取文本的Visitor有时是很实用的 ,只是注意在提取文本时将标签的属性也去掉了,也就是说只剩下标签之间的文本,例如<a>中的链接也去掉了。 
UrlModifyingVisitor:用来修改网页中的链接。 
(4)、Filter
 
如果说visitor是遍历提取信息,当然这个信息可以包括某些节点或者从节点分析出来的更有效的信息,这都取决于我们的Visitor做成什么样子,那么Filter则目标很明确,就是用来提取节点的。所以说要想用HtmlParser,首先要熟悉上面讲到的数据组织。
 
系统定义了17种具体的Filter,包括依据节点父子关系的Filter,连接Filter组合的Filter,依据网页内容匹配情况的filter,等等。我们也可以implement Filter来做自己的Filter来提取节点。
Filter的调用是同Visitor独立的,因为也无需先filter出一些NodeList,再用Visitor来访问。调用Filter的方法是:
NodeList nodeList = myParser.parse(someFilter);
解析之后,我们可以采用:
Node[] nodes = nodeList.toNodeArray();
来获取节点数组,也可以直接访问:
Node node = nodeList.elementAt(i)来获取Node。
另外,在Filter后得到NodeList以后,我们仍然可以使用NodeList的extractAllNodesThatMatch (someFilter)来进一步过滤,同时又可以用NodeList的isitAllNodesWith(someVisitor)来做进一步的访问。
这样,我们可以看到HtmlParser为我们提供了非常方便的Html解析方式,针对不同的应用可以采用visitor来遍历Html节点提取数据,也可以用Filter来过滤节点,提取出我们所关注的节点,再对节点进行处理。通过这样的组合,一定能够找出我们所需要的信息。

代码例子:

htmlparser取得一段html代码里面所有的链接C#版本,java版本类似:
string htmlcode = "<HTML><HEAD><TITLE>AAA</TITLE></HEAD><BODY>" + ...... + "</BODY></HTML>";
Parser parser = Parser.CreateParser(htmlcode, "GBK");
HtmlPage page = new HtmlPage(parser);
try
{ parser.VisitAllNodesWith(page);}
catch (ParserException e1)
{ e1 = null;}
NodeList nodelist = page.Body;
NodeFilter filter = new TagNameFilter("A");
nodelist = nodelist.ExtractAllNodesThatMatch(filter, true);
for (int i = 0; i < nodelist.Size(); i++)
{
LinkTag link=(LinkTag) nodelist.ElementAt(i);
System.Console.Write(link.GetAttribute("href") + "\n");
}

HTMLPARSER.NET 参考资料的更多相关文章

  1. 使用 HttpClient 和 HtmlParser 实现简易爬虫

    这篇文章介绍了 HtmlParser 开源包和 HttpClient 开源包的使用,在此基础上实现了一个简易的网络爬虫 (Crawler),来说明如何使用 HtmlParser 根据需要处理 Inte ...

  2. [转]使用 HttpClient 和 HtmlParser 实现简易爬虫

    http://www.ibm.com/developerworks/cn/opensource/os-cn-crawler/ http://blog.csdn.net/dancen/article/d ...

  3. python模块介绍- HTMLParser 简单的HTML和XHTML解析器

    python模块介绍- HTMLParser 简单的HTML和XHTML解析器 2013-09-11 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq ...

  4. HttpClient 与 HtmlParser 简介 转载

    转载地址:https://www.ibm.com/developerworks/cn/opensource/os-cn-crawler/ 本小结简单的介绍一下 HttpClinet 和 HtmlPar ...

  5. Node相关参考资料

    参考资料: [玩转Nodejs日志管理log4js]http://blog.fens.me/nodejs-log4js/ [dependencies与devDependencies之间的区别]http ...

  6. HTMLParser使用

    htmlparser[1] 是一个纯的java写的html(标准通用标记语言下的一个应用)解析的库,它不依赖于其它的java库文件,主要用于改造或提取html.它能超高速解析html,而且不会出错.现 ...

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

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

  8. CQRS及.NET中的参考资料

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:CQRS作为一种设计模式,其实一点都不新鲜了.不过今天有朋友感叹.NET朋友也关注CQ ...

  9. 爬虫技术 -- 基础学习(四)HtmlParser基本认识

    利用爬虫技术获取网页源代码后,针对网页抽取出它的特定文本内容,利用正则表达式和抽取工具,能够更好地抽取这些内容. 下面介绍一种抽取工具 -- HtmlParser HtmlParser是一个用来解析H ...

随机推荐

  1. 第46条:for-each循环优先于传统的for循环

    for-each循环通过完全隐藏迭代器或者索引变量,避免混乱和出错的可能,适用于集合和数组和任何实现Iterable接口的对象. 使用传统for循环,容易出错: enum Face { ONE, TW ...

  2. Oracle 关于事物的描述

    事物在Oracle中的4种状态: commit--提交 rollback--全部回滚 savepoint name;--定义一个回滚到这里的点:例如:savepoint a; rollback to ...

  3. MembershipProvider的Initialize

    背景 前几天为公司的登陆写密码校验,因为是老系统的东西了,数据已经存在了,所以我要知道密码的校验规则是啥,然后业务经理告诉我了是用Membership去做的加密,让我自己去看.之后我又去问了技术经理, ...

  4. 配置 Struts2 Hello World

    http://javaweb.group.iteye.com/group/wiki/1505-struts2-under-helloworld---how-to-make-the-first-of-t ...

  5. dedecms 获取文章发布时间和获取文章最后更新时间

    文章发布时间:[field:senddate function=MyDate('m-d',@me)/] 文章最后更新时间:[field:pubdate function=MyDate('m-d',@m ...

  6. live 写博

    1           2           3           4           5         1       2       3       4       5         ...

  7. osg 基本几何图元

    转自:osg 基本几何图元 //osg 基本几何图元 // ogs中所有加入场景中的数据都会加入到一个Group类对象中,几何图元作为一个对象由osg::Geode类来组织管理. // 绘制几何图元对 ...

  8. HBASE的安装

    HBASE的安装: 安装的软件版本:hbase-0.98.4-hadoop2.tar.gz 下载链接:http://www.apache.org/dist/hbase/hbase-0.98.4/ 1. ...

  9. 用shell查找某个目录下最大文件

    网上资料学习: 1.查找当前目录下最大文件(包括子目录里文件): find . -type f -exec stat -c "%s %n" {} \; | sort -nr | h ...

  10. 【GPS】 数据围栏

    1.记录gps信息,定位类型  gps  agps ,偏移量 2.根据id检索用户 gps 历史记录 3.创建围栏 4.围栏内用户检索(先实现 圆形和矩形) 5.判断一个点是否进出围栏 应用场景: o ...