HTMLParser使用详解(4)- 通过Visitor访问内容
2009-03-12 19:47:04
标签:
HTMLParser Java [ 推送到技术圈]
HTMLParser遍历了网页的内容以后,以树(森林)结构保存了结果。HTMLParser访问结果内容的方法有两种。使用Filter和使用Visitor。
下面介绍使用Visitor访问内容的方法。 4.1 NodeVisitor 从简单方面的理解,Filter是根据某种条件过滤取出需要的Node再进行处理。Visitor则是遍历内容树的每一个节点,对于符合条件的节点进行处理。实际的结果异曲同工,两种不同的方法可以达到相同的结果。 下面是一个最常见的NodeVisitro的例子。 测试代码:
public
static
void main(String[] args) {
try{ Parser parser = new Parser( (HttpURLConnection) ( new URL( "http://127.0.0.1:8080/HTMLParserTester.html")).openConnection() ); NodeVisitor visitor = new NodeVisitor( false, false ) { public void visitTag(Tag tag) { message("This is Tag:"+tag.getText()); } public void visitStringNode (Text string) { message("This is Text:"+string); } public void visitRemarkNode (Remark remark) { message("This is Remark:"+remark.getText()); } public void beginParsing () { message("beginParsing"); } public void visitEndTag (Tag tag){ message("visitEndTag:"+tag.getText()); } public void finishedParsing () { message("finishedParsing"); } }; parser.visitAllNodesWith(visitor); } catch( Exception e ) { e.printStackTrace(); } } 输出结果: beginParsing This is Tag:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" This is Text:Txt (121[0,121],123[1,0]): /n This is Text:Txt (244[1,121],246[2,0]): /n finishedParsing 可 以看到,开始遍历所以的节点以前,beginParsing先被调用,然后处理的是中间的Node,最后在结束遍历以前,finishParsing被调 用。因为我设置的 recurseChildren和recurseSelf都是false,所以Visitor没有访问子节点也没有访问根节点的内容。中间输出的两个/n 就是我们在 HTMLParser使用详解(1)- 初始化Parser 中讨论过的最高层的那两个换行。 我们先把recurseSelf设置成true,看看会发生什么。 NodeVisitor visitor = new NodeVisitor( false, true) { 输出结果: beginParsing This is Tag:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" This is Text:Txt (121[0,121],123[1,0]): /n This is Tag:head This is Text:Txt (244[1,121],246[2,0]): /n This is Tag:html xmlns="http://www.w3.org/1999/xhtml" finishedParsing 可以看到,HTML页面的第一层节点都被调用了。 我们再用下面的方法调用看看: NodeVisitor visitor = new NodeVisitor( true, false) { 输出结果: beginParsing This is Tag:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" This is Text:Txt (121[0,121],123[1,0]): /n This is Tag:meta http-equiv="Content-Type" content="text/html; charset=gb2312" This is Text:Txt (204[1,81],229[1,106]): 白泽居-title-www.baizeju.com visitEndTag:/title visitEndTag:/head This is Text:Txt (244[1,121],246[2,0]): /n This is Text:Txt (289[2,43],291[3,0]): /n This is Text:Txt (298[3,7],300[4,0]): /n This is Text:Txt (319[4,19],322[5,1]): /n/t This is Text:Txt (342[5,21],346[6,2]): /n/t/t This is Remark:这是注释 白泽居-www.baizeju.com This is Text:Txt (378[6,34],408[8,0]): /n/t/t白泽居-字符串1-www.baizeju.com/n This is Text:Txt (441[8,33],465[8,57]): 白泽居-链接文本-www.baizeju.com visitEndTag:/a This is Text:Txt (469[8,61],472[9,1]): /n/t visitEndTag:/div This is Text:Txt (478[9,7],507[11,0]): /n/t白泽居-字符串2-www.baizeju.com/n visitEndTag:/div This is Text:Txt (513[11,6],515[12,0]): /n visitEndTag:/body This is Text:Txt (522[12,7],524[13,0]): /n visitEndTag:/html finishedParsing 可以看到,所有的子节点都出现了,除了刚刚例子里面的两个最上层节点This is Tag:head和This is Tag:html xmlns="http://www.w3.org/1999/xhtml"。 想让它们都出来,只需要 NodeVisitor visitor = new NodeVisitor( true, true) { 输出结果: beginParsing This is Tag:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" This is Text:Txt (121[0,121],123[1,0]): /n This is Tag:head This is Tag:meta http-equiv="Content-Type" content="text/html; charset=gb2312" This is Tag:title This is Text:Txt (204[1,81],229[1,106]): 白泽居-title-www.baizeju.com visitEndTag:/title visitEndTag:/head This is Text:Txt (244[1,121],246[2,0]): /n This is Tag:html xmlns="http://www.w3.org/1999/xhtml" This is Text:Txt (289[2,43],291[3,0]): /n This is Tag:body This is Text:Txt (298[3,7],300[4,0]): /n This is Tag:div id="top_main" This is Text:Txt (319[4,19],322[5,1]): /n/t This is Tag:div id="logoindex" This is Text:Txt (342[5,21],346[6,2]): /n/t/t This is Remark:这是注释 白泽居-www.baizeju.com This is Text:Txt (378[6,34],408[8,0]): /n/t/t白泽居-字符串1-www.baizeju.com/n This is Tag:a href="http://www.baizeju.com" This is Text:Txt (441[8,33],465[8,57]): 白泽居-链接文本-www.baizeju.com visitEndTag:/a This is Text:Txt (469[8,61],472[9,1]): /n/t visitEndTag:/div This is Text:Txt (478[9,7],507[11,0]): /n/t白泽居-字符串2-www.baizeju.com/n visitEndTag:/div This is Text:Txt (513[11,6],515[12,0]): /n visitEndTag:/body This is Text:Txt (522[12,7],524[13,0]): /n visitEndTag:/html finishedParsing 哈哈,这下调用清楚了,大家在需要处理的地方增加自己的代码好了。 4.2 其他Visitor HTMLParser 还定义了几个其他的Visitor。 HtmlPage,NodeVisitor,ObjectFindingVisitor,StringFindingVisitor,TagFindingVisitor,TextExtractingVisitor,UrlModifyingVisitor, 它们都是NodeVisitor的子类,实现了一些特定的功能。笔者个人的感觉是没什么用处,如果你需要什么特定的功能,还不如自己写一个,想在这些里面 找到适合你需要的,化的时间可能更多。反正大家看看代码就发现,它们每个都没几行真正有效的代码。 |