關於這個HtmlParser的學習資料,網上真的很匱乏,這個好用的東西不要浪費啊,所以我在這里隆重的介紹一下。
HtmlParser是一個用來解析HTML文件的Java包,主要用於轉換盒抽取兩個方面。
利用HtmlParser,你可以實現下面的內容的抽取:
a.文本抽取 b.鏈接抽取 c.資源抽取。可以搜集到圖像和聲音文件等資源
d.鏈接檢查。保證鏈接是有用的 e.站點檢查,可以查看頁面不同版本之間的差異
利用HtmlParser,你可以利用它的轉換功能,主要體現在幾個方面:
a.URL重寫。能夠修正頁面中的錯誤鏈接 b.廣告清楚。清除頁面中的廣告內容和指向廣告的鏈接
c.將HTML頁面轉化成XML頁面 d.HTML頁面的清理
我們開始學習了,我們先來看看這個包中的類的大體框架:
在org.htmlparser包下,有幾個接口和類:
Parser類:這個是HtmlParser的核心類,主要的完成對Html頁面的分析工具,通過這個類我們可以得到這個頁面的各種信息。
Parser():無參數的構造方法。
Parser(String resource):根據String參數構建對象,這個參數可以是URL或者本地文件的路徑。
Parser(URLConnection connection):根據一個URLConnection對象構建對象。
createParser(String html, String charset):通過路徑名創建對象,並且設置編碼格式。
elements():返回這個類的元素節點的迭代器,通過這個迭代器我們遍歷頁面的節點。
setURL():設置這個Parser類要解析的頁面的地址。
parset():根據一個NodeFilter,也就是一個過濾器去獲取過濾剩下的頁面信息。
visitAllNodeWith(NodeVisitor visitor):通過一個NodeVisitor去遍歷所有的節點。
小試牛刀(這個只是簡單的使用,具體的類看下面的介紹):
@Test public void testVisitAllNodeWith() throws Exception { Parser parser = new Parser(); parser.setURL("http://www.google.cn"); parser.setEncoding(parser.getEncoding()); NodeVisitor visitor = new NodeVisitor() { public void visitTag(Tag tag) { System.out.println("*************************"); System.out.println(tag.getTagName()); System.out.println("*************************"); } }; parser.visitAllNodesWith(visitor); } @Test public void testElements() throws Exception { Parser parser = new Parser(); parser.setURL("http://www.google.cn"); parser.setEncoding(parser.getEncoding()); NodeIterator iterator = parser.elements(); while(iterator.hasMoreNodes()) { Node node = iterator.nextNode(); System.out.println("*************************"); System.out.println(node.getText()); System.out.println("*************************"); } }
Node接口:這個接口就好像定義了一顆樹來表示一個HTML頁面,定義獲取父子兄弟節點的方法,定義了節點到對應節點的html文本的方法,從上面的圖中我們看到有AbstractNode這個類,這個是Node的實現類,起到形成樹形結構的作用,在HTML頁面中有三種類型的Node,RemarkNode代表html中的注釋,TagNode代表標簽節點,TextNode代表文本節點。
getChildren():獲取子節點,返回一個NodeList對象。
getFirstChildren():獲取第一個子節點,返回一個Node對象。
getLastChildren():獲取最后一個子節點,返回一個Node對象。
getPreviousSibling():獲取前一個兄弟節點。
getNextSibling():獲取后一個兄弟節點。
getParent():獲取父節點。
getText():獲得文本內容。
toPlainTextString():獲取純文本信息。
toHtml():獲取Html信息。
accept(NodeVisitor visitor):對這個node應用visitor。
為了方法大家觀看,還是自己寫一個Html,然后練練方法:
node.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Title Node</title> </head> <body> <!-- remark --> <h1>H1 Node</h1> <div id="d1"> <div id="d2"> <a>Div Node</a> </div> </div> </body> </html>
測試方法:
@Test public void testNode() throws Exception { Parser parser = new Parser(); parser.setURL("src/node.html"); parser.setEncoding(parser.getEncoding()); NodeIterator iterator = parser.elements(); while(iterator.hasMoreNodes()) { Node node = iterator.nextNode(); System.out.println("*************************"); System.out.println("Text:" + node.getText()); System.out.println("PlainText:" + node.toPlainTextString()); System.out.println("ToHtml:" + node.toHtml()); System.out.println("*************************"); } }
Remark接口:這個接口代表了注釋。實現類有RemarkNode,這個類代表了注釋節點。
getText():獲取文本。
setText():設置文本。
Tag接口:這個接口就代表了Html頁面的標簽,實現類有TagNode,就是標簽節點。
getAttribute(String name):根據name拿到該標簽的屬性,當然有對應的setAttribute方法。
getTagName():拿到這個標簽的名字。
toTagHtml():返回這個標簽的html。
Text接口:這個接口代表Html的文本,實現類有TextNode,就是文本節點。
getText():拿到文本值。
setText():設置文本值。
NodeFilter接口:這個接口定義的是過濾器,通過各種各樣的過濾器可以篩選出特定的節點,具體的應用看下面的org.htmlparser.filters包下的類的應用,
accept(Node node):這個方法的返回值是boolean,方法的作用就是判斷要不要保留這個節點。
在org.htmlparser.visitors包下,有一個很重要的類NodeVisitor,下面講解一下:
NodeVisitor類:通過這個visitor我們可以遍歷樹的每一個節點,對於一個符合條件的節點,我們還可以進行適當的處理。
visitRemarkNode(Remark remark):訪問remark類型的節點,通過重寫這個方法可以實現對這個remark類型節點的特定操作。
visitStringNode(Text text):訪問Text類型的節點,通過重寫這個方法可以實現對這個Text類型節點的特定操作。
visitTag(Tag tag):訪問Tag類型的節點,通過重寫這個方法可以實現對這個Tag類型節點的特定操作。
小試牛刀:
public class MyVisitor extends NodeVisitor{ public MyVisitor() { } public void visitTag(Tag tag) { if(tag.getTagName().equals("BODY")) System.out.println("**********body**************"); System.out.println("TagName:" + tag.getTagName()); } public void visitStringNode(Text text) { System.out.println("text" + text.getText()); } public static void main(String[] args) throws Exception{ Parser parser = new Parser("src/node.html"); MyVisitor visitor = new MyVisitor(); parser.visitAllNodesWith(visitor); } }
在org.htmlparset.filters包下,有着很多過濾器,每個過濾器類都有自己特定的作用:
判斷類Filter:
TagNameFilter
HasAttributeFilter
HasChildFilter
HasParentFilter
HasSiblingFilter
IsEqualFilter
邏輯運算Filter:
AndFilter
NotFilter
OrFilter
XorFilter
其他Filter:
NodeClassFilter
StringFilter
LinkStringFilter
LinkRegexFilter
RegexFilter
CssSelectorNodeFilter
下面是一個關於TagNameFilter的小試牛刀:
@Test public void testTagNameFilter() throws Exception{ Parser parser = new Parser("src/node.html"); NodeFilter filter = new TagNameFilter("DIV"); NodeList nodeList = parser.extractAllNodesThatMatch(filter); if(nodeList != null) { for(int i = 0; i < nodeList.size(); i++) { Node node = nodeList.elementAt(i); System.out.println("Text:" + node.getText()); System.out.println("****************************"); } } }