參考文獻(xiàn):https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
1.Downloader Middleware調(diào)用
1.1Downloader Middleware調(diào)用方法
DOWNLOADER_MIDDLEWARES設(shè)置中,以字典的形式進(jìn)行,key是Middleware的路徑,value是代表Middleware的優(yōu)先級(jí)的數(shù)字。例:
DOWNLOADER_MIDDLEWARES = {
? ? 'myproject.middlewares.CustomDownloaderMiddleware': 543,
}
1.2優(yōu)先級(jí)順序介紹
process_request()是根據(jù)優(yōu)先級(jí)的升序(從小到大)進(jìn)行調(diào)用。
process_response()是根據(jù)優(yōu)先級(jí)的降序(從大到小)進(jìn)行調(diào)用。
2.Downloader Middleware內(nèi)置方法
1.1process_request(request, spider)
? 返回值:None,則繼續(xù)處理該request,并按順序執(zhí)行其他Middleware中的process_request()方法,直到返回response。
? 返回值:Request,停止后續(xù)(優(yōu)先級(jí)更低的)Middleware中的process_request()對(duì)request進(jìn)行處理,并把Request作為全新的Request返回調(diào)度隊(duì)列。
? 返回值:Response,停止后續(xù)的process_request()和process_exception(),并按序調(diào)用process_response(),直到將Response返回給Spider處理。
? 返回值:IgnoreRequest,調(diào)用process_exception()處理,如果沒(méi)有process_exception()處理將會(huì)調(diào)用errback()函數(shù),若無(wú)errback()處理,則忽略。
1.2process_response(request, response, spider)
? 返回值:Response,繼續(xù)處理該response,并按序執(zhí)行其他Middleware中的process_response()方法.
? 返回值:Request,停止后續(xù)Middleware中的process_process()對(duì)response進(jìn)行處理,并把Request作為全新的Request返回調(diào)度隊(duì)列。
? 返回值:IgnoreRequest,調(diào)用errback()函數(shù),若無(wú)errback()處理,則忽略。
1.3process_exception(request, exception, spider)
? 返回值:None,則繼續(xù)處理該exception,并按順序執(zhí)行其他Middleware中的process_exception()方法。
? 返回值:Response,停止后續(xù)Middleware中的process_exception()對(duì)exception進(jìn)行處理,并按序調(diào)用process_response()。
? 返回值:Request,停止后續(xù)Middleware中的process_exception()對(duì)exception進(jìn)行處理,并把Request作為全新的Request返回調(diào)度隊(duì)列。
3.CookiesMiddleware
3.1CookiesMiddleware介紹
保持同一次會(huì)話,類似requests包中的requests.session()方法。
3.2CookiesMiddleware使用
def parse(self, response):
? ? for i, url in enumerate(urls):
? ? ? ? yield scrapy.Request(url, meta={'cookiejar': i},callback=self.parse_page)
def parse_page(self, response):
? ? # do some processing
? ? return scrapy.Request("http://www.example.com/otherpage",
? ? ? ? ? ? ? ? ? ? ? ? ? meta={'cookiejar': response.meta['cookiejar']},
? ? ? ? ? ? ? ? ? ? ? ? ? callback=self.parse_other_page)
解釋:拋出請(qǐng)求時(shí)通過(guò)給meta中的cookiejar賦值,一種標(biāo)識(shí)一種會(huì)話保持,默認(rèn)為一種。
4.DownloadTimeoutMiddleware
從Spider對(duì)象中獲取DownloadTimeout屬性,并對(duì)request.meta賦值。
5.HttpAuthMiddleware
從Spider對(duì)象中獲取username和password,并檢查request.headers["Authorization"]是否存在,若不存在則對(duì)其賦值。
request.headers["Authorization"] = “{}:{}”.format(username, password)
6.DefaultHeadersMiddleware
添加scrapy默認(rèn)請(qǐng)求頭
7.HttpProxyMiddleware
? 通過(guò)request.meta["proxy"]添加代理。
? 通過(guò)request.meta["Proxy-Authorization"]進(jìn)行Basic認(rèn)證。
8.RedirectMiddleware
? handle_httpstatus_list = [301, 302] 忽略狀態(tài)碼為301,302的重定向
? 可以通過(guò)request.meta查看重定向的原因。
9.MetaRefreshMiddleware
從網(wǎng)頁(yè)中獲取http-equiv屬性中的重定向鏈接以及重定向延時(shí),自動(dòng)進(jìn)行重定向。
10.RetryMiddleware
? 設(shè)置需要重試的狀態(tài)碼:RETRY_HTTP_CODES=[500, 502, 503, 504, 522, 524, 408]
? 默認(rèn)為重試次數(shù)為retry_times=2。
? 可以通過(guò)request.meta["max_retry_times"]設(shè)置某個(gè)請(qǐng)求的最大重試次數(shù)。
11.RobotsTxtMiddleware
? 過(guò)濾robots協(xié)議,作用類似于setting文件中的ROBOTSTXT_OBEY
? 使用方法:request.meta["dont_obey_robotstxt"]
12.UserAgentMiddleware
給request.headers['User-Agent']屬性進(jìn)行賦值,通過(guò)采用random.choice()方法獲取隨機(jī)值。
13.HttpCompressionMiddleware
很多網(wǎng)站會(huì)對(duì)資源進(jìn)行壓縮,以加快網(wǎng)頁(yè)響應(yīng)速率。

HttpCompressionMiddleware不需要在開(kāi)發(fā)時(shí)進(jìn)行任務(wù)操作,其底層已經(jīng)封裝好了,會(huì)自動(dòng)獲取網(wǎng)頁(yè)壓縮方式,并對(duì)其進(jìn)行解壓。
如果關(guān)閉HttpCompressionMiddleware,會(huì)出現(xiàn)亂碼。


通過(guò)response.body可以看見(jiàn),返回的內(nèi)容是亂碼。再使用response.text可以看見(jiàn)已經(jīng)報(bào)錯(cuò)。