《面向?qū)ο蟮姆植际脚老x框架XXL-CRAWLER》
一、簡介
1.1 概述
XXL-CRAWLER 是一個(gè)面向?qū)ο蟮姆植际脚老x框架。一行代碼開發(fā)一個(gè)分布式爬蟲,擁有"多線程、異步、IP動(dòng)態(tài)代理、分布式、JS渲染"等特性;
1.2 特性
- 1、簡潔:API直觀簡潔,可快速上手;
- 2、輕量級:底層實(shí)現(xiàn)僅強(qiáng)依賴jsoup,簡潔高效;
- 3、模塊化:模塊化的結(jié)構(gòu)設(shè)計(jì),可輕松擴(kuò)展
- 4、面向?qū)ο螅褐С滞ㄟ^注解,方便的映射頁面數(shù)據(jù)到PageVO對象,底層自動(dòng)完成PageVO對象的數(shù)據(jù)抽取和封裝返回;單個(gè)頁面支持抽取一個(gè)或多個(gè)PageVO
- 5、多線程:線程池方式運(yùn)行,提高采集效率;
- 6、分布式支持:通過擴(kuò)展 "RunData" 模塊,并結(jié)合Redis或DB共享運(yùn)行數(shù)據(jù)可實(shí)現(xiàn)分布式。默認(rèn)提供LocalRunData單機(jī)版爬蟲。
- 7、JS渲染:通過擴(kuò)展 "PageLoader" 模塊,支持采集JS動(dòng)態(tài)渲染數(shù)據(jù)。原生提供Jsoup(快速、推薦)和HtmlUnit(較慢、JS渲染)兩種實(shí)現(xiàn),支持自由擴(kuò)展其他實(shí)現(xiàn)。
- 8、失敗重試:請求失敗后重試,并支持設(shè)置重試次數(shù);
- 9、代理IP:對抗反采集策略規(guī)則WAF;
- 10、動(dòng)態(tài)代理:支持運(yùn)行時(shí)動(dòng)態(tài)調(diào)整代理池,以及自定義代理池路由策略;
- 11、異步:支持同步、異步兩種方式運(yùn)行;
- 12、擴(kuò)散全站:支持以現(xiàn)有URL為起點(diǎn)擴(kuò)散爬取整站;
- 13、去重:防止重復(fù)爬??;
- 14、URL白名單:支持設(shè)置頁面白名單正則,過濾URL;
- 15、自定義請求信息,如:請求參數(shù)、Cookie、Header、UserAgent輪詢、Referrer等;
- 16、動(dòng)態(tài)參數(shù):支持運(yùn)行時(shí)動(dòng)態(tài)調(diào)整請求參數(shù);
- 17、超時(shí)控制:支持設(shè)置爬蟲請求的超時(shí)時(shí)間;
- 18、主動(dòng)停頓:爬蟲線程處理完頁面之后進(jìn)行主動(dòng)停頓,避免過于頻繁被攔截;
1.4 下載
文檔地址
源碼倉庫地址
| 源碼倉庫地址 | Release Download |
|---|---|
| https://github.com/xuxueli/xxl-crawler | Download |
| https://gitee.com/xuxueli0323/xxl-crawler | Download |
技術(shù)交流
1.5 環(huán)境
- JDK:1.7+
二、快速入門
爬蟲示例參考
(爬蟲示例代碼位于 /test 目錄下)
- 1、爬取頁面數(shù)據(jù)并封裝VO對象
- 2、爬取頁面,下載Html文件
- 3、爬取頁面,下載圖片文件
- 4、爬取頁面,代理IP方式
- 5、爬取公開的免費(fèi)代理,生成動(dòng)態(tài)代理池
- 6、JS渲染方式采集數(shù)據(jù)
第一步:引入Maven依賴
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-crawler</artifactId>
<version>${最新穩(wěn)定版}</version>
</dependency>
第二步:定義 "PageVo/頁面數(shù)據(jù)對象"(可選)
在此推薦兩款工具,可以直觀迅速的獲取頁面元素的Jquery cssQuery表達(dá)式。
- 1、Chrome DevTools:首先定位元素位置,然后從Element選中選中元素,點(diǎn)擊右鍵選擇“Copy + Copy selector”即可;
- 2、Jquery Selector Helper(Chrome插件):首先定位元素位置,然后從Element右側(cè)打開Selector界面,然后定位元素即可;
// PageSelect 注解:從頁面中抽取出一個(gè)或多個(gè)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
}
第三步:創(chuàng)建爬蟲
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();
第四步:啟動(dòng)爬蟲
crawler.start(true);
三、總體設(shè)計(jì)
架構(gòu)圖

3.1 功能定位
XXL-CRAWLER 是一個(gè)靈活高效、面向?qū)ο蟮腤eb爬蟲框架。采用模塊化設(shè)計(jì),各個(gè)模塊可靈活進(jìn)行自定義和擴(kuò)展。
借助 XXL-CRAWLER,一行代碼開發(fā)一個(gè)分布式爬蟲。
3.2 核心概念
| 概念 | 說明 |
|---|---|
| XxlCrawler | 爬蟲對象,維護(hù)爬蟲信息 |
| PageVo | 頁面數(shù)據(jù)對象,一張Web頁面可抽取一個(gè)或多個(gè)PageVo |
| PageLoader | 頁面加載器,負(fù)責(zé)加載頁面數(shù)據(jù),支持靈活的自定義和擴(kuò)展 |
| PageParser | 頁面解析器,綁定泛型PageVO后將會自動(dòng)抽取頁面數(shù)據(jù)對象,同時(shí)支持運(yùn)行時(shí)調(diào)整請求參數(shù)信息 |
3.3 爬蟲對象:XxlCrawler
功能:爬蟲對象,維護(hù)爬蟲信息,可選屬性如下。
| 方法 | 說明 |
|---|---|
| setUrls | 待爬的URL列表 |
| setAllowSpread | 允許擴(kuò)散爬取,將會以現(xiàn)有URL為起點(diǎn)擴(kuò)散爬取整站 |
| setWhiteUrlRegexs | URL白名單正則,非空時(shí)進(jìn)行URL白名單過濾頁面 |
| setIfPost | 請求方式:true=POST請求、false=GET請求 |
| setUserAgent | UserAgent |
| setParamMap | 請求參數(shù) |
| setCookieMap | 請求Cookie |
| setTimeoutMillis | 超時(shí)時(shí)間,毫秒 |
| setPauseMillis | 停頓時(shí)間,爬蟲線程處理完頁面之后進(jìn)行主動(dòng)停頓,避免過于頻繁被攔截; |
| setProxyMaker | 代理生成器,支持設(shè)置代理IP,同時(shí)支持調(diào)整代理池實(shí)現(xiàn)動(dòng)態(tài)代理; |
| setThreadCount | 爬蟲并發(fā)線程數(shù) |
| setPageParser | 頁面解析器 |
| setPageLoader | 頁面加載器,默認(rèn)提供 "JsoupPageParser" 和 "HtmlUnitPageLoader" 兩種實(shí)現(xiàn); |
| setRunData | 設(shè)置運(yùn)行時(shí)數(shù)據(jù)模型,默認(rèn)提供LocalRunData單機(jī)模型,支持?jǐn)U展實(shí)現(xiàn)分布式模型; |
| start | 運(yùn)行爬蟲,可通過入?yún)⒖刂仆交虍惒椒绞竭\(yùn)行 |
| stop | 終止爬蟲 |
3.4 核心注解:PageSelect
功能:描述頁面數(shù)據(jù)對象,通過該注解從頁面抽取PageVo數(shù)據(jù)信息,可選屬性如下。
| PageSelect | 說明 |
|---|---|
| cssQuery | CSS選擇器, 如 "#body" |
3.5 核心注解:PageFieldSelect
功能:描述頁面數(shù)據(jù)對象的屬性信息,通過該注解從頁面抽取PageVo的屬性信息,可選屬性如下。
(支持基礎(chǔ)數(shù)據(jù)類型 T ,包括 List<T>)
| PageFieldSelect | 說明 |
|---|---|
| cssQuery | CSS選擇器, 如 "#title" |
| selectType | jquery 數(shù)據(jù)抽取方式,如 ".html()/.text()/.val()/.attr()"等 |
| selectVal | jquery 數(shù)據(jù)抽取參數(shù),SelectType=ATTR 時(shí)有效,如 ".attr("abs:src")" |
| datePattern | 時(shí)間格式化,日期類型數(shù)據(jù)有效 |
3.6 多線程
以線程池方式并行運(yùn)行,提供對應(yīng)API(可參考"章節(jié)3.3")調(diào)整線程池大小,提高運(yùn)行效率;
3.7 異步
支持同步、異步兩種方式啟動(dòng)運(yùn)行。
- 同步:將會阻塞業(yè)務(wù)邏輯,爬蟲爬取完全部頁面后才會繼續(xù)執(zhí)行后續(xù)邏輯。
- 異步:不會阻塞業(yè)務(wù)邏輯,爬蟲邏輯以異步方式運(yùn)行。
3.8 動(dòng)態(tài)代理
ProxyMaker(代理生成器):實(shí)現(xiàn)代理支持的組件。支持設(shè)置代理IP,同時(shí)支持調(diào)整代理池實(shí)現(xiàn)動(dòng)態(tài)代理;
系統(tǒng)已經(jīng)提供了兩種策略實(shí)現(xiàn);
- RoundProxyMaker(循環(huán)代理生成器): 以循環(huán)方式獲取代理池中代理;
- RandomProxyMaker(隨機(jī)代理生成器): 以隨機(jī)方式獲取代理池中代理;
3.9、PageParser
PageParser(頁面解析器):綁定泛型PageVO后將會自動(dòng)抽取頁面數(shù)據(jù)對象,同時(shí)支持運(yùn)行時(shí)調(diào)整請求參數(shù)信息;
| 內(nèi)部方法 | 說明 |
|---|---|
| public void preLoad(PageLoadInfo pageLoadInfo) | 可選實(shí)現(xiàn),發(fā)起頁面請求之前觸發(fā)調(diào)用,可基于此運(yùn)行時(shí)調(diào)整請求參數(shù); |
| public void postLoad(Document html) | 可選實(shí)現(xiàn),發(fā)起頁面請求之后觸發(fā)調(diào)用,可基于此運(yùn)行時(shí)調(diào)整頁面數(shù)據(jù); |
| public abstract void parse(Document html, Element pageVoElement, T pageVo) | 必須實(shí)現(xiàn),頁面抽離封裝每個(gè)PageVO之后觸發(fā)調(diào)用,可基于此處理PageVO文檔或數(shù)據(jù); |
3.10、分布式支持 & RunData
支持自定義RunData(運(yùn)行時(shí)數(shù)據(jù)模型)并結(jié)合Redis或DB共享運(yùn)行數(shù)據(jù)來實(shí)現(xiàn)分布式爬蟲。默認(rèn)提供LocalRunData實(shí)現(xiàn)單機(jī)版爬蟲。
- RunData:運(yùn)行時(shí)數(shù)據(jù)模型,維護(hù)爬蟲運(yùn)行時(shí)的URL和白名單規(guī)則。
- 單機(jī):單機(jī)方式維護(hù)爬蟲運(yùn)行數(shù)據(jù),默認(rèn)提供 "LocalRunData" 的單機(jī)版實(shí)現(xiàn)。
- 分布式/集群:集群方式維護(hù)爬蟲爬蟲運(yùn)行數(shù)據(jù),可通過Redis或DB定制實(shí)現(xiàn)。
| RunData抽象方法 | 說明 |
|---|---|
| public abstract boolean addUrl(String link); | 新增一個(gè)待采集的URL,接口需要做URL去重,爬蟲線程將會獲取到并進(jìn)行處理; |
| public abstract String getUrl(); | 獲取一個(gè)待采集的URL,并且將它從"待采集URL池"中移除,并且添加到"已采集URL池"中; |
| public abstract int getUrlNum(); | 獲取待采集URL數(shù)量; |
3.11、JS動(dòng)態(tài)渲染 & PageLoader
頁面數(shù)據(jù)通過 "PageLoader" 組件加載,默認(rèn)使用以下兩種實(shí)現(xiàn):
- JsoupPageLoader:速度最快,推薦采用這種方式(不支持JS動(dòng)態(tài)渲染);
- HtmlUnitPageLoader:支持JS動(dòng)態(tài)渲染,速度較慢。
得益于模塊化結(jié)構(gòu)設(shè)計(jì),可自由擴(kuò)展其他 "PageLoader" 實(shí)現(xiàn),如 "Selenium" 方式等;
注意:
- 1、HtmlUnitPageLoader 為擴(kuò)展功能,因此maven依賴(htmlunit)scope為provided類型,使用時(shí)請單獨(dú)引入;
- 2、不推薦使用JS渲染方式采集數(shù)據(jù):
- 2.1:JS渲染,速度較慢;
- 2.1:JS渲染,環(huán)境要求較高;
- 2.3:在需要JS渲染的場景下,推薦做法是:分析頁面請求,模擬并主動(dòng)發(fā)起Ajax請求來代替JS引擎自動(dòng)請求渲染。因?yàn)樗俣雀?,更可控?/li>
四、版本更新日志
版本 V1.0.0,新特性[2017-09-13]
- 1、面向?qū)ο螅和ㄟ^VO對象描述頁面信息,提供注解方便的映射頁面數(shù)據(jù),爬取結(jié)果主動(dòng)封裝Java對象返回;
- 2、多線程:線程池方式并行運(yùn)行;
- 3、異步:支持同步、異步兩種方式運(yùn)行;
- 4、擴(kuò)散全站:支持以入口URL為起點(diǎn)擴(kuò)散爬取整站;
- 5、去重:防止重復(fù)爬??;
- 6、URL白名單:支持設(shè)置頁面白名單正則,過濾URL;
- 7、自定義請求信息,如:請求參數(shù)、Cookie、Header、UserAgent輪詢、Referrer等;
- 8、輕量級:底層實(shí)現(xiàn)僅依賴jsoup,簡潔高效;
- 9、超時(shí)控制:支持設(shè)置爬蟲請求的超時(shí)時(shí)間;
- 10、主動(dòng)停頓:爬蟲線程處理完頁面之后進(jìn)行主動(dòng)停頓,避免過于頻繁被攔截;
- 11、單個(gè)頁面支持抽取一個(gè)或多個(gè)PageVO;
版本 V1.1.0,新特性[2017-11-08]
- 1、頁面默認(rèn)cssQuery調(diào)整為html標(biāo)簽;
- 2、升級Jsoup至1.11.1版本;
- 3、修復(fù)PageVO注解失效的問題;
- 4、屬性注解參數(shù)attributeKey調(diào)整為selectVal;
- 5、代理IP:對抗反采集策略規(guī)則WAF;
- 6、動(dòng)態(tài)代理:支持運(yùn)行時(shí)動(dòng)態(tài)調(diào)整代理池,以及自定義代理池路由策略;
版本 V1.2.0,新特性[2017-12-14]
- 1、爬蟲Builder底層API優(yōu)化;
- 2、支持設(shè)置請求Headers;
- 3、支持設(shè)置多UserAgent輪詢;
- 4、失敗重試:支持請求失敗后主動(dòng)重試,并支持設(shè)置重試次數(shù);
- 5、動(dòng)態(tài)參數(shù):支持運(yùn)行時(shí)動(dòng)態(tài)調(diào)整請求參數(shù);
- 6、分布式支持:支持自定義RunData(運(yùn)行時(shí)數(shù)據(jù)模型)并結(jié)合Redis或DB共享運(yùn)行數(shù)據(jù)來實(shí)現(xiàn)分布式。默認(rèn)提供LocalRunData單機(jī)版爬蟲。
版本 V1.2.1,新特性[2018-02-07]
- 1、JS渲染:支持JS渲染方式采集數(shù)據(jù),可參考 "爬蟲示例6";
- 2、抽象并設(shè)計(jì)PageLoader,方便自定義和擴(kuò)展頁面加載邏輯,如JS渲染等。底層提供 "JsoupPageLoader(默認(rèn)/推薦)","HtmlUnitPageLoader"兩種實(shí)現(xiàn),可自定義其他類型PageLoader如 "Selenium" 等;
- 3、修復(fù)Jsoup默認(rèn)加載1M的限制;
- 4、爬蟲線程中斷處理優(yōu)化;
版本 V1.2.2,新特性[迭代中]
TODO LIST
- 1、擴(kuò)展SelectType;
- 3、bloomfilter去重,可選接入,大數(shù)據(jù)量下推薦;
- 4、對抗爬蟲蜜罐,成功率檢測,歷史數(shù)據(jù)學(xué)習(xí);
- 5、對抗主動(dòng)休眠防御,Timeout即可;
五、其他
5.1 項(xiàng)目貢獻(xiàn)
歡迎參與項(xiàng)目貢獻(xiàn)!比如提交PR修復(fù)一個(gè)bug,或者新建 Issue 討論新特性或者變更。
5.2 用戶接入登記
更多接入的公司,歡迎在 登記地址 登記,登記僅僅為了產(chǎn)品推廣。
5.3 開源協(xié)議和版權(quán)
產(chǎn)品開源免費(fèi),并且將持續(xù)提供免費(fèi)的社區(qū)技術(shù)支持。個(gè)人或企業(yè)內(nèi)部可自由的接入和使用。
- Licensed under the GNU General Public License (GPL) v3.
- Copyright (c) 2015-present, xuxueli.
捐贈(zèng)
無論金額多少都足夠表達(dá)您這份心意,非常感謝 :) 前往捐贈(zèng)