`
gstarwd
  • 浏览: 1489115 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

HTMLParser的两种使用方法

阅读更多

HTMLParser的两种使用方法

 

因为论文的关系,要 用到HTMLParser这个项目(使用的HTMLParser版本是1.6)

一,数据组织分析:

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来过滤节点,提取出我们所关注的节点,再对节点进行处理。通过这样的组合,一定能够找出 我们所需要的信息。
我的代码
package  com.eric.Html.htmlparser;

import  org.htmlparser.Node;
import  org.htmlparser.NodeFilter;
import  org.htmlparser.Parser;
import  org.htmlparser.filters.AndFilter;
import  org.htmlparser.filters.HasAttributeFilter;
import  org.htmlparser.filters.HasChildFilter;
import  org.htmlparser.filters.TagNameFilter;
import  org.htmlparser.util.NodeList;
import  org.htmlparser.util.ParserException;
import  org.htmlparser.visitors.TextExtractingVisitor;

/** */ /**
 * 
@author  作者 Eric yang E-mail:yjboy1982@126.com
 * 
@version  创建时间:2007-7-16 下午02:49:55
 * 类说明
 
*/

public   class  AstroExtractorTest  ... {

    
/** */ /**
     * 
@param  args
     * 
@throws  ParserException 
     
*/

    
public   static   void  main(String[] args)  throws  ParserException  ... {
        
//  TODO Auto-generated method stub
        String title ;
        String constellation ;
        String body ;
        String summary ;
        
        Parser parser 
=   new  Parser( " http://astro.sina.com.cn/sagittarius.html " );
        parser.setEncoding(
" GB2312 " ) ;
        
        NodeFilter filter_constellation_summart 
=   new  AndFilter(( new  TagNameFilter( " td " )),( new  HasChildFilter( new  TagNameFilter( " b " )))) ;
        
        NodeFilter filter_title 
=   new  AndFilter( new  TagNameFilter( " font " ),  new  HasAttributeFilter( " class " " f1491 " )) ;
        
        NodeFilter filter_body 
=   new  AndFilter(  new  TagNameFilter( " td " ),  new  HasAttributeFilter( " width " " 30% " )) ;
        
        NodeList nodelist 
=  parser.parse(filter_constellation_summart) ;
        Node node_constellation 
=  nodelist.elementAt( 0 ) ;        
        constellation 
=  node_constellation.getFirstChild().getNextSibling().toHtml() ;
            
        Node node_summary 
=  nodelist.elementAt( 1 ) ;
        NodeList summary_nodelist 
=  node_summary.getChildren() ;
        summary 
=  summary_nodelist.elementAt( 3 ).toHtml() + summary_nodelist.elementAt( 5 ).toHtml()  ;
        
        parser.reset() ;
        
        nodelist 
=  parser.parse(filter_title) ;
        Node node_title 
=  nodelist.elementAt( 0 ) ;
        title 
=  node_title.getNextSibling().getNextSibling().toHtml() ;
        
// title = node_title.getNextSibling().getNextSibling().toHtml() ;
        
        parser.reset() ;
        
        nodelist 
=  parser.parse(filter_body) ;
        Node node_body 
=  nodelist.elementAt( 0 ) ;
        Parser body_parser 
=   new  Parser(node_body.toHtml()) ;
        TextExtractingVisitor visitor 
=   new  TextExtractingVisitor() ;
        body_parser.visitAllNodesWith(visitor) ;
        body 
=  visitor.getExtractedText() ;
        
        
// System.out.println(node_summary.getChildren().toHtml()) ;
        
// System.out.println(node_body.toHtml()) ;
        
// System.out.println(title.trim()) ;
        
// System.out.println(constellation.trim()) ;
        
// System.out.println(body.trim()) ;
        System.out.println(summary.trim()) ;
        
    }


}

(编辑:aniston)
分享到:
评论

相关推荐

    用C#实现HtmlParser的代码

    该文档介绍了两种用C#来实现HtmlParser、对网页进行解析的方法,对于初学者有着很大帮助。

    HTMLParser Jar+src+html文档+chm文档+HttpClient Jar

    里面包含了HtmParser, Httpclient两个工具,一个用来获取网络页面,一个用来解析,配合使用,功能强大,里面还有HtmlParser 的帮助文档(格式有html和chm两种)欢迎大家前来下载使用,如果问题请联系我。

    html-parser:自己动手做

    代码采用Python3编写。 运行 python3 parser.py 学习建议 本解析器当前分两次提交,第一次是主框架,第二次...支持TextNode和ElementNode两种DOM结构 属性解析 自闭和标签 通过dfs实现层级缩进,方便调试 快来了...

    HttpClient以及获取页面内容应用

    1.4使用方法与步骤 开发环境:需要 使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。 1.创建HttpClient对象。 HttpClient client = new HttpClient(); 2.创建请求方法的实例,并指定请求URL。如果...

    Python编程入门经典

    1.3.3 为什么有3种类型的引号 7 1.3.4 使用print()函数 7 1.3.5 理解不同的引号 8 1.4 串联两个字符串 10 1.5 用不同的方法串联字符串 11 1.6 本章小结 12 1.7 习题 13 第2章 数值与运算符 15 2.1 不同类型的数值 15...

    基于Java和Python的爬虫项目实战源码.zip

    每个镜头的非边界过渡区的第一帧确定为关键帧 【找镜头边界:基于帧差的镜头边界检测方法、基于模型的镜头边界检测方法、基于学习的镜头边界检测方法】 使用非极大值抑制法确定镜头边界系数极大值并排序,以实现基于...

    node-fast-html-parser:一个非常快速HTML解析器,生成简化的DOM,并支持基本元素查询

    快速HTML解析器是一种非常快速的HTML解析器。 它将生成简化的DOM树,并具有基本元素查询支持。 根据设计,它打算以最低的价格解析大量HTML文件,因此性能是重中之重。 因此,某些格式错误HTML可能无法正确解析,但...

    java开源包8

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包1

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包11

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包2

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包3

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包6

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包5

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包10

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包4

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包7

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包9

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    java开源包101

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

    Java资源包01

    parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG(解析表达式语法)分析设施。你定义的Java源代码的语法规则,直接,没有必要专门编写和维护,外部语法文件。同时保持蒸提供全面的支持,...

Global site tag (gtag.js) - Google Analytics