用WebCollector制作一個爬取《知乎》並進行問題精准抽取的爬蟲(JAVA)


簡單介紹:

WebCollector是一個無須配置、便於二次開發的JAVA爬蟲框架(內核),它提供精簡的的API。僅僅需少量代碼就可以實現一個功能強大的爬蟲。

怎樣將WebCollector導入項目請看以下這個教程:

JAVA網絡爬蟲WebCollector深度解析——爬蟲內核


參數:

WebCollector無需繁瑣配置。僅僅要在代碼中給出以下幾個必要參數,就可以啟動爬蟲:

1.種子(必要):

種子即爬蟲的起始頁面。一個爬蟲可加入一個或多個種子。

2.正則(可選):

正則是約束爬取范圍的一些正則式。

正則不一定要給出。假設用戶沒有給出正則,系統會自己主動將爬取范圍限定在種子的域名內。

3.線程數(可選):

WebCollector是一個多線程的爬蟲,默認使用10個線程同一時候工作。開發人員能夠自己定義線程數。


需求:

簡述一下教程里代碼的功能:定制一個爬蟲,對“知乎”站點進行爬取。不要求下載全部的網頁和文件,而是要求對知乎中全部的“提問”頁面中的”問題“進行提取。如圖:

我們須要提取問題標題:“看了《蝙蝠俠》,假設我闖進紐交所,逼迫全部人賣掉他手里的全部的股票期貨債券什么的,會有什么毀滅性后果?",

以及問題的內容:“咱不討論這可行性,我就想聽聽這有什么毀滅性那個的后果么?再比方百度。58,新東方什么的在那上市的中國公司?再比方會對其它的比方倫敦交易所什么的影響?中國股市的影響?再比方對其它貨幣的影響之類的?“


代碼:

代碼分為兩部分,爬取器和控制器。

爬取器通過Override父類中的visit方法(即對每一個正在爬取的頁面須要進行的操作),來定制自己的爬取任務。

控制器通過給爬取器設置參數(上面所說的種子、正則、線程數)。啟動爬取器來完畢控制功能。

1.爬取器:

WebCollector中集成了多種爬取器(主要是遍歷算法不同),最經常使用的遍歷器是BreadthCrawler,它是基於廣度遍歷的算法進行爬取的。我們新建一個JAVA類ZhihuCrawler,繼承BreadthCrawler,來定制我們的爬取器。


public class ZhihuCrawler extends BreadthCrawler{

    /*visit函數定制訪問每一個頁面時所需進行的操作*/
    @Override
    public void visit(Page page) {
        String question_regex="^http://www.zhihu.com/question/[0-9]+";
        if(Pattern.matches(question_regex, page.getUrl())){
            System.out.println("正在抽取"+page.getUrl());
            /*抽取標題*/
            String title=page.getDoc().title();
            System.out.println(title);
            /*抽取提問內容*/
            String question=page.getDoc().select("div[id=zh-question-detail]").text();
            System.out.println(question);

        }
    }


 代碼解析: 
        

《知乎》中有非常多種網頁:提問網頁、用戶個人信息網頁、專頁。我們如今僅僅要對提問網頁進行操作。

提問網頁的URL一般例如以下:http://www.zhihu.com/question/21962447

question_regex是全部提問網頁的正則表達式,代碼中:

if(Pattern.matches(question_regex, page.getUrl())){
          //操作代碼 
}

保證我們僅僅對“提問”頁面進行抽取。

visit函數的參數Page page,是一個已經爬取並解析成DOM樹的頁面。Page的參數:

page.getUrl() returns the url of the downloaded page

page.getContent() returns the origin data of the page

page.getDoc() returns an instance of org.jsoup.nodes.Document

page.getResponse() returns the http response of the page

page.getFetchTime() returns the time this page be fetched at generated by System.currentTimeMillis()


特別要注意的是page.getDoc()(DOM樹)。這里的page.getDoc()是JSOUP的Document,假設須要做HTML解析、抽取。使用page.getDoc()是不二的選擇。關於jsoup的用法,可參考JSOUP的教程:

http://www.brieftools.info/document/jsoup/



ZhihuCrawler中用到了page.getUrl()和page.getDoc()。

我們能夠發現,《知乎》提問頁面的網頁標題就是問題的標題,所以通過:

String title=page.getDoc().title();
就獲取了提問標題。

抽取《知乎》提問頁面的提問內容,須要從HTML源代碼觀察規則:

<div data-action="/question/detail" data-resourceid="965792" class="zm-item-rich-text" id="zh-question-detail">
    <div class="zm-editable-content">咱不討論這可行性,我就想聽聽這有什么毀滅性那個的后果么?<br>
      再比方百度,58,新東方什么的在那上市的中國公司?<br>
      再比方會對其它的比方倫敦交易所什么的影響?中國股市的影響?<br>再比方對其它貨幣的影響之類的?
    </div>
</div>


對於《知乎》全部的提問界面。我們發現,提問內容都被放在一個id="zh-question-detail"的div中。這是JSOUP最適合適用的一種情況。我們僅僅要找到這個div,將當中的文本(text)取出就可以:

String question=page.getDoc().select("div[id=zh-question-detail]").text();


2.控制器:

我們須要一個控制器來啟動爬取器:


public class Controller {
    
    public static void main(String[] args) throws IOException{   
        ZhihuCrawler crawler=new ZhihuCrawler();
        crawler.addSeed("http://www.zhihu.com/question/21003086");
        crawler.addRegex("http://www.zhihu.com/.*");
        crawler.start(5);   
    }
}


首先實例化剛定義的ZhihuCrawler(爬取器)。

給爬取器一個種子:http://www.zhihu.com/question/21003086

crawler.start(5)並非表示開啟5個線程爬取,5表示爬取的深度(廣度遍歷的層數)。

執行Controller這個類,會發現不斷有輸出產生。可是輸出比較雜亂。這是由於我們不僅輸出了我們抽取的提問。還輸出了爬蟲的日志(爬取記錄等):

fetch:http://www.zhihu.com/people/lxjts
fetch:http://www.zhihu.com/question/24597698
正在抽取http://www.zhihu.com/question/24597698
小米4採用304不銹鋼除了提升質感和B格。還有其它的實際優點么? - 知乎
信號會不會跟ip4一樣悲劇了……
fetch:http://www.zhihu.com/topic/20006139
fetch:http://www.zhihu.com/topic/19559450
fetch:http://www.zhihu.com/question/20014415#
fetch:http://www.zhihu.com/collection/31102864
fetch:http://www.zhihu.com/topic/19663238
fetch:http://www.zhihu.com/collection/20021567
上面的輸出片段中,我們能夠看到一次visit函數的運行,訪問了 http://www.zhihu.com/question/24597698 ,對問題的標題進行了抽取:“小米4採用304不銹鋼除了提升質感和B格。還有其它的實際優點么? - 知乎”。同一時候也抽取了問題的內容:“信號會不會跟ip4一樣悲劇了……“。
"fetch:http://www.zhihu.com/question/24597698"是日志的輸出,表示一個已經爬取的網頁。


假設您想看到干凈的爬取結果,有以下幾種解決方式:

1.在ZhihuCrawler的visit方法里,加入代碼。將title和question字符串輸出到文件里。

2.在ZhihuCrawler的visit方法里。加入代碼,將title和question字符串提交到數據庫(推薦)。


可能有人會疑問。為什么我們給爬蟲加入種子的時候不加入《知乎》的首頁,這是由於《知乎》首頁在不登錄的情況下會默認返回登錄頁面。






免責聲明!

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



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