Scrapy的架構太重要了,單用一篇文章再總結整合下。前兩張圖來自《Learning Scrapy》,第三張圖來自Scrapy 1.0中文官方文檔(該中文文檔隻到1.0版),第四張圖來自Scrapy 1.4英文官方文檔(最新版),是我翻譯的。
一、Scrapy的Twisted引擎模型
這裡重要的概念是單線程、NIO、延遲項和延遲鍊。
挂衣鈎和鍊子
二、Scrapy的性能模型
Scrapy包括以下部分:
- 排程器:大量的Request在這裡排隊,直到下載下傳器處理它們。其中大部分是URL,是以體積不大,也就是說即便有大量請求存在,也可以被下載下傳器及時處理。
- 阻塞器:這是抓取器由後向前進行回報的一個安全閥,如果程序中的響應大于5MB,阻塞器就會暫停更多的請求進入下載下傳器。這可能會造成性能的波動。
- 下載下傳器:這是對Scrapy的性能最重要的元件。它用複雜的機制限制了并發數。它的延遲(管道長度)等于遠端伺服器的響應時間,加上網絡/作業系統、Python/Twisted的延遲。我們可以調節并發請求數,但是對其它延遲無能為力。下載下傳器的能力受限于CONCURRENT_REQUESTS*設定。
- 爬蟲:這是抓取器将Response變為Item和其它Request的元件。隻要我們遵循規則來寫爬蟲,通常它不是瓶頸。
- Item Pipelines:這是抓取器的第二部分。我們的爬蟲對每個Request可能産生幾百個Items,隻有CONCURRENT_ITEMS會被并行處理。這一點很重要,因為,如果你用pipelines連接配接資料庫,你可能無意地向資料庫導入資料,pipelines的預設值(100)就會看起來很少。
爬蟲和pipelines的代碼是異步的,會包含必要的延遲,但二者不會是瓶頸。爬蟲和pipelines很少會做繁重的處理工作。如果是的話,伺服器的CPU則是瓶頸。
三、Scrapy架構
原文連結:
http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/architecture.html接下來的圖表展現了Scrapy的架構,包括元件及在系統中發生的資料流的概覽(綠色箭頭所示)。 下面對每個元件都做了簡單介紹,并給出了詳細内容的連結。資料流如下所描述。
元件
Scrapy Engine
引擎負責控制資料流在系統中所有元件中流動,并在相應動作發生時觸發事件。 詳細内容檢視下面的資料流(Data Flow)部分。
排程器(Scheduler)
排程器從引擎接受request并将他們入隊,以便之後引擎請求他們時提供給引擎。
下載下傳器(Downloader)
下載下傳器負責擷取頁面資料并提供給引擎,而後提供給spider。
Spiders
Spider是Scrapy使用者編寫用于分析response并提取item(即擷取到的item)或額外跟進的URL的類。 每個spider負責處理一個特定(或一些)網站。 更多内容請看
。
Item Pipeline
Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到資料庫中)。 更多内容檢視
下載下傳器中間件(Downloader middlewares) https://link.jianshu.com?t=http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/architecture.html#downloader-middlewares
下載下傳器中間件是在引擎及下載下傳器之間的特定鈎子(specific hook),處理Downloader傳遞給引擎的response。 其提供了一個簡便的機制,通過插入自定義代碼來擴充Scrapy功能。更多内容請看
下載下傳器中間(Downloader Middleware)Spider中間件(Spider middlewares)
Spider中間件是在引擎及Spider之間的特定鈎子(specific hook),處理spider的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,通過插入自定義代碼來擴充Scrapy功能。更多内容請看
Spider中間件(Middleware)資料流(Data flow)
Scrapy中的資料流由執行引擎控制,其過程如下:
- 引擎打開一個網站(open a domain),找到處理該網站的Spider并向該spider請求第一個要爬取的URL(s)。
- 引擎從Spider中擷取到第一個要爬取的URL并在排程器(Scheduler)以Request排程。
- 引擎向排程器請求下一個要爬取的URL。
- 排程器傳回下一個要爬取的URL給引擎,引擎将URL通過下載下傳中間件(請求(request)方向)轉發給下載下傳器(Downloader)。
- 一旦頁面下載下傳完畢,下載下傳器生成一個該頁面的Response,并将其通過下載下傳中間件(傳回(response)方向)發送給引擎。
- 引擎從下載下傳器中接收到Response并通過Spider中間件(輸入方向)發送給Spider處理。
- Spider處理Response并傳回爬取到的Item及(跟進的)新的Request給引擎。
- 引擎将(Spider傳回的)爬取到的Item給Item Pipeline,将(Spider傳回的)Request給排程器。
- (從第二步)重複直到排程器中沒有更多地request,引擎關閉該網站。
事件驅動網絡(Event-driven networking)
Scrapy基于事件驅動網絡架構
Twisted編寫。是以,Scrapy基于并發性考慮由非阻塞(即異步)的實作。
關于異步程式設計及Twisted更多的内容請檢視下列連結:
四、Scrapy架構
https://docs.scrapy.org/en/latest/topics/architecture.html下圖展示了Scrapy的架構、它的元件及資料流(紅色箭頭)。分别對元件和資料流進行了說明。
資料流
資料流是受執行引擎控制的,流程如下:
- 引擎從爬蟲得到初始請求;
- 引擎在排程器中排程請求,并請求下一個要爬取的請求;
- 排程器傳回引擎下一個要爬取的請求;
- 通過下載下傳中間件,引擎将請求發送到下載下傳器;
- 頁面下載下傳完畢之後,下載下傳器生成一個該頁面的響應,并通過下載下傳中間件發送給引擎;
- 引擎收到來自下載下傳器的響應,并通過爬蟲中間件,将它發送到爬蟲進行處理;
- 爬蟲處理響應,而後傳回抓取到的items和新的請求到引擎,傳回還要要通過爬蟲中間件;
- 引擎将處理好的items發送到Item Pipelines,然後發送已處理的請求到排程器,并詢問下個可能的請求;
- 這個過程重複進行(從1開始),直到排程器沒有更多的請求。
Scrapy引擎
引擎負責控制資料流在系統中所有元件中流動,并在相應動作發生時觸發事件。
排程器
排程器從引擎接受請求并将其排隊,以便之後引擎請求它們時提供給引擎。
下載下傳器
下載下傳器負責擷取頁面,并提供給引擎,引擎再将其提供給爬蟲。
爬蟲
Spider是Scrapy使用者編寫的用于解析請求并提取item或額外跟進的請求的類。
Item Pipeline負責處理爬蟲提取出來的item。典型的任務有清理、 驗證及持久化(例如存取到資料庫中)。
下載下傳器中間件
下載下傳器中間件是在引擎及下載下傳器之間的特定鈎子(specific hook),當請求從引擎到下載下傳器時處理請求,響應從下載下傳器到引擎時處理響應。
如果要做以下的工作,就可以使用下載下傳器中間件:
- 請求發送給下載下傳器之前,處理這個請求(即,在Scrapy發送請求到網站之前);
- 傳遞響應到爬蟲之前,修改收到的響應;
- 發送一個新的請求到爬蟲,而不是傳遞收到的響應到爬蟲;
- 沒有擷取網頁,直接傳遞響應給爬蟲;
- 默默丢棄一些請求。
爬蟲中間件
爬蟲中間件是在引擎及爬蟲之間的特定鈎子(specific hook),處理爬蟲的輸入(響應)和輸出(items和請求)。
爬蟲中間件的可以用來:
- 對爬蟲調回的輸出做後處理 —— 修改、添加、移除請求或items;
- 後處理初始請求(start_requests);
- 處理爬蟲異常;
- 調用errback,而不是基于響應内容調回一些請求。
事件驅動網絡
Scrapy是基于事件驅動網絡架構 Twisted 編寫的。是以,Scrapy基于并發考慮由非阻塞(異步)代碼實作。