scrapy框架官方圖如下
基本流程是
1.spider發(fā)出初始request需求阳掐,默認(rèn)是對(duì)start_urls發(fā)起get方法的request始衅,如果帶參數(shù)或者post就重寫start_requests(def start_requests(self):)
經(jīng)過(guò)spider middlewears的process_start_requests(self, start_requests, spider),準(zhǔn)備向服務(wù)器發(fā)起訪問(wèn)锚烦。
2.這時(shí)會(huì)經(jīng)過(guò)downloader middlewears的process_request(request, spider)觅闽,這里的中間件優(yōu)先級(jí)會(huì)比setting里的高,比如訪問(wèn)時(shí)要帶上特別的headers涮俄,user-agent蛉拙,proxy,cookies之類都在process_request中間件里定義彻亲。
3.得到response之后會(huì)經(jīng)過(guò)downloader middlewears的process_response(self, request, response, spider)孕锄,結(jié)果必須是其中之一
# - return a Response object
# - return a Request object
# - or raise IgnoreRequest
然后再經(jīng)過(guò)spider middlewears的process_spider_input(self, response, spider)這個(gè)中間件結(jié)果只能是none或者拋出異常。
經(jīng)過(guò)兩個(gè)中間件之后進(jìn)入spider進(jìn)行頁(yè)面解析苞尝,得到item或者一系列新的帶爬url畸肆,
4.item經(jīng)中間件process_spider_output(self, response, result, spider):此中間件必須返回an iterable of Request, dict or Item objects.
然后進(jìn)入pipeline進(jìn)行數(shù)據(jù)清洗下載。
spider返回的是url則經(jīng)中間件后又進(jìn)入scheduler排隊(duì)帶爬宙址。
我倒是覺(jué)得這個(gè)圖說(shuō)的更明白
當(dāng)然轴脐,我省去了scrapy engine,它是調(diào)度抡砂,所有request大咱,response及產(chǎn)生的數(shù)據(jù)都會(huì)經(jīng)他之手。
中間件
SpiderMiddleware主要處理解析Item的相關(guān)邏輯修正注益,比如數(shù)據(jù)不完整要添加默認(rèn)碴巾,增加其他額外信息等。
DownloaderMiddleware主要處理請(qǐng)求Request發(fā)出去和結(jié)果Response返回的一些回調(diào)丑搔,
上文其他未提及的中間件還有:SpiderMiddleware中的
process_spider_exception(self, response, exception, spider):
downloader middlewears中的
process_exception(self, request, exception, spider):可以處理超時(shí)
看名字就知道這是兩個(gè)異常中間件厦瓢。
downloader middlewears詳細(xì)說(shuō)明:
process_request(request,spider)
當(dāng)每個(gè)request通過(guò)下載中間件時(shí),該方法被調(diào)用啤月,這里有一個(gè)要求煮仇,該方法必須返回以下三種中的任意一種:None,返回一個(gè)Response對(duì)象,返回一個(gè)Request對(duì)象或raise IgnoreRequest谎仲。三種返回值的作用是不同的欺抗。
None:Scrapy將繼續(xù)處理該request,執(zhí)行其他的中間件的相應(yīng)方法强重,直到合適的下載器處理函數(shù)(download handler)被調(diào)用,該request被執(zhí)行(其response被下載)绞呈。
Response對(duì)象:Scrapy將不會(huì)調(diào)用任何其他的process_request()或process_exception() 方法贸人,或相應(yīng)地下載函數(shù);其將返回該response佃声。 已安裝的中間件的 process_response() 方法則會(huì)在每個(gè)response返回時(shí)被調(diào)用艺智。
Request對(duì)象:Scrapy則停止調(diào)用 process_request方法并重新調(diào)度返回的request。當(dāng)新返回的request被執(zhí)行后圾亏, 相應(yīng)地中間件鏈將會(huì)根據(jù)下載的response被調(diào)用十拣。
raise一個(gè)IgnoreRequest異常:則安裝的下載中間件的 process_exception() 方法會(huì)被調(diào)用。如果沒(méi)有任何一個(gè)方法處理該異常志鹃, 則request的errback(Request.errback)方法會(huì)被調(diào)用夭问。如果沒(méi)有代碼處理拋出的異常, 則該異常被忽略且不記錄曹铃。
process_response(request, response, spider)
可以看返回是否是200加入重試機(jī)制
process_response的返回值也是有三種:response對(duì)象缰趋,request對(duì)象,或者raise一個(gè)IgnoreRequest異常
如果其返回一個(gè)Response(可以與傳入的response相同陕见,也可以是全新的對(duì)象)秘血, 該response會(huì)被在鏈中的其他中間件的 process_response() 方法處理。
如果其返回一個(gè) Request 對(duì)象评甜,則中間件鏈停止灰粮, 返回的request會(huì)被重新調(diào)度下載。處理類似于 process_request() 返回request所做的那樣忍坷。
如果其拋出一個(gè) IgnoreRequest 異常粘舟,則調(diào)用request的errback(Request.errback)。 如果沒(méi)有代碼處理拋出的異常佩研,則該異常被忽略且不記錄(不同于其他異常那樣)柑肴。
參考:
https://www.cnblogs.com/x-pyue/p/7795315.html
https://www.colabug.com/2119457.html
https://www.cnblogs.com/zhaof/p/7198407.html
https://blog.csdn.net/xnby/article/details/52297047