Scrapy爬蟲框架第五講(linux環境)【download middleware用法】


DOWNLOAD MIDDLEWRE用法詳解

                             

通過上面的Scrapy工作架構我們對其功能進行下總結:

(1)、在Scheduler調度出隊列時的Request送給downloader下載前對其進行修改

(2)、在下載生成后的Response發送給Spider並在Spider對其解析之前對其修改

【這里我們將scheduler spiders downloader middlewares downloader看作四個小伙伴做游戲進一步進行理解 】

(1)scheduler對spider說:請把request給我,spiders收到信息后,就說這是我的request,拿去吧

(2)scheduler收到request后要去找名叫downloader的小伙伴才能去服務器上下載數據,

(3)這時,名叫downloader middlewares的小伙伴跳出來說,得怎么沒我什么事了,於是它站在了scheduler和downloader中間,憤恨地說出了自己的價值(我可以對scheduler你的request進行如增加http header信息,增加proxy信息,重定向,失敗重試等操作!)


Scrapy框架提供了多種內置的downloader middleware(摘自http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html#topics-downloader-middleware-ref,小伙伴們了解即可)

'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware':100,【該中間件過濾所有robots.txt eclusion standard中禁止的request。】
'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware':200,【該中間件完成某些使用 Basic access authentication (或者叫HTTP認證)的spider生成的請求的認證過程。】
'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware':300,【該中間件設置 DOWNLOAD_TIMEOUT 指定的request下載超時時間.】
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware':400,【該中間件設置 DEFAULT_REQUEST_HEADERS 指定的默認request header】
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware':500,【用於覆蓋spider的默認user agent的中間件,要使得spider能覆蓋默認的user agent,其 user_agent 屬性必須被設置。】

'scrapy.downloadermiddlewares.retry.RetryMiddleware':600,【該中間件將重試可能由於臨時的問題,例如連接超時或者HTTP 500錯誤導致失敗的頁面。】
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware':650,【該中間件根據meta-refresh html標簽處理request重定向。】
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware':700,【該中間件提供了對壓縮(gzip, deflate)數據的支持】
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware':750,【該中間件根據response的狀態處理重定向的request。】
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware':800,【該中間件使得爬取需要cookie(例如使用session)的網站成為了可能。 其追蹤了web server發送的cookie,並在之后的request中發送回去, 就如瀏覽器所做的那樣】
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware':850,【該中間件提供了對request設置HTTP代理的支持。您可以通過在 Request 對象中設置 proxy 元數據來開啟代理。】


 

這里給小伙伴們普及一個概念:我們發現在每個內置中間件后面都跟了數字:這些數字是什么意思呢?

答:我們以食堂吃飯為例,就以我們學校二食堂,你去打飯正值中午11.50,這時你會發現人多到你想罵娘,所有你需要排隊等候,我們以此類比,你打的飯菜就相當於request請求,當你需要將request請求送給download組件(你成功打到飯菜)前你需要排隊,在這數字越小說明你在隊伍中的位置越靠前,即你的優先級越高,而數字越大的人排的越靠后就可能吃不到飯了,小伙伴們明白了沒?   


Scrapy框架不僅定義了自己的中間件,我們還可以根據需要進行自我定義:

class scrapy.downloadermiddlewares.DownloaderMiddleware

這里我們定義自己的downloader middleware ,而每個類都定義了一個或多個方法,我們介紹以下三個核心的方法:

(1)、process_request(request,spider) 【參數一:request (Request 對象) –即待處理的request對象 /參數二:spider (Spider 對象) – 該request對應的spider】

方法分析:

該方法在request被引擎調度給downloader之前被調用

該方法有4種返回結果:我們依次來分析:
(1)、返回None:

此時scrapy會繼續處理該Request,即不同的Downloader middleware 按優先級的順序修改該Request,並送給Downloader執行

(2)、返回Response:

此時scrapy不會再執行其他的process_request和process_exception方法,並調用Downloader middleware的每個process_response方法,將Request送給spider組件

(3)、返回Request對象

此時scrapy會返回process_request方法並重新執行(即重試),直到新的Request被執行,才返回Response

(4)、返回IgnoreRequest異常

此時會依次執行Downloader middleware的process_exception方法,如果process_exception方法無法解決,那么就會回調Request的errback方法,如果還無法解決,那么該異常就會被忽略


 

下面我們來打個比方幫助小伙伴們理解下上面四種放回情況:

我們以去食堂吃飯為例:(1)、就是你拿着飯卡成功打到了飯菜(2)、你拿着飯卡去打飯,食堂阿姨給了你一袋子東西(但遺憾的是這不是飯菜,即你打了假飯菜(3)、你拿着飯卡去打飯,食堂阿姨說你可能拿了假飯卡,重新去排隊打飯吧(4)、你拿着飯卡去打飯,食堂阿姨直接把你忽略了


 

小伙伴們明白了嗎?如果有問題,不要着急,我們接着往下看:
該方法使用實例分析:

下面小伙伴們讓我們使用process_request方法實現代理的設置(下面實驗是基於win10 pycharm中運行的 )

首先:啟動終端新建項目:scrapy startproject httpbintest

cd httpbinbest  ----scrapy genspider httpbin httpbin.org

接着:利用pycharm啟動項目

改寫httpbin.py

利用alt+f12啟動pycharm的terminal:執行命令:scrapy crawl httpbin

得到如下輸出:(這里我只貼出了部分)

這里我們可以看到成功爬取啦,小伙伴們我們注意到origin字段(這就是你本機電腦的ip,你可以把它復制進百度,一查,定位看看,這里我的是鎮江聯通)

下面我們要實現更換該ip來實現對網站的爬取(即偽裝自我)

打開:middleware.py並修改

這里小伙伴們可以上訊代理購買幾個i(本人發現系統代理需要輸密碼,所以出了9塊大洋買了幾個代理ip)【注釋:小伙伴們別忘了導入logging模塊】

這里我們返回值為None,具體什么意思參見上文

最后打開:settings.py(項目配置文件)啟動中間件

 

得到如下輸出:(這里我也只貼了部分)

小伙伴們我們可以將成功運行的ip百度一下,你會發現地址已換,我們成功實現了偽裝我們的ip進行爬取,是不是很有意思!


 

(2)、process_response(request,response,spider) 【參數一:Request對象 參數二:Response對象,即被處理的Response 參數三:Spider對象,即Response對應的Spider】

該方法返回四種結果,我們依次來分析:

(1)、返回Request對象

此時,優先級更低的Downloader Middleware 的process_response方法將不會被調用,該Request會重回隊列被process_request處理,即返回了上一個Request的(1)

(2)、返回Response對象

此時,將會執行更低優先級的process_response方法,繼續處理Response

(3)、返回IgnoreRequest異常

此時同Request的(4)

該方法使用實例分析

改寫middleware.py(這里我只貼出了部分)

改下httpbin.py

得到的輸出結果如下:

我們來分析下過程:downloader獲取Response之后經過middleware改寫,將原本的狀態嗎變成了206再傳給Response,所以我們得到的Response的狀態嗎成立206了

總結:process_response主要用來改寫你downloader返回的Response


 

(3)、process_exception(request,exception,spider)【參數一:產生異常的Request對象 參數二:即拋出的異常exception對象 參數三:Request對應的spider】----主要用來處理由process_request產生的異常

該方法返回三種結果,我們依次來分析下:

(1)、返回None

此時,更低優先級的Downloader  Middleware的process_exception方法將會被調用,直到所有的方法都被調度完畢【錯誤沒有被糾正】

(2)、返回Response

此時,更低優先級的Downloader Middleware的process_exception方法將不會被調用,而依次去執行所有中間件的process_response方法【錯誤被糾正了】

(3)、返回Request

此時,更低優先級的Downloader Middleware的process_exception方法將不會被調用,而依次去執行process_request方法【回爐重造了】


總結:

(1)Downloader Middlewares 由scrapy內置的middleware和你自己定義的middlewares組成

(2)如小伙伴不想使用scrapy內置的middlewares可以'scrapy.downloadermiddlewares.retry.RetryMiddleware':None,這樣就不啟用了

(3)各個middlewares后面的數字表示優先級,數字越小表明你的優先級越高(越遠離downloader即先進去后出來),數字越大表明優先級越低(越靠近downloader即后進去先出來)

(4)我們主要使用downloader middlewares 來改變User-Agent、設置代理、cookies等反反爬蟲機制(具體后面我們以實例詳談)

小伙伴們理解了嗎?

 

 

 

 

 

                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM