Downloader Middlewares (下載器中間件)
下載器中間件是引擎和下載器之間通信的中間件。在這個(gè)中間件中我們可以設(shè)置代理、更換請(qǐng)求頭等來(lái)達(dá)到反反爬蟲的目的。要寫下載器中間件,可以在下載器中實(shí)現(xiàn)兩個(gè)方法。
process_request(self,request,spider),這個(gè)方法是在請(qǐng)求發(fā)送之前會(huì)執(zhí)行
process_ response(self ,request,response,spider),這個(gè)方法是數(shù)據(jù)下載到引擎之前執(zhí)行
process_ request(self,request,spider):
這個(gè)方法是下載器在發(fā)送請(qǐng)求之前會(huì)執(zhí)行的。一般可以在這個(gè)里面設(shè)置隨機(jī)代理ip等。
1.參數(shù):
request發(fā)送請(qǐng)求的request對(duì)象。spider發(fā)送請(qǐng)求的spider對(duì)象。
2.返回值:
返回
None:如果返回None, Scrapy將 繼續(xù)處理該request,執(zhí)行其他中間件中的相應(yīng)方法,直到合適的下載器處理函數(shù)被調(diào)用。返回
Response對(duì)象: Scrapy將不會(huì)調(diào)用任何其他的process. request方法,將直接返回這個(gè)response對(duì)象。
已經(jīng)激活的中間件的process_ response()方法則會(huì)在每個(gè)response返回時(shí)被調(diào)用。
- 返回
Request對(duì)象:不再使用之前的request對(duì)象去下載數(shù)據(jù),而是根據(jù)現(xiàn)在返回的request對(duì)象返回?cái)?shù)據(jù)。如果這個(gè)方法中拋出了異常,則會(huì)調(diào)用process. exception方法。
process_response(self,request,response,spider):
這個(gè)是下載器下載的數(shù)據(jù)到引擎中間會(huì)執(zhí)行的方法。
1.參數(shù):
request: request對(duì)象。response:被處理的response對(duì)象。spider: splder對(duì)象。
2.返回值:
返回
Response對(duì)象: 會(huì)將這個(gè)新的response對(duì)象傳給其他中間件,最終傳給爬蟲。返回
Request對(duì)象:下載器鏈被切斷,返回的request會(huì)重新被下載器調(diào)度下載。如果拋出一個(gè)異常,那么調(diào)用request的errback 方法,如果沒有指定這個(gè)方法,那么會(huì)拋出一個(gè)異常。
隨機(jī)請(qǐng)求頭中間件:
爬蟲在頻繁訪問(wèn)一個(gè)頁(yè)面的時(shí)候,這個(gè)請(qǐng)求頭如果一直保持一致。那么很容易被服務(wù)器發(fā)現(xiàn),從而禁止掉這個(gè)請(qǐng)求頭的訪問(wèn)。因此我們要在訪問(wèn)這個(gè)頁(yè)面之前隨機(jī)的更改請(qǐng)求頭,這樣才可以避免尼蟲被抓。隨機(jī)更改請(qǐng)求頭,可以在下載中間件中實(shí)現(xiàn)。在請(qǐng)求發(fā)送給服務(wù)器之前,隨機(jī)的選擇一一個(gè)請(qǐng)求頭。這樣就可以避免總使用一個(gè)請(qǐng)求頭了。示例代碼如下:
1.在middlewares.py里面編寫隨機(jī)請(qǐng)求頭中間件
請(qǐng)求頭可以去這個(gè)網(wǎng)站去找
http://www.useragentstring.com/pages/useragentstring.php?typ=Browser
class UserAgentDownloadMiddleware(object):
# user-agent 設(shè)置隨機(jī)的請(qǐng)求頭中間鍵
USER_AGENTS = [
'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko',
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.21pre) Gecko K-Meleon/1.7.0',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows XP 5.1) Lobo/0.98.4',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.28) Gecko/20120410 Firefox/3.6.28 '
]
def process_request(self, request, spider):
# random.choice()在列表中隨機(jī)選擇一個(gè)
user_agent = random.choice(self.USER_AGENTS)
request.headers['User-Agent'] = user_agent
- 寫好中間件之后記得要在
settings.py調(diào)用
DOWNLOADER_MIDDLEWARES = {
'useragent_demo.middlewares.UserAgentDownloadMiddleware': 543,
}