HtmlParser的使用-爬蟲學習(三)


  關於這個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("****************************");
            }
        }
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM