HTMLParser使用详解(2)- Node内容  2010-03-18 13:41
HTMLParser将解析过的信息留存为一个树的结构。Node是信息留存的数据类型基础。
请看Node的界说:
public interface Node extends Cloneable;

Node中包括的要领有几类:
  1、对付树型结构进行遍历的函数,这些函数最轻易理解:
Node getParent ():取得父节点
NodeList getChildren ():取得子节点的列表
Node getFirstChild ():取得第一个子节点
Node getLastChild ():取得最后一个子节点
Node getPreviousSibling ():取得前一个兄弟(欠好意思,英文是兄弟姐妹,直译太麻烦并且不相符习惯,抱歉女同胞了)
Node getNextSibling ():取得下一个兄弟节点
  2、取得Node内容的函数:
String getText ():取得文本
String toPlainTextString():取得纯文本信息。
String toHtml () :取得HTML信息(原始HTML)
String toHtml (boolean verbatim):取得HTML信息(原始HTML)
String toString ():取得字符串信息(原始HTML)
Page getPage ():取得这个Node对应的Page东西
int getStartPosition ():取得这个Node在HTML页面中的起始位置
int getEndPosition ():取得这个Node在HTML页面中的结束位置
  3、用于Filter过滤的函数
void collectInto (NodeList list, NodeFilter filter):基于filter的条件对付这个节点进行过滤,相符条件的节点放到list中。
  4、用于Visitor遍历的函数:
void accept (NodeVisitor visitor):对这个Node应用visitor
  5、用于修改内容的函数,这类用得比较少:
void setPage (Page page):设置这个Node对应的Page东西
void setText (String text):设置文本
void setChildren (NodeList children):设置子节点列表
  6、其他函数:
void doSemanticAction ():执行这个Node对应的操纵(只有少数Tag有对应的操纵)
Object clone ():接口Clone的抽象函数。

实际我们用HTMLParser最多的是处理HTML页面,Filter或Visitor相关的函数是务必的,然后第一类和第二类函数是用得最多的。

   第一类函数比较轻易理解,下面用例子说明一下第二类函数。
下面是用于测试的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.baizeju.com</title><
/head>
<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释-->
白泽居-www.baizeju.com
<a href="http://www.baizeju.com">白泽居-www.baizeju.com</a>
</div>
白泽居-www.baizeju.com
</div>
</body>
</html>

测试源代码:
/**
* @author www.baizeju.com
*/
package com.baizeju.htmlparsertester;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import org.htmlparser.Node;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.Parser;

/**
* @author www.baizeju.com
*/
   public class Main {
private static String ENCODE = "GBK";
private static voidmessage( String szMsg ) {
     try{ System.out.println(new String(szMsg.getBytes(ENCODE), System.getProperty("file.encoding"))); }

    catch(Exception e ){}                                  }
public static String openFile( String szFileName ) {
             try {
  BufferedReader bis = new BufferedReader(new InputStreamReader(new FileInputStream( new File(szFileName)), ENCODE) );
  String szContent="";
  String szTemp;
   while ( ( szTemp = bis.readLine()) != null) {
     szContent+=szTemp+"\n";                     }
     bis.close();
      return szContent;
             }
      catch( Exception e ) {
return "";
}
}

public static void main(String[] args) {
  try{
  Parser parser = new Parser( (HttpURLConnection) (new URL("http://127.0.0.1:8080/HTMLParserTester.html")).openConnection() );
  for (NodeIterator i = parser.elements (); i.hasMoreNodes(); )

 {
   Node node = i.nextNode();
   message("getText:"+node.getText());
   message("getPlainText:"+node.toPlainTextString());
   message("toHtml:"+node.toHtml());
   message("toHtml(true):"+node.toHtml(true));
   message("toHtml(false):"+node.toHtml(false));
   message("toString:"+node.toString());
   message("=================================================");
   }
}
catch( Exception e ) {
System.out.println( "Exception:"+e );
                            }
   }
}

输出结果:
getText:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
getPlainText:
toHtml:<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
toHtml(true):<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
toHtml(false):<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
toString:Doctype
Tag : !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd; begins at : 0;
ends at : 121
=================================================
getText:
getPlainText:
toHtml:
toHtml(true):
toHtml(false):
toString:Txt (121[0,121],123[1,0]): \n
=================================================
getText:head
getPlainText:白泽居-www.baizeju.com
toHtml:<head><meta
http-equiv="Content-Type" content="text/html;
charset=gb2312"><title>白泽居-www.baizeju.com</title><
/head>
toHtml(true):<head><meta http-equiv="Content-Type"
content="text/html;
charset=gb2312"><title>白泽居-www.baizeju.com</title><
/head>
toHtml(false):<head><meta
http-equiv="Content-Type" content="text/html;
charset=gb2312"><title>白泽居-www.baizeju.com</title><
/head>
toString:HEAD: Tag (123[1,0],129[1,6]): head
Tag (129[1,6],197[1,74]): meta http-equiv="Content-Type" content="text/html; ...
Tag (197[1,74],204[1,81]): title
Txt (204[1,81],223[1,100]): 白泽居-www.baizeju.com
End (223[1,100],231[1,108]): /title
End (231[1,108],238[1,115]): /head

=================================================
getText:
getPlainText:
toHtml:
toHtml(true):
toHtml(false):
toString:Txt (238[1,115],240[2,0]): \n
=================================================
getText:html xmlns="http://www.w3.org/1999/xhtml"
getPlainText:
白泽居-www.baizeju.com
白泽居-www.baizeju.com
白泽居-www.baizeju.com
toHtml:<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释-->
白泽居-www.baizeju.com
<a href="http://www.baizeju.com">白泽居-www.baizeju.com</a>
</div>
白泽居-www.baizeju.com
</div>
</body>
</html>
toHtml(true):<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释-->
白泽居-www.baizeju.com
<a href="http://www.baizeju.com">白泽居-www.baizeju.com</a>
</div>
白泽居-www.baizeju.com
</div>
</body>
</html>
toHtml(false):<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释-->
白泽居-www.baizeju.com
<a href="http://www.baizeju.com">白泽居-www.baizeju.com</a>
</div>
白泽居-www.baizeju.com
</div>
</body>
</html>
toString:Tag (240[2,0],283[2,43]): html xmlns="http://www.w3.org/1999/xhtml"
Txt (283[2,43],285[3,0]): \n
Tag (285[3,0],292[3,7]): body
Txt (292[3,7],294[4,0]): \n
Tag (294[4,0],313[4,19]): div id="top_main"
Txt (313[4,19],316[5,1]): \n\t
Tag (316[5,1],336[5,21]): div id="logoindex"
Txt (336[5,21],340[6,2]): \n\t\t
Rem (340[6,2],351[6,13]): 这是注释
Txt (351[6,13],376[8,0]): \n\t\t白泽居-www.baizeju.com\n
Tag (376[8,0],409[8,33]): a href="http://www.baizeju.com"
Txt (409[8,33],428[8,52]): 白泽居-www.baizeju.com
End (428[8,52],432[8,56]): /a
Txt (432[8,56],435[9,1]): \n\t
End (435[9,1],441[9,7]): /div
Txt (441[9,7],465[11,0]): \n\t白泽居-www.baizeju.com\n
End (465[11,0],471[11,6]): /div
Txt (471[11,6],473[12,0]): \n
End (473[12,0],480[12,7]): /body
Txt (480[12,7],482[13,0]): \n
End (482[13,0],489[13,7]): /html

=================================================
 
对付第一个Node的内容,对应的就是第一行<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">,这个比较好理解。
从这个输出结果中,也可以看出内容的树状结构。或者说是树林结构。在Page内容的第一层Tag,如DOCTYPE,head和html,分别形成了一个最高层的Node节点(很多人可能对第二个和第四个Node的内容有点希罕。实际上这两个Node就是两个换行标记。HTMLParser把HTML页面内容中的所有换行,空格,Tab等都转换成了相应的Tag,所以就出现了这样的Node。虽然内容少但是级别高,呵呵)
  getPlainTextString是把用户可以看到的内容都包括了。有趣的有两点,一是<head>标签中的Title内容是在 plainText中的,可能在标题中可见的也算可见吧。

另外就是象前面说的,HTML内容中的换行符什么的,也都成了plainText,这个逻辑上似乎有点问题。

另外可能大众发觉toHtml,toHtml(true)和toHtml(false)的结果没什么区别。实际也是这样的,假如跟踪HTMLParser
的源代码就可以发觉,Node的子类是AbstractNode,其中实现了toHtml()的源代码,直接挪用toHtml(false),而
AbstractNode的三个子类RemarkNode,TagNode和TextNode中,toHtml(boolean
verbatim)的实现中,都没有处理verbatim参数,所以三个函数的结果是一模一样的。假如你不需要实现你自己的什么特别处理,简单使用
toHtml就可以了。
  HTML的Node类继续关系如下图(这个是从另外文章Copy的):

     AbstractNodes是Node的直接子类,也是一个抽象类。它的三个直接子类实现是
    RemarkNode,用于留存注释。在输出结果的 toString局部中可以看到有一个"Rem (345[6,2],356[6,13]): 这是注释",就是一个RemarkNode。
    TextNode也很简单,就是用户可见的文字信息。
    TagNode是最纷乱的,包括了HTML语言中的所有标签,并且可以扩展(扩展 HTMLParser 对自界说标签的处理能力)。
TagNode包括两类,一类是简单的Tag,实际就是不克包括其他Tag的标签,只能做叶子节点。另一类是 CompositeTag,就是可以包括其他Tag,是分支节点

HTMLParser使用详解(2)- Node内容的更多相关文章

  1. HTMLParser 使用详解

    htmlparser是一个纯的java写的html解析的库,它不依赖于其它的java库文件,主要用于改造或   提取html.它能超高速解析html,而且不会出错.现在htmlparser最新版本为2 ...

  2. HTMLParser使用详解(3)- 通过Filter访问内容

    HTMLParser遍历了网页的内容以后,以树(森林)结构保存了结果.HTMLParser访问结果内容的方法有两种.使用Filter和使用Visitor. (一)Filter类顾名思义,Filter就 ...

  3. win10 安装vue 详解-包括node.js、npm、webpack

    1.下载 去官网下载 node.js https://nodejs.org/en/download/ 一般不会选择最新的,我安装的是 12.18.4 进入历史记录页面网址 https://nodejs ...

  4. db2数据库新手可能碰到的问题及详解(部分内容来自网络搜索)

    一.db2安装好之后出现乱码,菜单栏呈现方框状,此时选择菜单第五项,点击选择下拉菜单中的最后一项,打开选择标签卡的第三项(字体),如果是无衬线都改为有衬线,如果是有衬线改为无衬线.乱码即可解决(网上一 ...

  5. JAVA中IO和NIO的详解分析,内容来自网络和自己总结

    用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...

  6. liunx-centos-基础命令详解(1) -主要内容来自 —https://www.cnblogs.com/caozy/p/9261224.html

    关机:halt/poweroff :立刻关机reboot :立刻重启 shutdown -r now :立刻重启shutdown -h 00:00 :定时重启 now:立刻shutdown -h +n ...

  7. Java解析HTML之HTMLParser使用与详解 分类: C_OHTERS 2014-05-19 21:46 2309人阅读 评论(0) 收藏

    转自:http://free0007.iteye.com/blog/1131163 HTMLParser具有小巧,快速的优点,缺点是相关文档比较少(英文的也少),很多功能需要自己摸索.对于初学者还是要 ...

  8. Node.js中环境变量process.env详解

    Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...

  9. HTML标签----图文详解(二)

    HTML标签超详细的图文演示再来一波~~~ 如果还没有看过昨天的福利的,那可要抓紧喽,传送门:HTML标签----图文详解 本文主要内容 列表标签 表格标签 框架标签及内嵌框架<iframe&g ...

随机推荐

  1. poj 1328 Radar Installatio【贪心】

    题目地址:http://poj.org/problem?id=1328 Sample Input 3 2 1 2 -3 1 2 1 1 2 0 2 0 0 Sample Output Case 1: ...

  2. 二分 连续上升子序列变形 UVA1471

    最大上升子序列解法: 1.动规转移方程 2.(nlogn) #include<cstdio> #include<algorithm> using namespace std; ...

  3. linux rpm包的编译

    有些软件包的特性是编译者选定的,如果编译未选定此特性,将无法使用.rpm包的版本落后于源码包. 因此需要定制安装,也就是手动编译安装. 编译需要编译环境. 编译的过程如下: 1.下载源码 2.执行 t ...

  4. js文件报错Syntax error on token "Invalid Regular Expression Options", no accurate correction

    Syntax error on token "Invalid Regular Expression Options", no accurate correction 1.选中报错的 ...

  5. 数据库中的id不会自动 替换,这个应该处理吗。怎么处理,那个是唯一主键

  6. (转)Java 调用 C++ (Java 调用 dll)

    转自: http://www.cnblogs.com/baokang/p/4979243.html 因为要做点图形处理的项目,需要在Java中调用dll库,所以开发的第一步是研究了一下Java Jni ...

  7. hdu-5867 Water problem(水题)

    题目链接: Water problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  8. Agc019_F Yes or No

    传送门 题目大意 有若干道判断题,其中有$n$道答案是$Yes$,另外$m$道答案是$No$,问题除了答案差异本质相同.这些题一道都不会做,但是事先知道$n$和$m$的数量.每次机器会事先等概率地排列 ...

  9. OI省选算法汇总( 转发黄学长博客 )

    [原文链接] http://hzwer.com/1234.html 注 : 蓝色为已学习算法 , 绿色为不熟练算法 , 灰色为未学习算法 1.1 基本数据结构 1. 数组 2. 链表,双向链表 3. ...

  10. 寻找总和为n的连续子数列之算法分析

    看到有这么道算法题在博客园讨论,算法eaglet和邀月都已经设计出来了,花了点时间读了下,学到点东西顺便记录下来吧. 题目是从1...n的数列中,找出总和为n的连续子数列. 这里先设好算法中需要用到的 ...