分佈式爬蟲框架XXL-CRAWLER

《分佈式爬蟲框架XXL-CRAWLER》

Maven Central
GitHub release
License
donate

1、簡介

1.1 概述

XXL-CRAWLER 是一個分佈式爬蟲框架。一行代碼開發一個分佈式爬蟲,擁有"多線程、異步、IP動態代理、分佈式、JS渲染"等特性;css

1.2 特性

  • 一、簡潔:API直觀簡潔,可快速上手;
  • 二、輕量級:底層實現僅強依賴jsoup,簡潔高效;
  • 三、模塊化:模塊化的結構設計,可輕鬆擴展
  • 四、面向對象:支持經過註解,方便的映射頁面數據到PageVO對象,底層自動完成PageVO對象的數據抽取和封裝返回;單個頁面支持抽取一個或多個PageVO
  • 五、多線程:線程池方式運行,提升採集效率;
  • 六、分佈式支持:經過擴展 "RunData" 模塊,並結合Redis或DB共享運行數據可實現分佈式。默認提供LocalRunData單機版爬蟲。
  • 七、JS渲染:經過擴展 "PageLoader" 模塊,支持採集JS動態渲染數據。原生提供 Jsoup(非JS渲染,速度更快)、HtmlUnit(JS渲染)、Selenium+Phantomjs(JS渲染,兼容性高) 等多種實現,支持自由擴展其餘實現。
  • 八、失敗重試:請求失敗後重試,並支持設置重試次數;
  • 九、代理IP:對抗反採集策略規則WAF;
  • 十、動態代理:支持運行時動態調整代理池,以及自定義代理池路由策略;
  • 十一、異步:支持同步、異步兩種方式運行;
  • 十二、擴散全站:支持以現有URL爲起點擴散爬取整站;
  • 1三、去重:防止重複爬取;
  • 1四、URL白名單:支持設置頁面白名單正則,過濾URL;
  • 1五、自定義請求信息,如:請求參數、Cookie、Header、UserAgent輪詢、Referrer等;
  • 1六、動態參數:支持運行時動態調整請求參數;
  • 1七、超時控制:支持設置爬蟲請求的超時時間;
  • 1八、主動停頓:爬蟲線程處理完頁面以後進行主動停頓,避免過於頻繁被攔截;

1.3 下載

文檔地址

源碼倉庫地址

源碼倉庫地址 Release Download
https://github.com/xuxueli/xxl-crawler Download
https://gitee.com/xuxueli0323/xxl-crawler Download

技術交流

1.4 環境

  • JDK:1.7+

2、快速入門

爬蟲示例參考

(爬蟲示例代碼位於 /test 目錄下)html

  • 一、爬取頁面數據並封裝VO對象
  • 二、爬取頁面,下載Html文件
  • 三、爬取頁面,下載圖片文件
  • 四、爬取頁面,代理IP方式
  • 五、爬取公開的免費代理,生成動態代理池
  • 六、分佈式爬蟲示例
  • 七、JS渲染方式採集數據,"htmlUnit" 方案
  • 八、JS渲染方式採集數據,"selenisum + phantomjs" 方案
  • 九、採集非Web頁面,如JSON接口等,直接輸出響應數據

第一步:引入Maven依賴

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-crawler</artifactId>
    <version>${最新穩定版}</version>
</dependency>

第二步:定義 "PageVo/頁面數據對象"(可選)

在此推薦兩款工具,能夠直觀迅速的獲取頁面元素的Jquery cssQuery表達式。java

  • 一、Chrome DevTools:首先定位元素位置,而後從Element選中選中元素,點擊右鍵選擇「Copy + Copy selector」便可;
  • 二、Jquery Selector Helper(Chrome插件):首先定位元素位置,而後從Element右側打開Selector界面,而後定位元素便可;
// PageSelect 註解:從頁面中抽取出一個或多個VO對象;
@PageSelect(cssQuery = "body")
public static class PageVo {

    @PageFieldSelect(cssQuery = ".blog-heading .title")
    private String title;

    @PageFieldSelect(cssQuery = "#read")
    private int read;

    @PageFieldSelect(cssQuery = ".comment-content")
    private List<String> comment;

    // set get
}

第三步:建立爬蟲

XxlCrawler crawler = new XxlCrawler.Builder()
    .setUrls("https://my.oschina.net/xuxueli/blog")
    .setWhiteUrlRegexs("https://my\\.oschina\\.net/xuxueli/blog/\\d+")
    .setThreadCount(3)
    .setPageParser(new PageParser<PageVo>() {
        @Override
        public void parse(Document html, Element pageVoElement, PageVo pageVo) {
            // 解析封裝 PageVo 對象
            String pageUrl = html.baseUri();
            System.out.println(pageUrl + ":" + pageVo.toString());
        }
    })
    .build();

第四步:啓動爬蟲

crawler.start(true);

3、整體設計

架構圖

輸入圖片說明

3.1 功能定位

XXL-CRAWLER 是一個分佈式Web爬蟲框架。採用模塊化設計,各個模塊可靈活進行自定義和擴展。jquery

藉助 XXL-CRAWLER,一行代碼開發一個分佈式爬蟲。git

3.2 核心概念

概念 說明
XxlCrawler 爬蟲對象,維護爬蟲信息
PageVo 頁面數據對象,一張Web頁面可抽取一個或多個PageVo
PageLoader Wed頁面加載器,負責加載頁面數據,支持靈活的自定義和擴展
PageParser Wed頁面解析器,綁定泛型PageVO後將會自動抽取頁面數據對象,同時支持運行時調整請求參數信息;

NonPageParser : 非Web頁面解析器,如JSON接口等,直接輸出響應數據github

3.3 爬蟲對象:XxlCrawler

功能:爬蟲對象,維護爬蟲信息,可選屬性以下。chrome

方法 說明
setUrls 待爬的URL列表
setAllowSpread 容許擴散爬取,將會以現有URL爲起點擴散爬取整站
setWhiteUrlRegexs URL白名單正則,非空時進行URL白名單過濾頁面
setIfPost 請求方式:true=POST請求、false=GET請求
setUserAgent UserAgent
setParamMap 請求參數
setCookieMap 請求Cookie
setTimeoutMillis 超時時間,毫秒
setPauseMillis 停頓時間,爬蟲線程處理完頁面以後進行主動停頓,避免過於頻繁被攔截;
setProxyMaker 代理生成器,支持設置代理IP,同時支持調整代理池實現動態代理;
setThreadCount 爬蟲併發線程數
setPageParser 頁面解析器
setPageLoader 頁面加載器,默認提供 "JsoupPageParser" 和 "HtmlUnitPageLoader" 兩種實現;
setRunData 設置運行時數據模型,默認提供LocalRunData單機模型,支持擴展實現分佈式模型;
start 運行爬蟲,可經過入參控制同步或異步方式運行
stop 終止爬蟲

3.4 核心註解:PageSelect

功能:描述頁面數據對象,經過該註解從頁面抽取PageVo數據信息,可選屬性以下。多線程

PageSelect 說明
cssQuery CSS選擇器, 如 "#body"

3.5 核心註解:PageFieldSelect

功能:描述頁面數據對象的屬性信息,經過該註解從頁面抽取PageVo的屬性信息,可選屬性以下。
(支持基礎數據類型 T ,包括 List 架構

PageFieldSelect 說明
cssQuery CSS選擇器, 如 "#title"
selectType jquery 數據抽取方式,如 ".html()/.text()/.val()/.attr()"等
selectVal jquery 數據抽取參數,SelectType=ATTR 時有效,如 ".attr("abs:src")"
datePattern 時間格式化,日期類型數據有效

3.6 多線程

以線程池方式並行運行,提供對應API(可參考"章節3.3")調整線程池大小,提升運行效率;併發

3.7 異步

支持同步、異步兩種方式啓動運行。

  • 同步:將會阻塞業務邏輯,爬蟲爬取徹底部頁面後纔會繼續執行後續邏輯。
  • 異步:不會阻塞業務邏輯,爬蟲邏輯以異步方式運行。

3.8 動態代理

ProxyMaker(代理生成器):實現代理支持的組件。支持設置代理IP,同時支持調整代理池實現動態代理;

系統已經提供了兩種策略實現;

  • RoundProxyMaker(循環代理生成器): 以循環方式獲取代理池中代理;
  • RandomProxyMaker(隨機代理生成器): 以隨機方式獲取代理池中代理;

3.九、PageParser

PageParser(頁面解析器):綁定泛型PageVO後將會自動抽取頁面數據對象,同時支持運行時調整請求參數信息;

內部方法 說明
public void preParse(PageRequest pageRequest) 可選實現,發起頁面請求以前觸發調用,可基於此運行時調整請求參數;
public abstract void parse(Document html, Element pageVoElement, T pageVo) 必須實現,頁面抽離封裝每一個PageVO以後觸發調用,可基於此處理PageVO文檔或數據;

3.十、分佈式支持 & RunData

支持自定義RunData(運行時數據模型)並結合Redis或DB共享運行數據來實現分佈式爬蟲。默認提供LocalRunData實現單機版爬蟲。

  • RunData:運行時數據模型,維護爬蟲運行時的URL和白名單規則。
    • 單機:單機方式維護爬蟲運行數據,默認提供 "LocalRunData" 的單機版實現。
    • 分佈式/集羣:集羣方式維護爬蟲爬蟲運行數據,可經過Redis或DB定製實現。
RunData抽象方法 說明
public abstract boolean addUrl(String link); 新增一個待採集的URL,接口須要作URL去重,爬蟲線程將會獲取到並進行處理;
public abstract String getUrl(); 獲取一個待採集的URL,而且將它從"待採集URL池"中移除,而且添加到"已採集URL池"中;
public abstract int getUrlNum(); 獲取待採集URL數量;

3.十一、JS動態渲染 & PageLoader

頁面數據經過 "PageLoader" 組件加載,默認使用如下兩種實現:

  • JsoupPageLoader:速度最快,推薦採用這種方式(不支持JS動態渲染);
  • HtmlUnitPageLoader:支持JS動態渲染;
  • SeleniumPhantomjsPageLoader:支持JS動態渲染,"selenisum + phantomjs" 方案,兼容性較高;

得益於模塊化結構設計,可自由擴展其餘 "PageLoader" 實現,如 "selenisum + chrome/headless" 方式等;

注意:

  • 一、HtmlUnitPageLoader 爲擴展功能,所以maven依賴(htmlunit)scope爲provided類型,使用時請單獨引入;
  • 二、SeleniumPhantomjsPageLoader 爲擴展功能,所以maven依賴(selenisum + phantomjs)scope爲provided類型,使用時請單獨引入;
  • 三、JS渲染方式採集數據實用性廣,可是也存在缺點,以下:
    • 2.1:JS渲染,速度較慢;
    • 2.1:JS渲染,環境要求較高;
    • 2.3:在須要JS渲染的場景下,推薦作法是:分析頁面請求,模擬並主動發起Ajax請求來代替JS引擎自動請求渲染。由於速度更快,更可控;

4、版本更新日誌

版本 V1.0.0,新特性[2017-09-13]

  • 一、面向對象:經過VO對象描述頁面信息,提供註解方便的映射頁面數據,爬取結果主動封裝Java對象返回;
  • 二、多線程:線程池方式並行運行;
  • 三、異步:支持同步、異步兩種方式運行;
  • 四、擴散全站:支持以入口URL爲起點擴散爬取整站;
  • 五、去重:防止重複爬取;
  • 六、URL白名單:支持設置頁面白名單正則,過濾URL;
  • 七、自定義請求信息,如:請求參數、Cookie、Header、UserAgent輪詢、Referrer等;
  • 八、輕量級:底層實現僅依賴jsoup,簡潔高效;
  • 九、超時控制:支持設置爬蟲請求的超時時間;
  • 十、主動停頓:爬蟲線程處理完頁面以後進行主動停頓,避免過於頻繁被攔截;
  • 十一、單個頁面支持抽取一個或多個PageVO;

版本 V1.1.0,新特性[2017-11-08]

  • 一、頁面默認cssQuery調整爲html標籤;
  • 二、升級Jsoup至1.11.1版本;
  • 三、修復PageVO註解失效的問題;
  • 四、屬性註解參數attributeKey調整爲selectVal;
  • 五、代理IP:對抗反採集策略規則WAF;
  • 六、動態代理:支持運行時動態調整代理池,以及自定義代理池路由策略;

版本 V1.2.0,新特性[2017-12-14]

  • 一、爬蟲Builder底層API優化;
  • 二、支持設置請求Headers;
  • 三、支持設置多UserAgent輪詢;
  • 四、失敗重試:支持請求失敗後主動重試,並支持設置重試次數;
  • 五、動態參數:支持運行時動態調整請求參數;
  • 六、分佈式支持:支持自定義RunData(運行時數據模型)並結合Redis或DB共享運行數據來實現分佈式。默認提供LocalRunData單機版爬蟲。

版本 V1.2.1,新特性[2018-02-07]

  • 一、JS渲染:支持JS渲染方式採集數據,可參考 "爬蟲示例6";
  • 二、抽象並設計PageLoader,方便自定義和擴展頁面加載邏輯,如JS渲染等。底層提供 "JsoupPageLoader(默認/推薦)","HtmlUnitPageLoader"兩種實現,可自定義其餘類型PageLoader如 "Selenium" 等;
  • 三、修復Jsoup默認加載1M的限制;
  • 四、爬蟲線程中斷處理優化;

版本 V1.2.2,新特性[2018-10-24]

  • 一、系統底層重構,規範包名;
  • 二、採集線程白名單過濾優化,避免冗餘失敗重試;
  • 三、加強JS渲染方式採集能力,原生新提供 "SeleniumPhantomjsPageLoader",支持以 "selenisum + phantomjs" 方式採集頁面數據;
  • 四、支持採集非Web頁面,如JSON接口等,直接輸出響應數據;選擇 "NonPageParser" 便可;

版本 V1.3.0,新特性[迭代中]

  • 一、[ING]加強JS渲染採集能力,原生提供 "selenium chrome headless" 方案實現,並提供開箱即用的 PageLoader ;
  • 二、[ING]進一步優化 selenium 特性兼容問題;

TODO LIST

  • 一、擴展SelectType;
  • 二、協程,擱置,jsoup/htmlunit/selenisum協程兼容性低;
  • 三、bloomfilter去重,可選接入,大數據量下推薦;
  • 四、對抗爬蟲蜜罐,成功率檢測,歷史數據學習;
  • 五、對抗主動休眠防護,Timeout便可;
  • 六、頁面生僻字中文亂碼處理;

5、其餘

5.1 項目貢獻

歡迎參與項目貢獻!好比提交PR修復一個bug,或者新建 Issue 討論新特性或者變動。

5.2 用戶接入登記

更多接入的公司,歡迎在 登記地址 登記,登記僅僅爲了產品推廣。

5.3 開源協議和版權

產品開源免費,而且將持續提供免費的社區技術支持。我的或企業內部可自由的接入和使用。

  • Licensed under the GNU General Public License (GPL) v3.
  • Copyright (c) 2015-present, xuxueli.

捐贈

不管金額多少都足夠表達您這份心意,很是感謝 :) 前往捐贈

相關文章
相關標籤/搜索