转载 http://www.cnblogs.com/549294286/archive/2012/09/04/2670601.html
HTMLParser的核心模块是org.htmlparser.Parser类,这个类实际完成了对于HTML页面的分析工作。这个类有下面几个构造函数:
public
Parser ();
public
Parser (Lexer lexer, ParserFeedback fb);
public
Parser (URLConnection connection, ParserFeedback fb)
throws
ParserException;
public
Parser (String resource, ParserFeedback feedback)
throws
ParserException;
public
Parser (String resource)
throws
ParserException;
public
Parser (Lexer lexer);
public
Parser (URLConnection connection)
throws
ParserException;
public
static
Parser createParser (String html, String charset);
//静态类
|
Node中包含的方法有几类:
对于树型结构进行遍历的函数,这些函数最容易理解:
Node getParent ():取得父节点
NodeList getChildren ():取得子节点的列表
Node getFirstChild ():取得第一个子节点
Node getLastChild ():取得最后一个子节点
Node getPreviousSibling ():取得前一个兄弟(不好意思,英文是兄弟姐妹,直译太麻烦而且不符合习惯,对不起女同胞了)
Node getNextSibling ():取得下一个兄弟节点
取得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页面中的结束位置
用于Filter过滤的函数:
void collectInto (NodeList list, NodeFilter filter):基于filter的条件对于这个节点进行过滤,符合条件的节点放到list中。
用于Visitor遍历的函数:
void accept (NodeVisitor visitor):对这个Node应用visitor
用于修改内容的函数,这类用得比较少:
void setPage (Page page):设置这个Node对应的Page对象
void setText (String text):设置文本
void setChildren (NodeList children):设置子节点列表
其他函数:
void doSemanticAction ():执行这个Node对应的操作(只有少数Tag有对应的操作)
Object clone ():接口Clone的抽象函数。
类框架图:
AbstractNodes是Node的直接子类,也是一个抽象类。它的三个直接子类实现是RemarkNode,用于保存注释。在输出结果的toString部分中可以看到有一个"Rem (345[6,2],356[6,13]): 这是注释",就是一个RemarkNode。TextNode也很简单,就是用户可见的文字信息。TagNode是最复杂的,包含了HTML语言中的所有标签,而且可以扩展(扩展 HTMLParser 对自定义标签的处理能力)。TagNode包含两类,一类是简单的Tag,实际就是不能包含其他Tag的标签,只能做叶子节点。另一类是CompositeTag,就是可以包含其他Tag,是分支节点
HTMLParser遍历了网页的内容以后,以树(森林)结构保存了结果。HTMLParser访问结果内容的方法有两种。使用Filter和使用Visitor。
实际我们用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
>
<
body
>
<
div
id
=
"top_main"
>
<
div
id
=
"logoindex"
>
<!--这是注释-->
白泽居-www.baizeju.com
</
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
void
message( 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
<body >
<div id=
"top_main"
>
<div id=
"logoindex"
>
<!--这是注释-->
白泽居-www.baizeju.com
|