Spider Middleware是介入到Scrapy的Spider處理機制的鉤子框架。咱們首先來看看它的架構,以下圖所示。
html
當Downloader生成Response以後,Response會被髮送給Spider,在發送給Spider以前,Response會首先通過Spider Middleware處理,當Spider處理生成Item和Request以後,Item和Request還會通過Spider Middleware的處理。bash
Spider Middleware有以下三個做用。微信
咱們能夠在Downloader生成的Response發送給Spider以前,也就是在Response發送給Spider以前對Response進行處理。網絡
咱們能夠在Spider生成的Request發送給Scheduler以前,也就是在Request發送給Scheduler以前對Request進行處理。架構
咱們能夠在Spider生成的Item發送給Item Pipeline以前,也就是在Item發送給Item Pipeline以前對Item進行處理。框架
須要說明的是,Scrapy其實已經提供了許多Spider Middleware,它們被SPIDER_MIDDLEWARES_BASE
這個變量所定義。
scrapy
SPIDER_MIDDLEWARES_BASE
變量的內容以下:ide
{
'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': 50,
'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': 500,
'scrapy.spidermiddlewares.referer.RefererMiddleware': 700,
'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware': 800,
'scrapy.spidermiddlewares.depth.DepthMiddleware': 900,
}複製代碼
和Downloader Middleware同樣,Spider Middleware首先加入到SPIDER_MIDDLEWARES
設置中,該設置會和Scrapy中SPIDER_MIDDLEWARES_BASE
定義的Spider Middleware合併。而後根據鍵值的數字優先級排序,獲得一個有序列表。第一個Middleware是最靠近引擎的,最後一個Middleware是最靠近Spider的。ui
Scrapy內置的Spider Middleware爲Scrapy提供了基礎的功能。若是咱們想要擴展其功能,只須要實現某幾個方法便可。
url
每一個Spider Middleware都定義瞭如下一個或多個方法的類,核心方法有以下4個。
process_spider_input(response, spider)
。
process_spider_output(response, result, spider)
。
process_spider_exception(response, exception, spider)
。
process_start_requests(start_requests, spider)
。
只須要實現其中一個方法就能夠定義一個 Spider Middleware。下面咱們來看看這4個方法的詳細用法。
當Response被Spider Middleware處理時,process_spider_input()
方法被調用。
process_spider_input()
方法的參數有以下兩個。
response
,是Response對象,即被處理的Response。
spider
,是Spider對象,即該Response對應的Spider。
process_spider_input()
應該返回None或者拋出一個異常。
若是它返回None,Scrapy將會繼續處理該Response,調用全部其餘的Spider Middleware,直到Spider處理該Response。
若是它拋出一個異常,Scrapy將不會調用任何其餘Spider Middleware的process_spider_input()
方法,而調用Request的errback()
方法。errback
的輸出將會被從新輸入到中間件中,使用process_spider_output()
方法來處理,當其拋出異常時則調用process_spider_exception()
來處理。
當Spider處理Response返回結果時,process_spider_output()
方法被調用。
process_spider_output()
方法的參數有以下三個。
response
,是Response對象,即生成該輸出的Response。
result
,包含Request或Item對象的可迭代對象,即Spider返回的結果。
spider
,是Spider對象,即其結果對應的Spider。
process_spider_output()
必須返回包含Request或Item對象的可迭代對象。
當Spider或Spider Middleware的process_spider_input()
方法拋出異常時,process_spider_exception()
方法被調用。
process_spider_exception()
方法的參數有以下三個。
response
,是Response對象,即異常被拋出時被處理的Response。
exception
,是Exception對象,即被拋出的異常。
spider
,是Spider對象,即拋出該異常的Spider。
process_spider_exception()
必需要麼返回None
,要麼返回一個包含Response或Item對象的可迭代對象。
若是它返回None
,Scrapy將繼續處理該異常,調用其餘Spider Middleware中的process_spider_exception()
方法,直到全部Spider Middleware都被調用。
若是它返回一個可迭代對象,則其餘Spider Middleware的process_spider_output()
方法被調用,其餘的process_spider_exception()
不會被調用。
process_start_requests()
方法以Spider啓動的Request爲參數被調用,執行的過程相似於process_spider_output()
,只不過它沒有相關聯的Response,而且必須返回Request。
process_start_requests()
方法的參數有以下兩個。
start_requests
,是包含Request的可迭代對象,即Start Requests。
spider
,是Spider對象,即Start Requests所屬的Spider。
process_start_requests()
必須返回另外一個包含Request對象的可迭代對象。
本節介紹了Spider Middleware的基本原理和自定義Spider Middleware的方法。Spider Middleware使用的頻率不如Downloader Middleware的高,在必要的狀況下它能夠用來方便數據的處理。
本資源首發於崔慶才的我的博客靜覓: Python3網絡爬蟲開發實戰教程 | 靜覓
如想了解更多爬蟲資訊,請關注個人我的微信公衆號:進擊的Coder
weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)