Scrapy入門到放棄06:Spider中間件

前言

寫一寫Spider中間件吧,都凌晨了,一點都不想寫,主要是也沒啥用…哦不,是平時用得少。因為工作上的事情,已經拖更好久了,這次就趁著半夜寫一篇。

Scrapy-deltafetch插件是在Spider中間件實現的去重邏輯,開發過程中個人用的還是比較少一些的。

作用

Scrapy架構
依舊是那張熟悉的架構圖,不出意外,這張圖是最後一次出現在Scrapy系列文章中了。

如架構圖所示,Spider中間件位於Spiders(程式)和engine之間,在Item即將擁抱Pipeline之前,對Item和Response進行處理。官方定義如下:

Spider中間件是介入Scrapy的spider處理機制的鉤子框架,可以添加程式碼來處理髮送給 Spiders 的response及spider產生的item和request。

Spider中間件

當我們啟動爬蟲程式的時候,Scrapy自動幫我們激活啟用一些內置的Spider中間件。

Spider中間件

如圖所示,這裡幫我們啟用了五個Spider中間件,這裡我們依次分析一波。

內置Spider中間件

之前在下載器中間件也說了:大部分內置中間件是和settings中的配置配套使用的。Spider中間件也不例外。這裡就想將

1. HttpErrorMiddleware

作用:默認過濾出所有失敗,即響應值不在200-300之間)的response。

使用:方式很多,只講兩個,選一即可。

  1. 程式內屬性定義
class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

這個和custom_settings有異曲同工之妙,都是只在當前爬蟲生效,但是這裡作為屬性出現的。

  1. settings.py全局定義
HTTPERROR_ALLOWED_CODES = [400, 404]

如果使用custom_settings定義此配置時,和方法1一樣,都是在當前程式生效。話到此處,不妨看看HttpError中間件的源碼是如何處理響應碼的。

上圖為HttpError中間件的源碼,可以看出通過response的status來獲取響應碼,然後進行過濾判斷,如果響應碼在[200, 300)區間,則直接通過;否則就要查看配置,再次進行判斷。

2. OffsiteMiddleware

該中間件過濾出所有主機名不在spider屬性 allowed_domains 的request,request設置了 dont_filter,則就算不在也不過濾pider的 handle_httpstatus_list 屬性或 HTTPERROR_ALLOWED_CODES 設置來指定spider能處理的response返回值

3. RefererMiddleware

根據生成Request的Response的URL來設置Request的Referer欄位

4. UrlLengthMiddleware

過濾URLLENGTH_LIMIT – 允許爬取URL最長的長度

5. DepthMiddleware

用來限制爬取深度的最大深度或類似,
DEPTH_LIMIT – 爬取所允許的最大深度,如果為0,則沒有限制。
DEPTH_STATS – 是否收集爬取狀態。
DEPTH_PRIORITY – 是否根據其深度對requet安排優先順序

自定義Spider中間件

Spider中間件也是在middlewares.py中進行定義,通過SPIDER_MIDDLEWARES進行激活啟用配置。

這裡我們先看看Scrapy給定的自定義模板是怎麼樣的。

如圖,主要需要實現以下幾個方法:

  1. from_crawler:類方法,用於初始化中間件
  2. process_spider_input:當response通過spider中間件時,該方法被調用,處理該response
  3. process_spider_output:當Spider處理response返回result時,該方法被調用
  4. process_spider_exception:異常時, 該方法被調用
  5. process_start_requests:該方法以spider 啟動的request為參數被調用,執行的過程類似於 process_spider_outpu ,只不過其沒有相關聯的response並且必須返回request(不是item)。

這裡具體如何實現就不寫了,參考上面HttpErrorMiddleware的程式碼實現即可。

區別

Spider中間件和下載器中間件有什麼區別?

  1. Spider中間件可以獲取到Item,即爬取數據的封裝結構。
  2. Spider中間件是單向的,處理請求和響應。下載器中間件是雙向的,第一次處理請求,第二次處理請求和響應。
  3. Spider中間件主要對請求後的響應結果進行處理;下載器中間件主要是對在請求前構造請求,例如添加請求頭、代理IP等。

結語

這篇文章主要是作一個知識擴展,對於Spider中間件來說,了解並會使用內置中間件即可,至於自定義真的很少會用到。

寫這種基礎理論篇是最磨人性子的了,其實可能自己一看就懂,但是就是很難很好的講出來。所幸的是,後面應該就快要到實操的環節了。期待下一次相遇。


95後小程式設計師,寫的都是日常工作中的親身實踐,置身於初學者的角度從0寫到1,詳細且認真。文章會在公眾號 [入門到放棄之路] 首發,期待你的關注。

感謝每一份關注