posts - 23,comments - 66,trackbacks - 0
by lostfire

这两天准备做一些网站编程的工作,于是对HtmlParse小研究了一下,目的是快速入手,而不是深入研究,做了一下整理,和大家共同讨论一下。
 
一,数据组织分析:

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:文本节点
 
二,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组合是难以做成什么事情的。
 
三,系统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:用来修改网页中的链接。
四,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来过滤节点,提取出我们所关注的节点,再对节点进行处理。通过这样的组合,一定能够找出我们所需要的信息。
 
参考:
http://htmlparser.sourceforge.net/
http://www.blogjava.net/rocky/archive/2005/12/21/24997.aspx
http://www.westing.cn/xblog/?p=90
posted on 2006-07-02 22:47 rd2pm 阅读(34179) 评论(23)  编辑  收藏 所属分类: http tool

FeedBack:
# re: HtmlParser初步研究
2006-07-03 10:26 | 艾尘
这东西不错。一年前用来做过项目。可以自定义Tag,还是比较方便。邮件列表也天天更新。  回复  更多评论
  
# re: HtmlParser初步研究
2006-07-03 13:12 | rox
晕倒,我正好用过了,你才写。
不过,还是感谢你为大家的劳动。
呵呵。  回复  更多评论
  
# re: HtmlParser初步研究
2006-07-03 14:15 | lostfire
@rox
看来还是有很多人用的,大家都用来做什么方面的工作啊?  回复  更多评论
  
# re: HtmlParser初步研究
2006-07-03 15:15 | 老妖
汗,这个东西还真的有人用啊!当时只是初步写了一个应急的小demo哦,好久没有上blog了,没有想到有这么多人捧场,顶一下  回复  更多评论
  
# re: HtmlParser初步研究
2006-07-09 15:56 | pysh@163.com
htmlParser有好多。我用的是叫什么jericho提供的api。如果你也是欢迎交流一下qq 54171690  回复  更多评论
  
# re: HtmlParser初步研究
2006-08-18 14:18 | common
一个例子就行了。  回复  更多评论
  
# re: HtmlParser初步研究
2006-10-14 13:18 | czp
太他妈的志同道和了
正需要这方面的资料啊




狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!狂顶!  回复  更多评论
  
# re: HtmlParser初步研究
2007-01-05 17:38 | ruozhi
刚接手一个项目要解析html,先拿它试验一次.QQ:52386348  回复  更多评论
  
# re: HtmlParser初步研究
2007-02-05 00:50 | 涂万刚
辉哥!

我顶  回复  更多评论
  
# re: HtmlParser初步研究
2007-04-30 14:10 | 雨夜
刚学........................  回复  更多评论
  
# re: HtmlParser初步研究
2007-05-27 09:47 | liu_UFO
顶哈,我也刚刚开始学习java ,我的毕业论文是用java 作,需要解析html,提取论坛里面的文字,正在学习htmlparse  回复  更多评论
  
# re: HtmlParser初步研究
2007-08-26 15:40 | 邹江
@liu_UFO


你好,我想了解下你以前做提取论坛里面的内容是怎么提取的,源代码还有吗  回复  更多评论
  
# re: HtmlParser初步研究
2007-10-05 17:55 |
不错,不过还是有些不全,对于初学者来讲还是不太明白,像node里有很多东西都要用到,但没有写。
谢谢,已经了解了不少!  回复  更多评论
  
# re: HtmlParser初步研究
2007-10-28 19:58 | 中华信鸽
找到了:)  回复  更多评论
  
# re: HtmlParser初步研究
2007-11-28 11:56 | 北京seo
不错.  回复  更多评论
  
# re: HtmlParser初步研究
2009-05-03 13:46 | 11
相当不错,对于我这样的初学者还是非常有用的。  回复  更多评论
  
# re: HtmlParser初步研究[未登录]
2009-11-28 00:43 | dongdong
你好,我现在在自学HTMLPARSER和爬虫这里,谢谢你的文章,给我提供了帮助。希望能够和你成为朋友,向你多多请教。所以。。可以留下一个联系方式么?QQ或邮箱,不胜荣幸。
我的邮箱是Spirit.dongdong@gmail.com  回复  更多评论
  
# re: HtmlParser初步研究
2009-12-13 15:32 | hahabk
来学习了.  回复  更多评论
  
# re: HtmlParser初步研究
2009-12-25 16:46 | cqyuu
学习了~!谢谢~!  回复  更多评论
  
# re: HtmlParser初步研究
2010-12-03 10:20 | 火地晋
楼主知道有css parser吗  回复  更多评论
  
# re: HtmlParser初步研究
2011-03-05 18:05 | guolongxin
你好,我也在做一个这样的东西,但是不会,你能把你以前做的发我看下吗?谢谢
我的邮箱490403992@qq.com  回复  更多评论
  
# re: HtmlParser初步研究
2011-11-21 20:24 | 忧伤恛忆
谢谢楼主,最近正好用到。。。。。。不过还是有些看不明白。。。。  回复  更多评论
  
# re: HtmlParser初步研究
2012-04-29 07:40 | newgod
解析完 http://www.sina.com.cn 要多少毫秒?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: