webmagic半火,一個(gè)簡(jiǎn)潔但功能齊全的爬蟲框架,其官方文檔已經(jīng)非常詳盡钮糖,但偏重于使用,該文從源碼結(jié)構(gòu)以及細(xì)節(jié)上進(jìn)行分析
webmagic組件
webmagic的各個(gè)功能分別通過(guò)組件來(lái)實(shí)現(xiàn)店归,很好的實(shí)現(xiàn)了各功能之間的解耦,主要包括四大組件:Scheduler消痛、Downloader、Pipeline秩伞、PageProcessor逞带,四大組件通過(guò)Spider類進(jìn)行相互協(xié)作完成框架功能
一、Scheduler
抓取url的管理纱新,包含添加待抓取url以及取出需要抓取的url功能展氓,分別通過(guò)push方法和poll方法完成兩項(xiàng)功能,抓取url進(jìn)行了抽象脸爱,以Request進(jìn)行表示遇汞。
實(shí)現(xiàn)類
QueueScheduler:內(nèi)部以LinkedBlockingQueue實(shí)現(xiàn)url隊(duì)列,添加待抓取url直接以queue.add方法實(shí)現(xiàn),取出抓取url以queue.poll實(shí)現(xiàn)勺疼。該類繼承于DuplicateRemovedScheduler教寂,因此有自動(dòng)去重的功能。
PriorityScheduler:以優(yōu)先級(jí)作為取出待抓取url的條件执庐,內(nèi)部以PriorityBlockingQueue作為隊(duì)列的實(shí)現(xiàn),同樣繼承于DuplicateRemovedScheduler导梆,擁有去重功能
二轨淌、PageProcessor
如何對(duì)一個(gè)頁(yè)面內(nèi)容進(jìn)行處理,是用戶主要需要實(shí)現(xiàn)的接口看尼,一般用戶需要實(shí)現(xiàn)對(duì)頁(yè)面內(nèi)容的抽取以及更多待抓取url的獲取
實(shí)現(xiàn)類
SimplePageProcessor:配置一個(gè)url正則表達(dá)式递鹉,自動(dòng)從頁(yè)面內(nèi)容中抽取出對(duì)應(yīng)的url加入抓取隊(duì)列
三、Pipeline
對(duì)PageProcessor的抽取結(jié)果進(jìn)行持久化處理藏斩,比如寫入文件躏结、存入數(shù)據(jù)庫(kù)、或者簡(jiǎn)單的打印到控制臺(tái)
實(shí)現(xiàn)類
ConsolePipeline:直接將結(jié)果輸出到控制臺(tái)
FilePipeline:將抽取結(jié)果寫入文件進(jìn)行持久化
四狰域、Downloader
負(fù)責(zé)對(duì)待抓取的url進(jìn)行下載媳拴,可配置下載線程數(shù)
實(shí)現(xiàn)類
HttpClientDownloader:使用apache HttpClient進(jìn)行頁(yè)面的下載功能,實(shí)現(xiàn)了代理配置功能
輔助類
一兆览、CountableThreadPool
負(fù)責(zé)spider的線程管理屈溉,實(shí)現(xiàn)了一個(gè)堵塞線程池,可以實(shí)時(shí)獲取線程池中正在使用的線程以及等待狀態(tài)的線程數(shù)量抬探,線程數(shù)的統(tǒng)計(jì)以AtomicInteger實(shí)現(xiàn)線程安全子巾,內(nèi)部默認(rèn)的ExecutorService通過(guò)Executors.newFixedThreadPool生成,主要方法execute接受一個(gè)Runnable對(duì)象作為待執(zhí)行任務(wù)小压,線程池中無(wú)可用線程時(shí)會(huì)進(jìn)入阻塞狀態(tài)
二线梗、Proxy
進(jìn)行spider的代理管理,抽取為單獨(dú)的組件可以實(shí)現(xiàn)解耦
三怠益、Selector
實(shí)現(xiàn)對(duì)下載后的頁(yè)面內(nèi)容進(jìn)行選擇的功能仪搔,主要實(shí)現(xiàn)有xpath、css溉痢、regex以及jsonPath
四僻造、Request
對(duì)抓取url的封裝
五、Page
存儲(chǔ)抽取的內(nèi)容以及抓取的url(非線程安全)
配置類
一孩饼、Spider
爬蟲的入口髓削,對(duì)各個(gè)組件進(jìn)行協(xié)調(diào)立膛,包含一個(gè)Downloader宝泵,一個(gè)PageProcessor,一個(gè)Scheduler以及一個(gè)PipeLine列表儿奶,抓取任務(wù)的執(zhí)行線程調(diào)度以CountableThreadPool完成
二闯捎、site
抓取站點(diǎn)的配置,包括域名秉版、ua茬祷、默認(rèn)cookie、默認(rèn)編碼秸妥、默認(rèn)http頭等
webmagic關(guān)于多線程的處理
爬蟲程序必然牽涉到多線程處理以實(shí)現(xiàn)并行的抓取任務(wù)筛峭,在webmagic中主要有三處需要對(duì)多線程情況進(jìn)行處理
Scheduler
在同一時(shí)間可能會(huì)有多個(gè)線程對(duì)Scheduler進(jìn)行操作陪每,webmaigic的QueueScheduler實(shí)現(xiàn)直接以LinkedBlockingQueue解決該問(wèn)題
HttpClientDownloader
在對(duì)httpclient的獲取中檩禾,主要是在生成新的httpClient時(shí)需要進(jìn)行多線程的處理,主要代碼
當(dāng)需要獲取的httpclient不存在時(shí)進(jìn)開始進(jìn)行同步處理饵婆,在同步代碼塊中判斷是否有對(duì)應(yīng)的httpclient存在侨核,如果沒有則生成對(duì)應(yīng)httpclient并加入列表中灌灾,該處使用雙重檢查保證不會(huì)重復(fù)放入httpclient锋喜,進(jìn)行雙重檢測(cè)是由于未對(duì)整個(gè)方法進(jìn)行同步處理豌鸡,目的是為了性能優(yōu)化涯冠,即不會(huì)對(duì)存在相應(yīng)的httpclient進(jìn)行同步逼庞,只對(duì)獲取不到該對(duì)象的情況進(jìn)行同步
Spider
spider負(fù)責(zé)對(duì)整個(gè)抓取過(guò)程進(jìn)行協(xié)調(diào),自然避免不了對(duì)多線程的處理赛糟,該類主要通過(guò)ReentrantLock和Condition進(jìn)行多線程的處理。當(dāng)爬蟲開始執(zhí)行時(shí),spider持續(xù)從scheduler中獲取待抓取的url穆咐,當(dāng)待抓取url為空時(shí)字旭,該線程進(jìn)行等待狀態(tài),通過(guò)waitNewUrl實(shí)現(xiàn)
該阻塞狀態(tài)通過(guò)signalNewUrl方法進(jìn)行解除