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. codeforces 60B bfs

    题意:给出一个六面体分为k层,每层n行m列,每个小立方体有'.'(空)与'#'(障碍)的状态,第一层某个空的位置有一个水龙头,水流每次往六个方向流动(...).最少时间水流能把立方体空的部分填满. 思 ...

  2. Spring Cloud之Hystrix服务保护框架

    服务保护利器 微服务高可用技术 大型复杂的分布式系统中,高可用相关的技术架构非常重要. 高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用的服务,从而足以应对分布式系统环境中的 ...

  3. Oracle数据库的三种验证机制

    关于超级管理员登陆不需要密码因为: 数据库的三种验证机制: 操作系统验证(具有sysdba和sysopera的用户) 密码文件验证(具有sysdba和sysopera的用户) 数据库验证(普通用户) ...

  4. 分享知识-快乐自己:Mybatis 基础动态语句

    目录: User: package mlq.bean; /** * 用户实体类 */ public class User { private Integer uId; private String u ...

  5. 十四 Django框架,中间件

    django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在django项目的se ...

  6. PL/SQL学习笔记_01_基础:变量、流程控制

    PL/SQL语句可以在Oracle客户端的 SQL窗口或者 command  窗口中运行 在SQL窗口中运行步骤同 SQL语句 在command  窗口中运行的步骤如下: 1)File—new com ...

  7. Java丨JDK与JRE

    小编是以为热爱Java的程序员,可是在我身边的一部分人他们不知道JDK和JRE是什么,有什么区别! 今天小编以个人的理解来说一说,不足之处还望大家指证. 首先我们来看看JDK和JRE他们两个的英文意思 ...

  8. (转)#ifndef的用法

    原文链接:http://wenku.baidu.com/link?url=c4doqVo3U429RkwTN5eaJIfD2rEu-1bLKKQXuqO8drmL359PhUjVmzC7P94wBY9 ...

  9. 2017人工智能元年,AI在喧嚣和质疑中一路走来

    前百度首席科学家吴恩达说:就像100年前的电力.20年前的互联网一样,AI也会改变每一个产业! 有人说,现在就像1995年,那一年,第一家互联网公司--网景上市,一天之内大涨208%,互联网正式登上历 ...

  10. docker数据卷(volume)

    1.什么是数据卷volume https://blog.csdn.net/dream_broken/article/details/52314993 为了了解什么是Docker Volume,首先我们 ...