您好,登錄后才能下訂單哦!
如何使用Scrapy 中間鍵,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
中間件的運用比較廣泛,如果直接從定義的角度去理解中間件會有點亂,我以分布式系統為例子進行說明。在上篇文章,我講到目前后臺服務架構基本都是往分布式發展。其實分布式系統也算是一個中間件。
那什么是分布式系統?分布式系統是由一組通過網絡進行通信、為了完成共同的任務而協調工作的計算機節點組成的系統。我們從下圖中可得知,分布式系統是介于操作系統和用戶應用之間的軟件。
那么不妨我們進一步拓展下思維去理解中間件。可知,中間件(middleware)是基礎軟件的一大類,屬于可復用軟件的范疇。顧名思義,中間件處于操作系統軟件與用戶的應用軟件的中間。
我們先通過一張圖了解下 Scrapy 架構。
我們可以看到 Scrapy 框架是有兩個中間件。
一個是 Downloader 中間件,它是 Engine 和 Downloader 的樞紐。主要負責處理 Downloader 傳遞給 Engine 的 responses;
另一個是 Spider 中間件,它Spider 中間件是 Engine 和 Spider 的連接橋梁;它主要是處理 Spider 的輸入(responses) 以及輸出 item 和 requests 給 Engine;
在 Scrapy 框架中,Downloader 中間件和 Spider 中間件都是支持自定義擴展。在實際應用中,我們經常需要對 Downloader 中間件進行制定化。例如實現一個 User-Agent 中間件給每個 HTTP 請求的頭部增加隨機篩選的 User-Agent 屬性;或者實現一個代理中間件給每個 HTTP 請求設置隨機選擇的代理地址。
接下來,讓我們學習如何實現 Scrapy 的 Downloader 中間件。
1) 定義中間件
在 Scrapy 項目中,找到 middlewares.py 文件,在文件中創建自己的中間件類。例如,我創建一個代理中間件:
class ProxyMiddleware(object):
每個中間件一共有三個方法,分別是:
process_request(request,spider)
當每個 request 通過下載中間件時,該方法被調用。該方法必須返回以下三種中的任意一種:None,返回一個 Response 對象,返回一個 Request 對象或 raise IgnoreRequest。每種返回值的作用是不同的。
None: Scrapy 將會繼續處理該 request,執行其他的中間件的相應方法,直到合適的下載器處理函數( download handler )被調用,該 request 被執行(其 response被下載)。如果有多個中間件,其他的中間件可以通過返回 Null,然后指定對應的中間件去處理 request
Request 對象:Scrapy 則停止調用 process_request 方法并重新調度返回的 request。簡單來說是拒絕該 Request 的 HTTP 請求。
Response 對象:直接返回結果。
raise IgnoreRequest 異常:拋出異常,然后會被中間件的 process_exception() 方法會被調用。
process_response(request, response, spider)
process_response 的返回值也是有三種:Response 對象,Request對象,或者 raise 一個 IgnoreRequest 異常。
如果返回的結果是 Response, 該 response 會被在鏈中的其他中間件的 process_response() 方法處理。
如果的結果是 Request 對象,則中間件鏈停止,request 會被重新調度下載。
raise IgnoreRequest 異常: 拋出異常,然后會被中間件的 process_exception() 方法會被調用。。
process_exception(request, exception, spider)
當下載處理器(download handler)或 process_request() (下載中間件)拋出異常(包括 IgnoreRequest 異常)時,Scrapy 調用 process_exception()。
process_exception() 的返回結果同樣也是有三個: None、Response 對象、Request 對象。
如果其返回 None ,Scrapy 將會繼續處理該異常,接著調用已安裝的其他中間件的 process_exception() 方法,直到所有中間件都被調用完畢。
如果其返回一個 Response 對象,則其他中間件鏈的 process_response() 方法被調用,之后 Scrap y將不會調用其他中間件的 process_exception() 方法。
如果其返回一個 Request 對象, 則返回的request將會被重新調用下載。這將停止中間件的 process_exception() 方法執行,就如返回一個 response 的那樣。如果 HTTP 請求失敗,我們可以在這里對 HTTP 請求進行重試。例如我們頻繁爬取訪問一個網站導致被封 IP,就可以在這里設置增加代理繼續訪問。
我們可以不用實現全部方法,只需要根據需求實現對應的方法即可。例如,我想給每個 HTTP 請求都添加代理地址, 我實現 process_request() 即可。
class ProxyMiddleware(object):
# overwrite process request
def process_request(self, request, spider):
# 從數據庫中隨機讀取一個代理地址
proxy_address = proxy_pool.random_select_proxy()
logging.debug("===== ProxyMiddleware get a random_proxy:【 {} 】 =====".format(proxy_address))
request.meta['proxy'] = proxy_address
return None
2) 在 setting.py 啟用中間件
我們已經實現了中間件,最后一步需要啟用該中間件。我們將定義的中間件添加到 settings.py 文件。如果你是重載系統中間件,還需要將系統的中間件的值設置為 None。我前面定義的代理中間件,是需要對 HTTP 請求做操作。所以重載了 HttpProxyMiddleware 中間件。
# 中間件填寫規則
# yourproject.myMiddlewares(文件名).middleware類
# 設置代理
'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': None,
'scrapydemo.middlewares.ProxyMiddleware': 100
看完上述內容,你們掌握如何使用Scrapy 中間鍵的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。