常用的Java網(wǎng)絡(luò)爬蟲庫
Java 開發(fā)語言是業(yè)界使用最廣泛的開發(fā)語言之一,在互聯(lián)網(wǎng)從業(yè)者中具有廣泛的使用者,Java 網(wǎng)絡(luò)爬蟲可以幫助 Java 開發(fā)人員以快速、簡單但廣泛的方式為各種目的抓取數(shù)據(jù)。平常我們在討論網(wǎng)絡(luò)爬蟲的時候,很多人都會想到使用 Python 語言,因為與 Python 相關(guān)的網(wǎng)絡(luò)爬蟲資料很多,框架也有不少,上手會方便不少。但實際上,Java 網(wǎng)絡(luò)爬蟲家族里面也有很多優(yōu)秀的開源框架或者開源庫供大家使用。下圖是國外某個網(wǎng)站在某年度篩選出來的最受歡迎的 50 個網(wǎng)絡(luò)爬蟲開源框架或者開源庫,從這個排名中我們可以看出 Java 網(wǎng)絡(luò)爬蟲的應(yīng)用也是很廣泛的。
接下來給大家介紹幾個常用的Java開源網(wǎng)絡(luò)爬蟲庫:
1.Heritrix
Heritrix 是一個完全由 Java 開發(fā)的、開源網(wǎng)絡(luò)爬蟲工具,用戶可以使用它從網(wǎng)絡(luò)上面抓取想要的資源。它的主要組件包括 Web Administrative Console、Crawl Order、Crawl Controller、Frontier、Scope、ToeThreads 和 Processor 等。在國內(nèi),Heritrix 也有著十分廣泛的使用者,很多開發(fā)人員和研究人員都在使用 Heritrix 來采集數(shù)據(jù),為進一步的數(shù)據(jù)分析和數(shù)據(jù)挖掘工作做準備。Heritrix 的最出色之處在于開發(fā)者可以在現(xiàn)有框架的基礎(chǔ)上面對各個組件進行擴展,實現(xiàn)自己需要的抓取邏輯。其整體結(jié)構(gòu)如下圖所示:
一個完整的網(wǎng)頁采集任務(wù)是從 CrawlOrder 開始的。用戶可以通過多種不同方法創(chuàng)建 一個網(wǎng)頁采集任務(wù),例如復(fù)制已經(jīng)存在的任務(wù)、手動創(chuàng)建新的任務(wù)等,其中最方便的方法 是利用默認的配置文件 order.xml 來創(chuàng)建一個任務(wù)。這個文件中記錄了抓取任務(wù)的所有屬 性,每次配置一個新的任務(wù)都會產(chǎn)生一個新的 order.xml 文件,Heritrix 中的 CrawlOrder 組件就是用來存儲 order.xml 文件中的內(nèi)容。
Heritrix 采用了良好的模塊化設(shè)計,這些模塊由一個采集控制器類(CrawlerController)來協(xié)調(diào)調(diào)度,CrawlerController 在架構(gòu)中處于核心地位,其主要工作結(jié)構(gòu)如下圖所示:
接下來,給大家稍微介紹一下上圖中提到的各個工作組件。
CrawlController 在執(zhí)行抓取任務(wù)的過程中,作為一個主線程在工作,CrawlController 決定著如何開始抓取工作,并決定著何時開始、何時結(jié)束數(shù)據(jù)采集工作。
Frontier 組件的任務(wù)是為線程提供鏈接,它借助一些算法來判斷采集到的 URI 是否會 被處理,同時它也負責(zé)記錄日志和報告爬蟲的運行狀態(tài)。
Frontier 組件中有一個屬性叫做 scope,它決定了當前抓取范圍的組件。通過配置抓取范圍,可以決定爬蟲是在一個域名下抓取還是在多個域名下抓取。
Heritrix 支持多線程運行,因此 Heritrix 內(nèi)部維護了標準線程池 ToePool, 這個線程池用于管理爬蟲中的所有線程,每一個線程在處于運行狀態(tài)時只處理一個 URL。 采用多線程的技術(shù)可以提高爬蟲采集網(wǎng)頁的效率,以便更快速有效地抓取網(wǎng)頁內(nèi)容。負責(zé)處理的線程叫做 ToeThread,ToeThread 從 Frontier 中請求待處理的 URL 后,發(fā)送給處理器進行處理。
在 Heritrix 中,處理器被分組為處理器鏈。每個處理器鏈都會對 URL 進行一些處理。當一個處理器處理完一個 URL 后,ToeThread 會將 URL 發(fā)送給下一個處理器,直到 URL 被所有處理器處理完畢。處理器可以選擇告訴 URL 跳轉(zhuǎn)到某個特定的鏈。此外,如果處理器出現(xiàn)致命錯誤,處理將跳至后處理鏈。處理器鏈的工作流程如下圖所示:
下面對各個處理鏈進行一下簡單介紹:
(1)Pre-fetch processing chain(預(yù)處理鏈)
預(yù)處理鏈負責(zé)檢查 URL 是否符合抓取規(guī)則,是否在抓取范圍內(nèi)。在預(yù)處理鏈中,包含兩個主要的處理器,Preselector 和 PreconditionEnforcer。
PreSelector 用來檢查 URL 是否符合采集任務(wù)的需要,以便判斷是 否要繼續(xù)處理該 URL,它可以將一部分不滿足需求的 URL 過濾掉。這里主要是 通過正則表達式匹配 URL,如果一個 URL 滿足正則表達式,這個 URL 會進入 下一步的處理;否則就拋棄這個 URL。
PreconditionEnforcer 的作用是確保抓取一個 URL 的所有先 決條件都已經(jīng)滿足,例如驗證 DNS 是否成功解析、robots 信息是否已經(jīng)獲取等。
(2)Fetch processing chain(抓取處理鏈)
抓取處理鏈中的處理器中的處理器主要負責(zé)從服務(wù)器獲取數(shù)據(jù),Heritrix 支持的 每個網(wǎng)絡(luò)協(xié)議都有一個與之對應(yīng)的處理器,例如 HTTP 協(xié)議對應(yīng)的是 FetchHTTP 處理器。
(3)Extractor processing chain(提取器處理鏈)
在提取器處理鏈中,URL 所引用的文檔內(nèi)容處于可用的狀態(tài),多個處理器將依次嘗試從中獲取新鏈接。與抓取處理鏈一樣,每個網(wǎng)絡(luò)協(xié)議都有一個與之對應(yīng)的提取處理器,例如:ExtractorHTTP、ExtractorFTP 等。
(4)Write/index processing chain (存檔處理鏈)
該鏈負責(zé)將數(shù)據(jù)寫入歸檔文件。Heritrix 自帶的 ARCWriterProcessor 可將數(shù)據(jù)寫入 ARC 格式。還可以編寫新的處理器來支持其他格式,甚至創(chuàng)建索引。
(5)Post-processing chain(后處理鏈)
URL 應(yīng)始終通過該處理鏈,即使在該鏈中較早的處理器已決定不抓取該 URL。后處理鏈必須包含以下處理器:
- CrawlStateUpdater: 用于更新每一臺可能在采集過程中受到爬蟲影響的主機的信 息,這里的信息包括 robots 信息和 IP 地址。
- LinksScoper:主要用于驗證鏈接的范圍。驗證從網(wǎng)頁中抽取出來的 URL 是否在 規(guī)定的范圍內(nèi),并過濾掉不在該范圍內(nèi)的 URL。
- FrontierScheduler: 將提取到的鏈接放入到 Frontier 中,以便后續(xù)調(diào)度抓取。
優(yōu)缺點
優(yōu)點:開發(fā)者可以方便地在現(xiàn)有框架基礎(chǔ)上進行擴展
缺點:單實例的爬蟲,無法在分布式環(huán)境下進行工作;應(yīng)對反爬蟲的機制比較薄弱
實戰(zhàn)篇:
安裝及配置
下載地址: https://github.com/internetarchive/heritrix3
我這里使用的版本是 3.4.0,安裝方法簡單,只要參考官方文檔就可以了。
啟動及運行
啟動的時候,我們可以選擇通過命令行啟動:
$HERITRIX_HOME/bin/heritrix -a admin:123456
也可以選擇將工程源代碼導(dǎo)入到 IDE 后,在 IDE 中啟動。無論選擇哪種啟動方式,都需要注意添加參數(shù)-a 來設(shè)置用戶名和密碼。
engine listening at port 8443
operator login set per command-line
NOTE: We recommend a longer, stronger password, especially if your web?interface will be internet-accessible.
Heritrix version: 3.4.0-20220727
運行之后看到上面的日志信息就代表啟動成功了。
在瀏覽器中訪問: https://localhost:8443 ,可以進入到管理界面。
注意:一定要是 https 鏈接才可以,因為 Heritrix 在啟動 web 容器的時候只支持了 https 協(xié)議,而沒有支持 http 協(xié)議,因為本地沒有設(shè)置證書,所以會出現(xiàn)安全警告,忽略繼續(xù)訪問就可以的。
抓取任務(wù)創(chuàng)建與配置
啟動成功以后,我們就可以創(chuàng)建和配置抓取任務(wù)了。
在創(chuàng)建任務(wù)的過程中,最重要的就是通過 configuration 選項配置抓取任務(wù)。通過一個名為 crawler-beans.cxml 的配置文件控制整個抓取過程。crawler-beans.cxml 采用 Spring 來管理,里面的配置都是 spring bean。下面對 crawler-beans.cxml 文件中涉及到的 spring bean 進行簡單介紹。
bean id | class | 作用 |
---|---|---|
simpleOverrides和longerOverrides | org.springframework.beans.factory.config.PropertyOverrideConfigurer | 屬性資源配置器覆蓋應(yīng)用程序上下文定義中的 bean 屬性值。它將屬性文件中的值推送到 bean 定義中。 |
metadata | org.archive.modules.CrawlMetadata | 該bean的主要作用是記錄抓取job的基本屬性,名稱、抓取地址和robots協(xié)議規(guī)則的遵循。 |
seeds | org.archive.modules.seeds.TextSeedModule | 該bean的主要作用是設(shè)置種子地址的讀取位置 |
acceptSurts | org.archive.modules.deciderules.surt.SurtPrefixedDecideRule | surtprefixeddeciderule是Heritrix3中的一個決策規(guī)則(DecideRule),它的作用是允許或禁止基于URL前綴的抓取。 |
scope | org.archive.modules.deciderules.DecideRuleSequence | Deciderulesequence的作用是定義和控制抓取流程中的決策規(guī)則序列。 |
candidateScoper | org.archive.crawler.prefetch.CandidateScoper | Candidatescoper會根據(jù)一系列的規(guī)則或算法,對網(wǎng)頁進行判斷和打分。例如,它可以根據(jù)網(wǎng)頁的URL結(jié)構(gòu)、網(wǎng)頁內(nèi)容的關(guān)鍵詞匹配、鏈接的可用性等因素,來評估網(wǎng)頁的重要性和質(zhì)量。根據(jù)這些評估標準,Candidatescoper會給每個網(wǎng)頁打上一個分數(shù),分數(shù)高的網(wǎng)頁將被優(yōu)先保留。 |
preparer | org.archive.crawler.prefetch.FrontierPreparer | FrontierPreparer主要作用是設(shè)置URL的抓取深度,隊列,成本控制等。 |
candidateProcessors | org.archive.modules.CandidateChain | 主要作用是管理待爬取的URL,CandidateChain引用了candidateScoper來決定相關(guān)的URL是否會保留并生成CrawlURI,同時還引用了prepare bean來控制抓取的深度并進行成本控制等。 |
preselector | org.archive.crawler.prefetch.Preselector | 預(yù)先選擇器,這里會過濾掉一部分URL.如blockByRegex為拒絕正則,allowByRegex為允許正則 |
preconditions | org.archive.crawler.prefetch.PreconditionEnforcer | 先決條件設(shè)置,如設(shè)置IP有效期,爬蟲協(xié)議文件robots.txt有效期 |
fetchDns | org.archive.modules.fetcher.FetchDNS | FetchDNS主要用于處理域名解析功能 |
extractorHttp | org.archive.modules.extractor.ExtractorHTTP | URL提取器 |
extractorRobotsTxt | org.archive.modules.extractor.ExtractorRobotsTxt | 查看Robots協(xié)議 |
ExtractorSitemap | org.archive.modules.extractor.ExtractorSitemap | extractorsitemap是heritrix中的一個用來處理網(wǎng)站地圖(sitemap)的抽取器。 |
ExtractorHTML | org.archive.modules.extractor.ExtractorHTML | HTML內(nèi)容提取器 |
配置好各個選項之后,我們就可以開始真正執(zhí)行抓取任務(wù)了。因為篇幅的關(guān)系這里就不展開描述了,感興趣的讀者可以自行實踐。
2.Norconex?Web Crawler
官方地址: https://opensource.norconex.com/crawlers/web/
Norconex 也是一款非常優(yōu)秀的開源爬蟲工具,與之相關(guān)的中文資料比較少。但是,如果你正在尋找一個開源的企業(yè)級爬蟲工具,那你一定不能錯過它。作者認為 Norconex Web Crawler 有兩個功能最值得關(guān)注:
- 支持多種類型的 HTML 文檔下載器。當我們要采集網(wǎng)頁中的特定信息時,我們首先要能夠下載網(wǎng)頁的內(nèi)容,Norconex 提供了 GenericHttpFetcher 來滿足大部分場景下的需求,但是在某些情況下,可能需要更專業(yè)的方式來獲取網(wǎng)絡(luò)資源。例如:通過 Javascript 異步加載的網(wǎng)頁內(nèi)容,則通過 WebDriverHttpFetcher 來獲取網(wǎng)頁內(nèi)容更加合理。當然,你也可以開發(fā)自定義的 HTML 文檔下載器。
- 提供了 HTTP 請求頭和 HTTP 響應(yīng)頭監(jiān)聽器和修改器。Norconex 基于 BrowserMobProxy 實現(xiàn)了 HTTP 請求頭和 HTTP 響應(yīng)頭監(jiān)聽器和修改器(HttpSniffer)。HttpSniffer 使得對 HttpFetcher 請求和響應(yīng)內(nèi)容的監(jiān)控更加方便,也可以使 HTTP 的請求更加規(guī)范化,而且可以多一種方式獲取到 web 服務(wù)響應(yīng)的內(nèi)容。
接下來,我們重點介紹一下 BrowserMobProxy(簡稱 BMP),它是一款由 Java 編寫開源的網(wǎng)絡(luò)訪問代理工具,在后面我們自己編寫的 Java 網(wǎng)絡(luò)爬蟲中也會用到該工具。通過 BMP,我們可以修改、設(shè)置和捕獲到網(wǎng)絡(luò)的請求和響應(yīng),BMP 甚至可以將網(wǎng)絡(luò)請求的所有細節(jié)記錄到 HAR 文件中。Har 是一種用于導(dǎo)出 HTTP 跟蹤信息的開放格式,稱為 HTTP 存檔 (HAR)。數(shù)據(jù)存儲格式為 JSON 文檔。具體信息可以參見( RFC 4627 )。BMP 有兩種工作模式,嵌入式模式和獨立啟動模式。嵌入式模式是通過 Java 代碼調(diào)用使用。嵌入式模式是利用 Java 代碼來啟動代理,并通過 Java 代碼來捕獲修改請求信息和響應(yīng)信息。另一種是獨立啟動模式,可以通過命令行來啟動,通過 RestAPI 來進行操作。
3. Crawler4j
Crawler4j是用Java編寫的開源項目,它支持多線程方式采集網(wǎng)站信息,并利用正則表達式限制采集對象。Crawler4j具有完整的爬蟲功能框架,小巧靈活并可以獨立運行。因此,易于集成到項目中,或者將第三方業(yè)務(wù)邏輯嵌入工作流中自定義爬行。其主要工作流程如下所示:
Crawler4j最主要的缺點是不支持動態(tài)網(wǎng)頁的抓取,但是我們可以基于Crawler4j進行二次開發(fā)對WebCrawlerFactory進行擴展使其支持動態(tài)網(wǎng)頁內(nèi)容的抓取。
總結(jié)
本章中,我們介紹了幾個目前仍然比較活躍的爬蟲開源框架,Heritrix,Norconex和Crawler4j。在后面的章節(jié)里面,我們會參考這些開源的框架和軟件,開發(fā)一套屬于我們自己的Java爬蟲軟件。