前言
剛換了公司,公司老板讓我修改pyspider源碼以實(shí)現(xiàn)功能(假設(shè)我們有5個(gè)服務(wù)器,一個(gè)部署在美國(guó),4個(gè)部署在國(guó)內(nèi),但是pyspider 分發(fā)節(jié)點(diǎn)是根據(jù)redis的生產(chǎn)消費(fèi)模式隨機(jī)分發(fā),我抓取國(guó)內(nèi)的網(wǎng)頁,他說不定會(huì)分發(fā)到美國(guó)的那個(gè)服務(wù)器,那么怎么指定就讓他分發(fā)到國(guó)內(nèi)的這4個(gè)服務(wù)器上哪 ?)
目錄結(jié)構(gòu)
- message_queue
- scheduler
- fetcher
- processor
- webui
- run.py
scheduler用于事件的分發(fā)
fetcher用于拉取數(shù)據(jù),其中涉及到phantomjs的拉取。
processor用于頁面解析數(shù)據(jù)提取工作(用我們自己寫的腳本干活的)。
所以pyspider的核心組件是拉去網(wǎng)頁的fetcher和處理網(wǎng)頁的processor。
一. run.py(程序的入口)
這個(gè)py文件為程序的入口,包括讀取配置文件、鏈接數(shù)據(jù)庫、鏈接redis等操作.

這段代碼為讀取config.json文件中的數(shù)據(jù)庫內(nèi)容,其中可以使用mysql、mongodb、sqllite(太小了吧),這里面并不包括我大postgresql、oracle等數(shù)據(jù)庫,所以你想使用其他的數(shù)據(jù)庫,自己手動(dòng)添加吧。

這段代碼也比較簡(jiǎn)單,他也是讀取config.json 中的mssage_queue屬性,我用的redis,其中紅框標(biāo)記的connect_message_queue為鏈接消息隊(duì)列redis的方法,這個(gè)很重要,具體的在后面分析,但是有一個(gè)小問題,他是在一個(gè)for循環(huán)里面,所以鏈接的話是會(huì)鏈接五次,這是為什么那,我有點(diǎn)不知道。
二. message_queus
這個(gè)里面主要有幾個(gè)消息對(duì)列的工具類,包括redis、rabbitmq等其余一些不知道什么玩意的消息隊(duì)列?,F(xiàn)在看一下我們剛才說的connect_message_queue方法這里可以看一下了。

這個(gè)方法一進(jìn)來還是一大堆判斷,總之最后是走到Queue,這個(gè)方法是具體的消息隊(duì)列對(duì)象,里面不用想就是包含了對(duì)數(shù)據(jù)隊(duì)列的實(shí)例化以及具體操作了,像get、put方法,這里有一點(diǎn)要說明,這里redis的模式用的是生產(chǎn)消費(fèi)模式(另一種是發(fā)布訂閱模式,不同點(diǎn)自己去看)
三. fetcher
fetcher 是用來拉取數(shù)據(jù)的,我們顯卡他的run方法.

函數(shù)run()是抓取程序fetcher中的一個(gè)大的循環(huán)程序。
函數(shù)run()中定義了另外一個(gè)函數(shù)queue_loop(),該函數(shù)接收輸入隊(duì)列中的所有任務(wù),并抓取它們。同時(shí)該函數(shù)也監(jiān)聽中斷信號(hào)。其中inqueue就是維持的redis隊(duì)列,他調(diào)用get_nowait()方法從redis中拿取task。函數(shù)queue_loop()也會(huì)調(diào)用另一個(gè)能使我們更接近于實(shí)際檢索Web資源操作的函數(shù):fetch()。
函數(shù)fetch()只決定檢索該資源的正確方法是什么。最后調(diào)用的是http_fetch,這個(gè)函數(shù)很長(zhǎng),但是也是辦實(shí)事的,它包含處理header、cookie等問題。
四. processor
內(nèi)容處理程序的目的是分析已經(jīng)抓取回來的頁面。
它簡(jiǎn)單地從隊(duì)列中得到需要被分析的下一個(gè)任務(wù),并利用on_task(task, response)函數(shù)對(duì)其進(jìn)行分析。
ontask()方法嘗試?yán)幂斎氲娜蝿?wù)找到任務(wù)所屬的項(xiàng)目。然后它運(yùn)行項(xiàng)目中的定制腳本。最后它分析定制腳本返回的響應(yīng)response。
五.scheduler
這個(gè)主要就是實(shí)現(xiàn)調(diào)度策略。具體的是六個(gè)方法,作者都有注釋。
六.解決老板提出的問題
剛才說了老板提出的問題是指定節(jié)點(diǎn)完成任務(wù)。最開始的想法是利用redis指定分發(fā),利用redis的的頻道解決問題,但是后來因?yàn)榉N種原因感覺不太行,所以現(xiàn)在研究的辦法是在fetcher的run方法中進(jìn)行ip判斷,判斷非法ip,正常ip通過修改以達(dá)到指定具體節(jié)點(diǎn)的目的,雖然很low,但是可以解決問題。
來個(gè)結(jié)尾
讓我再說最后一句,這是自己瞎總結(jié)的,如果有問題,萬分希望指出,另外如果你是美女,歡迎加我qq來問問題。qq:810043299 :) 別忘了點(diǎn)贊啊