Scrapy的架構(gòu)

Scrapy的架構(gòu)太重要了,單用一篇文章再總結(jié)整合下。前兩張圖來(lái)自《Learning Scrapy》,第三張圖來(lái)自Scrapy 1.0中文官方文檔(該中文文檔只到1.0版),第四張圖來(lái)自Scrapy 1.4英文官方文檔(最新版),是我翻譯的。

一、Scrapy的Twisted引擎模型

這里重要的概念是單線程、NIO、延遲項(xiàng)和延遲鏈。

掛衣鉤和鏈子

二、Scrapy的性能模型

Scrapy包括以下部分:

  • 調(diào)度器:大量的Request在這里排隊(duì),直到下載器處理它們。其中大部分是URL,因此體積不大,也就是說(shuō)即便有大量請(qǐng)求存在,也可以被下載器及時(shí)處理。
  • 阻塞器:這是抓取器由后向前進(jìn)行反饋的一個(gè)安全閥,如果進(jìn)程中的響應(yīng)大于5MB,阻塞器就會(huì)暫停更多的請(qǐng)求進(jìn)入下載器。這可能會(huì)造成性能的波動(dòng)。
  • 下載器:這是對(duì)Scrapy的性能最重要的組件。它用復(fù)雜的機(jī)制限制了并發(fā)數(shù)。它的延遲(管道長(zhǎng)度)等于遠(yuǎn)程服務(wù)器的響應(yīng)時(shí)間,加上網(wǎng)絡(luò)/操作系統(tǒng)、Python/Twisted的延遲。我們可以調(diào)節(jié)并發(fā)請(qǐng)求數(shù),但是對(duì)其它延遲無(wú)能為力。下載器的能力受限于CONCURRENT_REQUESTS*設(shè)置。
  • 爬蟲:這是抓取器將Response變?yōu)镮tem和其它Request的組件。只要我們遵循規(guī)則來(lái)寫爬蟲,通常它不是瓶頸。
  • Item Pipelines:這是抓取器的第二部分。我們的爬蟲對(duì)每個(gè)Request可能產(chǎn)生幾百個(gè)Items,只有CONCURRENT_ITEMS會(huì)被并行處理。這一點(diǎn)很重要,因?yàn)?,如果你用pipelines連接數(shù)據(jù)庫(kù),你可能無(wú)意地向數(shù)據(jù)庫(kù)導(dǎo)入數(shù)據(jù),pipelines的默認(rèn)值(100)就會(huì)看起來(lái)很少。

爬蟲和pipelines的代碼是異步的,會(huì)包含必要的延遲,但二者不會(huì)是瓶頸。爬蟲和pipelines很少會(huì)做繁重的處理工作。如果是的話,服務(wù)器的CPU則是瓶頸。


三、Scrapy架構(gòu)

原文鏈接:http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/architecture.html

接下來(lái)的圖表展現(xiàn)了Scrapy的架構(gòu),包括組件及在系統(tǒng)中發(fā)生的數(shù)據(jù)流的概覽(綠色箭頭所示)。 下面對(duì)每個(gè)組件都做了簡(jiǎn)單介紹,并給出了詳細(xì)內(nèi)容的鏈接。數(shù)據(jù)流如下所描述。

組件

Scrapy Engine

引擎負(fù)責(zé)控制數(shù)據(jù)流在系統(tǒng)中所有組件中流動(dòng),并在相應(yīng)動(dòng)作發(fā)生時(shí)觸發(fā)事件。 詳細(xì)內(nèi)容查看下面的數(shù)據(jù)流(Data Flow)部分。

調(diào)度器(Scheduler)

調(diào)度器從引擎接受request并將他們?nèi)腙?duì),以便之后引擎請(qǐng)求他們時(shí)提供給引擎。

下載器(Downloader)

下載器負(fù)責(zé)獲取頁(yè)面數(shù)據(jù)并提供給引擎,而后提供給spider。

Spiders

Spider是Scrapy用戶編寫用于分析response并提取item(即獲取到的item)或額外跟進(jìn)的URL的類。 每個(gè)spider負(fù)責(zé)處理一個(gè)特定(或一些)網(wǎng)站。 更多內(nèi)容請(qǐng)看 Spiders 。

Item Pipeline

Item Pipeline負(fù)責(zé)處理被spider提取出來(lái)的item。典型的處理有清理、 驗(yàn)證及持久化(例如存取到數(shù)據(jù)庫(kù)中)。 更多內(nèi)容查看 Item Pipeline

下載器中間件(Downloader middlewares)

下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的response。 其提供了一個(gè)簡(jiǎn)便的機(jī)制,通過(guò)插入自定義代碼來(lái)擴(kuò)展Scrapy功能。更多內(nèi)容請(qǐng)看 下載器中間(Downloader Middleware)

Spider中間件(Spider middlewares)

Spider中間件是在引擎及Spider之間的特定鉤子(specific hook),處理spider的輸入(response)和輸出(items及requests)。 其提供了一個(gè)簡(jiǎn)便的機(jī)制,通過(guò)插入自定義代碼來(lái)擴(kuò)展Scrapy功能。更多內(nèi)容請(qǐng)看 Spider中間件(Middleware) 。

數(shù)據(jù)流(Data flow)

Scrapy中的數(shù)據(jù)流由執(zhí)行引擎控制,其過(guò)程如下:

  1. 引擎打開一個(gè)網(wǎng)站(open a domain),找到處理該網(wǎng)站的Spider并向該spider請(qǐng)求第一個(gè)要爬取的URL(s)。
  2. 引擎從Spider中獲取到第一個(gè)要爬取的URL并在調(diào)度器(Scheduler)以Request調(diào)度。
  3. 引擎向調(diào)度器請(qǐng)求下一個(gè)要爬取的URL。
  4. 調(diào)度器返回下一個(gè)要爬取的URL給引擎,引擎將URL通過(guò)下載中間件(請(qǐng)求(request)方向)轉(zhuǎn)發(fā)給下載器(Downloader)。
  5. 一旦頁(yè)面下載完畢,下載器生成一個(gè)該頁(yè)面的Response,并將其通過(guò)下載中間件(返回(response)方向)發(fā)送給引擎。
  6. 引擎從下載器中接收到Response并通過(guò)Spider中間件(輸入方向)發(fā)送給Spider處理。
  7. Spider處理Response并返回爬取到的Item及(跟進(jìn)的)新的Request給引擎。
  8. 引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調(diào)度器。
  9. (從第二步)重復(fù)直到調(diào)度器中沒有更多地request,引擎關(guān)閉該網(wǎng)站。

事件驅(qū)動(dòng)網(wǎng)絡(luò)(Event-driven networking)

Scrapy基于事件驅(qū)動(dòng)網(wǎng)絡(luò)框架 Twisted 編寫。因此,Scrapy基于并發(fā)性考慮由非阻塞(即異步)的實(shí)現(xiàn)。

關(guān)于異步編程及Twisted更多的內(nèi)容請(qǐng)查看下列鏈接:


四、Scrapy架構(gòu)

原文鏈接:https://docs.scrapy.org/en/latest/topics/architecture.html

下圖展示了Scrapy的架構(gòu)、它的組件及數(shù)據(jù)流(紅色箭頭)。分別對(duì)組件和數(shù)據(jù)流進(jìn)行了說(shuō)明。

數(shù)據(jù)流

數(shù)據(jù)流是受執(zhí)行引擎控制的,流程如下:

  1. 引擎從爬蟲得到初始請(qǐng)求;
  2. 引擎在調(diào)度器中調(diào)度請(qǐng)求,并請(qǐng)求下一個(gè)要爬取的請(qǐng)求;
  3. 調(diào)度器返回引擎下一個(gè)要爬取的請(qǐng)求;
  4. 通過(guò)下載中間件,引擎將請(qǐng)求發(fā)送到下載器;
  5. 頁(yè)面下載完畢之后,下載器生成一個(gè)該頁(yè)面的響應(yīng),并通過(guò)下載中間件發(fā)送給引擎;
  6. 引擎收到來(lái)自下載器的響應(yīng),并通過(guò)爬蟲中間件,將它發(fā)送到爬蟲進(jìn)行處理;
  7. 爬蟲處理響應(yīng),而后返回抓取到的items和新的請(qǐng)求到引擎,返回還要要通過(guò)爬蟲中間件;
  8. 引擎將處理好的items發(fā)送到Item Pipelines,然后發(fā)送已處理的請(qǐng)求到調(diào)度器,并詢問(wèn)下個(gè)可能的請(qǐng)求;
  9. 這個(gè)過(guò)程重復(fù)進(jìn)行(從1開始),直到調(diào)度器沒有更多的請(qǐng)求。

組件

Scrapy引擎

引擎負(fù)責(zé)控制數(shù)據(jù)流在系統(tǒng)中所有組件中流動(dòng),并在相應(yīng)動(dòng)作發(fā)生時(shí)觸發(fā)事件。

調(diào)度器

調(diào)度器從引擎接受請(qǐng)求并將其排隊(duì),以便之后引擎請(qǐng)求它們時(shí)提供給引擎。

下載器

下載器負(fù)責(zé)獲取頁(yè)面,并提供給引擎,引擎再將其提供給爬蟲。

爬蟲

Spider是Scrapy用戶編寫的用于解析請(qǐng)求并提取item或額外跟進(jìn)的請(qǐng)求的類。

Item Pipeline

Item Pipeline負(fù)責(zé)處理爬蟲提取出來(lái)的item。典型的任務(wù)有清理、 驗(yàn)證及持久化(例如存取到數(shù)據(jù)庫(kù)中)。

下載器中間件

下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),當(dāng)請(qǐng)求從引擎到下載器時(shí)處理請(qǐng)求,響應(yīng)從下載器到引擎時(shí)處理響應(yīng)。

如果要做以下的工作,就可以使用下載器中間件:

  • 請(qǐng)求發(fā)送給下載器之前,處理這個(gè)請(qǐng)求(即,在Scrapy發(fā)送請(qǐng)求到網(wǎng)站之前);
  • 傳遞響應(yīng)到爬蟲之前,修改收到的響應(yīng);
  • 發(fā)送一個(gè)新的請(qǐng)求到爬蟲,而不是傳遞收到的響應(yīng)到爬蟲;
  • 沒有獲取網(wǎng)頁(yè),直接傳遞響應(yīng)給爬蟲;
  • 默默丟棄一些請(qǐng)求。

爬蟲中間件

爬蟲中間件是在引擎及爬蟲之間的特定鉤子(specific hook),處理爬蟲的輸入(響應(yīng))和輸出(items和請(qǐng)求)。

爬蟲中間件的可以用來(lái):

  • 對(duì)爬蟲調(diào)回的輸出做后處理 —— 修改、添加、移除請(qǐng)求或items;
  • 后處理初始請(qǐng)求(start_requests);
  • 處理爬蟲異常;
  • 調(diào)用errback,而不是基于響應(yīng)內(nèi)容調(diào)回一些請(qǐng)求。

事件驅(qū)動(dòng)網(wǎng)絡(luò)

Scrapy是基于事件驅(qū)動(dòng)網(wǎng)絡(luò)框架 Twisted 編寫的。因此,Scrapy基于并發(fā)考慮由非阻塞(異步)代碼實(shí)現(xiàn)。

關(guān)于異步編程及Twisted更多的內(nèi)容請(qǐng)查看下列鏈接:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評(píng)論 6 540
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,275評(píng)論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,368評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,736評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,919評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,481評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,235評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,427評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,656評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評(píng)論 1 294
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,160評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,380評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容