摘要:優(yōu)雅的使用框架,爬取唐詩(shī)別苑網(wǎng)的詩(shī)人詩(shī)歌數(shù)據(jù)同時(shí)在幾種動(dòng)態(tài)加載技術(shù)中對(duì)比作選擇雖然差不多兩年沒有維護(hù),但其本身是一個(gè)優(yōu)秀的爬蟲框架的實(shí)現(xiàn),源碼中有很多值得參考的地方,特別是對(duì)爬蟲多線程的控制。
優(yōu)雅的使用WebMagic框架,爬取唐詩(shī)別苑網(wǎng)的詩(shī)人詩(shī)歌數(shù)據(jù)
同時(shí)在幾種動(dòng)態(tài)加載技術(shù)(HtmlUnit、PhantomJS、Selenium、JavaScriptEngine)中對(duì)比作選擇
WebMagic雖然差不多兩年沒有維護(hù),但其本身是一個(gè)優(yōu)秀的爬蟲框架的實(shí)現(xiàn),源碼中有很多值得參考的地方,特別是對(duì)爬蟲多線程的控制。另外,由于頁(yè)面爬取到的是非結(jié)構(gòu)化數(shù)據(jù),所以數(shù)據(jù)保存到MongoDB。技術(shù)準(zhǔn)備
IDE:IntelliJ IDEA 2018.3.5
JDK版本:1.8.0_181
數(shù)據(jù)庫(kù):MongoDB 4.0.10
涉及技術(shù):
Webmagic輕量級(jí)爬蟲框架
HtmlUnit網(wǎng)頁(yè)分析工具包,模擬瀏覽器運(yùn)行
PhantomJS
JavaScriptEngine
MongoDB ORM框架 Morphia
JUC:Java線程池、線程協(xié)作、線程安全類
日志log4j 1.7.25
Java反射
單例模式、工廠模式、代理模式
pom.xml文件中的依賴非常簡(jiǎn)單,并沒有使用到Spring系列的框架,所以有些地方自己編碼實(shí)現(xiàn)了Spring提供的功能項(xiàng)目結(jié)構(gòu)
biz包:包括頁(yè)面爬取邏輯的Processor類,爬蟲結(jié)果保存的Pipeline類
dao包:數(shù)據(jù)獲取層
entity包:實(shí)體類,映射保存在MongoDB的文檔(Document)
vo包:值對(duì)象,簡(jiǎn)單的Java對(duì)象
util包:工具包,包括數(shù)據(jù)庫(kù)連接類、爬蟲輔助類
common包:項(xiàng)目相關(guān)通用類
Main類:程序入口
項(xiàng)目說(shuō)明根據(jù)需求將數(shù)據(jù)保存到MongoDB數(shù)據(jù)庫(kù),因此在程序運(yùn)行前必須設(shè)置好resources/mongodb.properties文件
最好保證MongoDB的版本是4.0以上。另外MongoDB的用戶管理比較麻煩,過(guò)程大致如下:首先需要?jiǎng)?chuàng)建存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)庫(kù),如命名為user_tangpoem,并存入隨便一條數(shù)據(jù)(集合)使數(shù)據(jù)庫(kù)有效化,然后創(chuàng)建一個(gè)
admin數(shù)據(jù)庫(kù)的root用戶,繼續(xù)創(chuàng)建一個(gè)可以讀寫應(yīng)用數(shù)據(jù)庫(kù)user_tangpoem的用戶,然后修改MongoDB配置文件使其以安全認(rèn)證模式啟動(dòng)。重啟數(shù)據(jù)庫(kù),選擇admin數(shù)據(jù)庫(kù)(use admin)
用剛剛創(chuàng)建的用戶(非root用戶)使用db.auth()進(jìn)行登錄,返回1說(shuō)明驗(yàn)證成功,選擇user_tangpoem數(shù)據(jù)庫(kù)(use user_tangpoem),輸入show collections,如果看到最初創(chuàng)建數(shù)據(jù)庫(kù)時(shí)的集合,則說(shuō)明用戶創(chuàng)建成功。
詳細(xì)可參考 MongoDB4.0.0 遠(yuǎn)程連接及用戶名密碼認(rèn)證登陸配置——windows
爬蟲以多線程的方式運(yùn)行,在resources/spider.properties文件中可以設(shè)置線程數(shù)和線程睡眠時(shí)間,在設(shè)置好數(shù)據(jù)庫(kù)配置的基礎(chǔ)上,直接運(yùn)行Main.main(),爬蟲就會(huì)開始爬取。
線程睡眠,是WebMagic框架源碼中每線程爬取完一個(gè)url后必然經(jīng)歷的過(guò)程,但作者文檔并沒有對(duì)此進(jìn)行說(shuō)明,請(qǐng)根據(jù)實(shí)際情況調(diào)整動(dòng)態(tài)加載技術(shù)的選擇 1. PhantomJS和Selenium
WebMagic底層已經(jīng)很好的使用了HttpClient加載靜態(tài)頁(yè)面,對(duì)于動(dòng)態(tài)頁(yè)面,也有PhantomJSDownloader和SeleniumDownloader兩個(gè)常用的利用
瀏覽器內(nèi)核模擬瀏覽器行為的實(shí)現(xiàn),其中,PhantomJS需要指定phantomjs.exe和進(jìn)行爬取的JS文件,而seleniumDownloader需要指定chromedriver.exe,需要自行下載對(duì)應(yīng)操作系統(tǒng)的版本,
使用起來(lái)并不難,本項(xiàng)目不多作討論。這里關(guān)鍵說(shuō)明HtmlUnit
一款開源的Java頁(yè)面分析工具,讀取頁(yè)面后,可以有效的使用HtmlUnit分析頁(yè)面上的內(nèi)容。使用純Java實(shí)現(xiàn)的模擬瀏覽器,不需要指定外部文件。
雖然其對(duì)JS的支持并不完全,但總體而言HtmlUnit的內(nèi)存消耗、CPU消耗和效率都比PhantomJS和Selenium好,值得進(jìn)行使用
本項(xiàng)目使用2.25版本的HtmlUnit并沒有出現(xiàn)JS加在不成功的問(wèn)題,但使用2.3x的版本會(huì)無(wú)法加載3. JavaScriptEngine
既然要加載JS,為何不直接提取JS代碼,使用Java自帶的JS引擎處理呢?
因?yàn)?strong>JavaScriptEngine是有局限性的,最明顯就是其不支持jquery的語(yǔ)法,因?yàn)閖query使用了瀏覽器內(nèi)置的對(duì)象,而JS引擎本身是沒有瀏覽器對(duì)象的
那還能使用JS引擎嗎?
當(dāng)然可以,只要分析過(guò)頁(yè)面的加載邏輯,如果不涉及瀏覽器對(duì)象的使用,或者將JS邏輯進(jìn)行轉(zhuǎn)化,還是能夠使用JS引擎的,但犧牲了泛用性。本項(xiàng)目經(jīng)分析后使用JS引擎加載
4. 橫向?qū)Ρ?/b>經(jīng)過(guò)測(cè)試,三者比較如下
加載一個(gè)接口的效率:PhantomJS約13秒,HtmlUnit約10秒,JS引擎約6秒
內(nèi)存消耗、CPU消耗:PhantomJS > HtmlUnit > JS引擎
PhantomJS使用外置的程序,所以JVM無(wú)法管理這部分的硬件資源,需要打開任務(wù)管理器爬取過(guò)程
經(jīng)過(guò)分析,爬取步驟分為4步:
爬取所有的詩(shī)人id。調(diào)用一次接口即可獲得所有的詩(shī)人id,返回JSON格式數(shù)據(jù),接口地址為:http://poem.studentsystem.org...
爬取所有的詩(shī)人信息。根據(jù)上一步的詩(shī)人id逐一爬取對(duì)應(yīng)的詩(shī)人詳細(xì)信息,一共有 2529 條數(shù)據(jù),則接口調(diào)用 2529 次,返回JSON格式數(shù)據(jù),接口地址為:http://poem.studentsystem.org...{id}
爬取所有的詩(shī)歌信息。根據(jù)上一步的詩(shī)人信息獲取所有的詩(shī)歌id,然后逐一調(diào)用接口獲取詩(shī)歌詳細(xì)信息,一共有約 48000 條數(shù)據(jù),則接口調(diào)用 48000 次,返回html頁(yè)面,需要模擬瀏覽器動(dòng)態(tài)執(zhí)行JS,接口地址為:http://poem.studentsystem.org...{id}
由于動(dòng)態(tài)執(zhí)行JS可會(huì)能超時(shí),因此最后要處理未成功加載完畢的詩(shī)歌信息,從數(shù)據(jù)庫(kù)中讀取這類數(shù)據(jù),再次構(gòu)成url調(diào)用接口爬取,直到所有數(shù)據(jù)都完整。這類數(shù)據(jù)約占1%,則接口調(diào)用約 480 次
顯然,如上描述,采用的是寬度優(yōu)先遍歷,所以當(dāng)執(zhí)行到第3步時(shí),才會(huì)有數(shù)據(jù)入庫(kù)耗時(shí)估計(jì)優(yōu)化后使用Java8的nashorn JS引擎執(zhí)行JS代碼,不需要?jiǎng)討B(tài)加載JS,所以不會(huì)出現(xiàn)4的問(wèn)題
根據(jù)爬取過(guò)程分析,忽略程序啟動(dòng)時(shí)間和調(diào)用獲取詩(shī)人id接口的時(shí)間
在開啟8線程的并發(fā)模式下(使用HtmlUnit進(jìn)行動(dòng)態(tài)加載):
調(diào)用獲取詩(shī)人信息的接口,每次需要5秒(5秒是線程內(nèi)置的睡眠時(shí)間,可設(shè)置)
調(diào)用獲取詩(shī)歌信息的接口,每次需要10秒(包含了上述的5秒)
一共需要: 2529 / 8 5 + 48000 (1 + 0.01)/ 8 * 10 ≈ 62596秒 ≈ 1043分鐘 ≈ 17.4小時(shí)
上述數(shù)據(jù)是在本地測(cè)試中得到的,配置為 win10 8G i5-4210M 4核
優(yōu)化后,用JS引擎取代模擬瀏覽器動(dòng)態(tài)加載JS,獲取詩(shī)歌信息的耗時(shí)明顯縮短,由10秒縮短到6秒左右,因此重新計(jì)算耗時(shí)如下:
2529 / 8 5 + 48000 / 8 6 ≈ 37185秒 ≈ 620分鐘 ≈ 10.3小時(shí)
性能評(píng)估當(dāng)使用模擬瀏覽器動(dòng)態(tài)加載JS時(shí),觀察JVM的使用情況,發(fā)現(xiàn)爬取詩(shī)歌階段頻繁發(fā)生Minor GC(新生代GC),差不多10秒一次,如下圖所示,
后判明是多線程模擬瀏覽器加載頁(yè)面行為非常的耗內(nèi)存(參考同時(shí)打開8個(gè)瀏覽器加載網(wǎng)頁(yè)),對(duì)象頻繁創(chuàng)建,頻繁消耗,
建議運(yùn)行時(shí)通過(guò)-Xms -Xmx把JVM內(nèi)存設(shè)置得大些,至少1G,然后把新生代的比例設(shè)大,如-Xms2048M -Xmx2048M -XX:+UseParallelOldGC -XX:NewRatio=1
后來(lái),用JS引擎取代模擬瀏覽器動(dòng)態(tài)加載JS,不僅速度得到明顯提升,而且內(nèi)存的消耗大幅度降低,Minor GC平均1分鐘發(fā)生一次,如下圖所示,
最后附上GitHub項(xiàng)目地址:https://github.com/Kanarienvogels/spider-tangpoem
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74977.html
摘要:有一個(gè)模塊其中實(shí)現(xiàn)了一個(gè)。但是感覺靈活性不大。接口如下它會(huì)獲得一個(gè)實(shí)例,你可以在里面進(jìn)行任意的操作。本部分到此結(jié)束。 webmagic有一個(gè)selenium模塊,其中實(shí)現(xiàn)了一個(gè)SeleniumDownloader。但是感覺靈活性不大。所以我就自己參考實(shí)現(xiàn)了一個(gè)。 首先是WebDriverPool用來(lái)管理WebDriver池: import java.util.ArrayList; im...
摘要:是爬蟲框架中比較簡(jiǎn)單易上手的一個(gè)。官網(wǎng)鏈接下面的例子是使用這個(gè)框架來(lái)爬取工商銀行的私人理財(cái)推薦分頁(yè)列表數(shù)據(jù)。頁(yè)面鏈接為引入配置如果項(xiàng)目已經(jīng)引入記錄日志,則需要在中排除。 webmagic是java爬蟲框架中比較簡(jiǎn)單易上手的一個(gè)。官網(wǎng)鏈接:http://webmagic.io/ 下面的例子是使用這個(gè)框架來(lái)爬取工商銀行的私人理財(cái)推薦分頁(yè)列表數(shù)據(jù)。頁(yè)面鏈接為:https://mybank.i...
摘要:爬蟲框架源碼分析之爬蟲框架源碼分析之爬蟲框架源碼分析之爬蟲框架源碼分析之爬蟲框架源碼分析之之進(jìn)階 爬蟲框架Webmagic源碼分析之Spider爬蟲框架WebMagic源碼分析之Scheduler爬蟲框架WebMagic源碼分析之Downloader爬蟲框架WebMagic源碼分析之Selector爬蟲框架WebMagic源碼分析之SeleniumWebMagic之Spider進(jìn)階
摘要:序是里頭比較優(yōu)秀的一個(gè)爬蟲框架使用作為解析工具,并基于其開發(fā)了解析的工具。默認(rèn)使用了作為下載工具。這里展示一下入門級(jí)使用。 序 webmagic是java里頭比較優(yōu)秀的一個(gè)爬蟲框架: 使用Jsoup作為HTML解析工具,并基于其開發(fā)了解析XPath的工具Xsoup。 默認(rèn)使用了Apache HttpClient作為下載工具。 這里展示一下入門級(jí)使用。 maven ...
摘要:獲取正在運(yùn)行的線程數(shù),用于狀態(tài)監(jiān)控。之后初始化組件主要是初始化線程池將到中,初始化開始時(shí)間等。如果線程池中運(yùn)行線程數(shù)量為,并且默認(rèn),那么就停止退出,結(jié)束爬蟲。 本系列文章,針對(duì)Webmagic 0.6.1版本 一個(gè)普通爬蟲啟動(dòng)代碼 public static void main(String[] args) { Spider.create(new GithubRepoPageP...
閱讀 2589·2021-11-15 11:38
閱讀 2922·2021-11-02 14:44
閱讀 3870·2021-09-26 10:13
閱讀 3110·2021-08-13 15:02
閱讀 813·2019-08-30 15:56
閱讀 1526·2019-08-30 15:53
閱讀 2379·2019-08-30 13:01
閱讀 3263·2019-08-29 12:57