Java解析HTML之NekoHTML
生活随笔
收集整理的這篇文章主要介紹了
Java解析HTML之NekoHTML
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
[size=medium]NekoHTML是一個(gè)簡(jiǎn)單地HTML掃描器和標(biāo)簽補(bǔ)償器(tag balancer),使得程序能解析HTML文檔并用標(biāo)準(zhǔn)的XML接口來訪問其中的信息。這個(gè)解析器能投掃描HTML文件并“修正”許多作者(人或機(jī)器)在編寫HTML文檔過程中常犯的錯(cuò)誤。NekoHTML能增補(bǔ)缺失的父元素、自動(dòng)用結(jié)束標(biāo)簽關(guān)閉相應(yīng)的元素,以及不匹配的內(nèi)嵌元素標(biāo)簽。NekoHTML的開發(fā)使用了Xerces Native Interface (XNI),后者是Xerces2的實(shí)現(xiàn)基礎(chǔ)。
[quote][url=http://jsoup.org/]jsoup[/url] 是一款Java 的HTML解析器,可直接解析某個(gè)URL地址、HTML文本內(nèi)容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于JQuery的操作方法來取出和操作數(shù)據(jù)。[/quote]
[url=http://nekohtml.sourceforge.net/]http://nekohtml.sourceforge.net/[/url]
[url=http://xerces.apache.org/xerces2-j/]http://xerces.apache.org/xerces2-j/[/url]
版本:nekohtml_1.9.15.jar xerces-2.9.1[/size]
[b]1、獲取元素內(nèi)容[/b]
//創(chuàng)建一個(gè)解析器
DOMParser parser = new DOMParser();
//解析HTML文件
parser.parse("html/test1.html");
//獲取解析后的DOM樹
Document document = parser.getDocument();
//通過getElementsByTagName獲取Node
NodeList nodeList = document.getElementsByTagName("a");
for (int i = 0; i < nodeList.getLength(); i++) {
Element e = (Element)nodeList.item(i);
System.out.print(e.getAttribute("href") + "\t");
System.out.println(e.getTextContent());
}
<html>
<head><title>test1</title></head>
<body>
<a href="http://www.sina.com.cn">www.sina.com.cn</a><br>
<a href="http://www.sohu.com">www.sohu.com</a><br>
<a href="http://www.163.com" name="test">www.163.com</a><br>
<a href="http://www.qq.com">www.qq.com</a><br>
</body>
</html>
[quote]
http://www.sina.com.cn www.sina.com.cn
http://www.sohu.com www.sohu.com
http://www.163.com www.163.com
http://www.qq.com www.qq.com
[/quote]
[b]2、使用XPathAPI[/b]
DOMParser parser = new DOMParser();
parser.parse("html/test2.html");
Node node = parser.getDocument();
//獲取所有<td>內(nèi)容
//****注意在查找是必須使用大寫字母的tag名(NekoHTML默認(rèn)將HTML的tag名都轉(zhuǎn)成了大寫,屬性名變?yōu)樾?#xff09;
NodeList nodeList = XPathAPI.selectNodeList(node, "//TD");
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getTextContent());
}
//獲取所有<a>內(nèi)容
NodeList nodeList2 = XPathAPI.selectNodeList(node, "//A");
for (int i = 0; i < nodeList2.getLength(); i++) {
Element e = (Element) nodeList2.item(i);
System.out.print(e.getAttribute("href") + "\t");
System.out.println(e.getTextContent());
}
<html>
<head><title>test2</title></head>
<body>
<h1>Page Title</h1>
<!-- Table -->
<table>
<tr>
<td>a1</td> <td>a2</td> <td>a3</td>
</tr>
<tr>
<td>b1</td> <td>b2</td> <td>b3</td>
</tr>
<tr>
<td>c1</td> <td>c2</td> <td>c3</td>
</tr>
</table>
<!-- Link -->
<a href="http://www.aaa.com/">aaa</a>
<a href="http://www.bbb.com/">bbb</a>
<a href="http://www.ccc.com/">ccc</a>
</body>
</html>
[quote]
a1
a2
a3
b1
b2
b3
c1
c2
c3
http://www.aaa.com/ aaa
http://www.bbb.com/ bbb
http://www.ccc.com/ ccc
[/quote]
[b]3、設(shè)置Filter[/b]
//生成ElementRemover(默認(rèn)會(huì)不輸出所有的Tag名)
ElementRemover remover = new ElementRemover();
//設(shè)置輸出的Tag名及其屬性
remover.acceptElement("title", null);
remover.acceptElement("a", new String[]{"href"});
//刪除Tag
remover.removeElement("script");
//生成StringWriter
StringWriter filteredDescription = new StringWriter();
Writer writer = new Writer(filteredDescription, null);
//設(shè)置Filter
XMLDocumentFilter[] filters = { remover, writer };
DOMParser parser = new DOMParser();
parser.setProperty("http://cyberneko.org/html/properties/filters", filters);
parser.parse("html/test3.html");
//獲取結(jié)果
String description = filteredDescription.toString();
System.out.println(description);
<html>
<head>
<title>test3</title>
<script src="http://www.iteye.com/javascripts/application.js" type="text/javascript"></script>
</head>
<body>
<!-- Link -->
<a href="http://www.aaa.com/">aaa</a>
<a href="http://www.bbb.com/">bbb</a>
<a href="http://www.ccc.com/">ccc</a>
</body>
</html>
[quote]
<TITLE>test3</TITLE>
<!-- Link -->
<A href="http://www.aaa.com/">aaa</A>
<A href="http://www.bbb.com/">bbb</A>
<A href="http://www.ccc.com/">ccc</A>
[/quote]
[b]4、補(bǔ)充修正[/b]
//補(bǔ)充修正
StringWriter filteredDescription1 = new StringWriter();
Writer writer1 = new Writer(filteredDescription1, null);
XMLDocumentFilter[] filters1 = { writer1 };
DOMParser parser1 = new DOMParser();
parser1.setProperty("http://cyberneko.org/html/properties/filters", filters1);
parser1.parse("html/test4.html");
System.out.println(filteredDescription1.toString());
System.out.println();
//不補(bǔ)充修正
StringWriter filteredDescription2 = new StringWriter();
Writer writer2 = new Writer(filteredDescription2, null);
XMLDocumentFilter[] filters2 = { writer2 };
DOMParser parser2 = new DOMParser();
parser2.setProperty("http://cyberneko.org/html/properties/filters", filters2);
//默認(rèn)為true
parser2.setFeature("http://cyberneko.org/html/features/balance-tags",false);
parser2.parse("html/test4.html");
System.out.println(filteredDescription2.toString());
System.out.println();
//nekohtml功能(feature)列表
//屬性 默認(rèn)值 值域 描述
//http://cyberneko.org/html/features/balance-tags True 是否允許增補(bǔ)缺失的標(biāo)簽。如果要以XML方式操作HTML文件,此值必須為真。此處提供設(shè)置功能,為了性能的原因。
//http://cyberneko.org/html/features/balance-tags/ignore-outside-content False 是否忽略文檔根元素以后的數(shù)據(jù)。如果為false,<html>和<bod>被忽略,所有的內(nèi)容都被解析。
//http://cyberneko.org/html/features/document-fragment False 解析HTML片段時(shí)是否作標(biāo)簽增補(bǔ)。此功能不要用在DOMParser上,而要用在DOMFragmentParser上。
//http://apache.org/xml/features/scanner/notify-char-refs False 當(dāng)遇到字符實(shí)體引用(如&#x20;)是否將(#x20)報(bào)告給相應(yīng)地文檔處理器。
//http://apache.org/xml/features/scanner/notify-builtin-refs False 當(dāng)遇到XML內(nèi)建的字符實(shí)體引用(如&amp;)是否將(amp)報(bào)告給相應(yīng)地文檔處理器。
//http://cyberneko.org/html/features/scanner/notify-builtin-refs False 當(dāng)遇到HTML內(nèi)建的字符實(shí)體引用(如&copy;)是否將(copy)報(bào)告給相應(yīng)地文檔處理器。
//http://cyberneko.org/html/features/scanner/script/strip-comment-delims False 是否剝掉<script>元素中的<!-- -->等注釋符。
//http://cyberneko.org/html/features/augmentations False 是否將與HTML事件有關(guān)的infoset項(xiàng)包括在解析管道中。
//http://cyberneko.org/html/features/report-errors False 是否報(bào)告錯(cuò)誤。
//nekohtml屬性列表
//屬性 默認(rèn)值 值域 描述
//http://cyberneko.org/html/properties/filters null XMLDocumentFilter[] 在解析管道的最后按數(shù)組順序追加自定義的處理組件(過濾器),必須為數(shù)組類型。
//http://cyberneko.org/html/properties/default-encoding Windows-1252 IANA encoding names 默認(rèn)的HTML文件編碼
//http://cyberneko.org/html/properties/names/elems 默認(rèn)為upper upper,lower,match 如果整理識(shí)別出的元素名稱
//http://cyberneko.org/html/properties/names/attrs 默認(rèn)為lower upper,lower,no-change 如果整理識(shí)別出的屬性名稱
<a href="http://www.aaa.com/">aaa
<a href="http://www.bbb.com/">bbb
<a href="http://www.ccc.com/">ccc
[quote]
<HTML><HEAD></HEAD><BODY><A href="http://www.aaa.com/">aaa
</A><A href="http://www.bbb.com/">bbb
</A><A href="http://www.ccc.com/">ccc</A></BODY></HTML>
<A href="http://www.aaa.com/">aaa
<A href="http://www.bbb.com/">bbb
<A href="http://www.ccc.com/">ccc
[/quote]
[b]5、DOMFragmentParser[/b]
DOMFragmentParser parser = new DOMFragmentParser();
HTMLDocument document = new HTMLDocumentImpl();
DocumentFragment fragment = document.createDocumentFragment();
parser.parse("html/test5.html", fragment);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(new DOMSource(fragment), new StreamResult(new OutputStreamWriter(System.out, "utf-8")));
<html><head><title>test2</title></head><body><h1>Page Title</h1><!-- Table --><table><tr><td>a1</td><td>a2</td><td>a3</td></tr><tr><td>b1</td><td>b2</td><td>b3</td></tr><tr><td>c1</td><td>c2</td><td>c3</td></tr></table></body></html>
[quote]
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>test2</TITLE>
</HEAD>
<BODY>
<H1>Page Title</H1>
<!-- Table -->
<TABLE>
<TBODY>
<TR>
<TD>a1</TD><TD>a2</TD><TD>a3</TD>
</TR>
<TR>
<TD>b1</TD><TD>b2</TD><TD>b3</TD>
</TR>
<TR>
<TD>c1</TD><TD>c2</TD><TD>c3</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
[/quote]
[quote][url=http://jsoup.org/]jsoup[/url] 是一款Java 的HTML解析器,可直接解析某個(gè)URL地址、HTML文本內(nèi)容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于JQuery的操作方法來取出和操作數(shù)據(jù)。[/quote]
[url=http://nekohtml.sourceforge.net/]http://nekohtml.sourceforge.net/[/url]
[url=http://xerces.apache.org/xerces2-j/]http://xerces.apache.org/xerces2-j/[/url]
版本:nekohtml_1.9.15.jar xerces-2.9.1[/size]
[b]1、獲取元素內(nèi)容[/b]
//創(chuàng)建一個(gè)解析器
DOMParser parser = new DOMParser();
//解析HTML文件
parser.parse("html/test1.html");
//獲取解析后的DOM樹
Document document = parser.getDocument();
//通過getElementsByTagName獲取Node
NodeList nodeList = document.getElementsByTagName("a");
for (int i = 0; i < nodeList.getLength(); i++) {
Element e = (Element)nodeList.item(i);
System.out.print(e.getAttribute("href") + "\t");
System.out.println(e.getTextContent());
}
<html>
<head><title>test1</title></head>
<body>
<a href="http://www.sina.com.cn">www.sina.com.cn</a><br>
<a href="http://www.sohu.com">www.sohu.com</a><br>
<a href="http://www.163.com" name="test">www.163.com</a><br>
<a href="http://www.qq.com">www.qq.com</a><br>
</body>
</html>
[quote]
http://www.sina.com.cn www.sina.com.cn
http://www.sohu.com www.sohu.com
http://www.163.com www.163.com
http://www.qq.com www.qq.com
[/quote]
[b]2、使用XPathAPI[/b]
DOMParser parser = new DOMParser();
parser.parse("html/test2.html");
Node node = parser.getDocument();
//獲取所有<td>內(nèi)容
//****注意在查找是必須使用大寫字母的tag名(NekoHTML默認(rèn)將HTML的tag名都轉(zhuǎn)成了大寫,屬性名變?yōu)樾?#xff09;
NodeList nodeList = XPathAPI.selectNodeList(node, "//TD");
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getTextContent());
}
//獲取所有<a>內(nèi)容
NodeList nodeList2 = XPathAPI.selectNodeList(node, "//A");
for (int i = 0; i < nodeList2.getLength(); i++) {
Element e = (Element) nodeList2.item(i);
System.out.print(e.getAttribute("href") + "\t");
System.out.println(e.getTextContent());
}
<html>
<head><title>test2</title></head>
<body>
<h1>Page Title</h1>
<!-- Table -->
<table>
<tr>
<td>a1</td> <td>a2</td> <td>a3</td>
</tr>
<tr>
<td>b1</td> <td>b2</td> <td>b3</td>
</tr>
<tr>
<td>c1</td> <td>c2</td> <td>c3</td>
</tr>
</table>
<!-- Link -->
<a href="http://www.aaa.com/">aaa</a>
<a href="http://www.bbb.com/">bbb</a>
<a href="http://www.ccc.com/">ccc</a>
</body>
</html>
[quote]
a1
a2
a3
b1
b2
b3
c1
c2
c3
http://www.aaa.com/ aaa
http://www.bbb.com/ bbb
http://www.ccc.com/ ccc
[/quote]
[b]3、設(shè)置Filter[/b]
//生成ElementRemover(默認(rèn)會(huì)不輸出所有的Tag名)
ElementRemover remover = new ElementRemover();
//設(shè)置輸出的Tag名及其屬性
remover.acceptElement("title", null);
remover.acceptElement("a", new String[]{"href"});
//刪除Tag
remover.removeElement("script");
//生成StringWriter
StringWriter filteredDescription = new StringWriter();
Writer writer = new Writer(filteredDescription, null);
//設(shè)置Filter
XMLDocumentFilter[] filters = { remover, writer };
DOMParser parser = new DOMParser();
parser.setProperty("http://cyberneko.org/html/properties/filters", filters);
parser.parse("html/test3.html");
//獲取結(jié)果
String description = filteredDescription.toString();
System.out.println(description);
<html>
<head>
<title>test3</title>
<script src="http://www.iteye.com/javascripts/application.js" type="text/javascript"></script>
</head>
<body>
<!-- Link -->
<a href="http://www.aaa.com/">aaa</a>
<a href="http://www.bbb.com/">bbb</a>
<a href="http://www.ccc.com/">ccc</a>
</body>
</html>
[quote]
<TITLE>test3</TITLE>
<!-- Link -->
<A href="http://www.aaa.com/">aaa</A>
<A href="http://www.bbb.com/">bbb</A>
<A href="http://www.ccc.com/">ccc</A>
[/quote]
[b]4、補(bǔ)充修正[/b]
//補(bǔ)充修正
StringWriter filteredDescription1 = new StringWriter();
Writer writer1 = new Writer(filteredDescription1, null);
XMLDocumentFilter[] filters1 = { writer1 };
DOMParser parser1 = new DOMParser();
parser1.setProperty("http://cyberneko.org/html/properties/filters", filters1);
parser1.parse("html/test4.html");
System.out.println(filteredDescription1.toString());
System.out.println();
//不補(bǔ)充修正
StringWriter filteredDescription2 = new StringWriter();
Writer writer2 = new Writer(filteredDescription2, null);
XMLDocumentFilter[] filters2 = { writer2 };
DOMParser parser2 = new DOMParser();
parser2.setProperty("http://cyberneko.org/html/properties/filters", filters2);
//默認(rèn)為true
parser2.setFeature("http://cyberneko.org/html/features/balance-tags",false);
parser2.parse("html/test4.html");
System.out.println(filteredDescription2.toString());
System.out.println();
//nekohtml功能(feature)列表
//屬性 默認(rèn)值 值域 描述
//http://cyberneko.org/html/features/balance-tags True 是否允許增補(bǔ)缺失的標(biāo)簽。如果要以XML方式操作HTML文件,此值必須為真。此處提供設(shè)置功能,為了性能的原因。
//http://cyberneko.org/html/features/balance-tags/ignore-outside-content False 是否忽略文檔根元素以后的數(shù)據(jù)。如果為false,<html>和<bod>被忽略,所有的內(nèi)容都被解析。
//http://cyberneko.org/html/features/document-fragment False 解析HTML片段時(shí)是否作標(biāo)簽增補(bǔ)。此功能不要用在DOMParser上,而要用在DOMFragmentParser上。
//http://apache.org/xml/features/scanner/notify-char-refs False 當(dāng)遇到字符實(shí)體引用(如&#x20;)是否將(#x20)報(bào)告給相應(yīng)地文檔處理器。
//http://apache.org/xml/features/scanner/notify-builtin-refs False 當(dāng)遇到XML內(nèi)建的字符實(shí)體引用(如&amp;)是否將(amp)報(bào)告給相應(yīng)地文檔處理器。
//http://cyberneko.org/html/features/scanner/notify-builtin-refs False 當(dāng)遇到HTML內(nèi)建的字符實(shí)體引用(如&copy;)是否將(copy)報(bào)告給相應(yīng)地文檔處理器。
//http://cyberneko.org/html/features/scanner/script/strip-comment-delims False 是否剝掉<script>元素中的<!-- -->等注釋符。
//http://cyberneko.org/html/features/augmentations False 是否將與HTML事件有關(guān)的infoset項(xiàng)包括在解析管道中。
//http://cyberneko.org/html/features/report-errors False 是否報(bào)告錯(cuò)誤。
//nekohtml屬性列表
//屬性 默認(rèn)值 值域 描述
//http://cyberneko.org/html/properties/filters null XMLDocumentFilter[] 在解析管道的最后按數(shù)組順序追加自定義的處理組件(過濾器),必須為數(shù)組類型。
//http://cyberneko.org/html/properties/default-encoding Windows-1252 IANA encoding names 默認(rèn)的HTML文件編碼
//http://cyberneko.org/html/properties/names/elems 默認(rèn)為upper upper,lower,match 如果整理識(shí)別出的元素名稱
//http://cyberneko.org/html/properties/names/attrs 默認(rèn)為lower upper,lower,no-change 如果整理識(shí)別出的屬性名稱
<a href="http://www.aaa.com/">aaa
<a href="http://www.bbb.com/">bbb
<a href="http://www.ccc.com/">ccc
[quote]
<HTML><HEAD></HEAD><BODY><A href="http://www.aaa.com/">aaa
</A><A href="http://www.bbb.com/">bbb
</A><A href="http://www.ccc.com/">ccc</A></BODY></HTML>
<A href="http://www.aaa.com/">aaa
<A href="http://www.bbb.com/">bbb
<A href="http://www.ccc.com/">ccc
[/quote]
[b]5、DOMFragmentParser[/b]
DOMFragmentParser parser = new DOMFragmentParser();
HTMLDocument document = new HTMLDocumentImpl();
DocumentFragment fragment = document.createDocumentFragment();
parser.parse("html/test5.html", fragment);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(new DOMSource(fragment), new StreamResult(new OutputStreamWriter(System.out, "utf-8")));
<html><head><title>test2</title></head><body><h1>Page Title</h1><!-- Table --><table><tr><td>a1</td><td>a2</td><td>a3</td></tr><tr><td>b1</td><td>b2</td><td>b3</td></tr><tr><td>c1</td><td>c2</td><td>c3</td></tr></table></body></html>
[quote]
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>test2</TITLE>
</HEAD>
<BODY>
<H1>Page Title</H1>
<!-- Table -->
<TABLE>
<TBODY>
<TR>
<TD>a1</TD><TD>a2</TD><TD>a3</TD>
</TR>
<TR>
<TD>b1</TD><TD>b2</TD><TD>b3</TD>
</TR>
<TR>
<TD>c1</TD><TD>c2</TD><TD>c3</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
[/quote]
總結(jié)
以上是生活随笔為你收集整理的Java解析HTML之NekoHTML的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(3005):vue+eleme
- 下一篇: [html] a标签的默认事件禁用后,