对于下载中间件
settings里的数字大小:
- process_request的顺序 数字越小,越先调用
- process_response 的顺序, 数字越大,越先调用
返回值:
process_request: 【None :继续调用下一个中间件的process_request方法;】
【Response object:预示着下载已经完成,就以返回的response作为下载结果,进而开始调用 process_response方法】
【Request object: 将这个请求request添加到任务队列中,当前的request的process_request流程就结束了,没有其他操作了】
【抛出IgnoreRequest异常:将调用process_exception(),process_exception()如果没有处理该异常,则会继续调用errback来处理,如果errback
中也没有对它处理的,就会忽视该异常】
process_response : 【Response :这个response可以是传过来的response,也可以是一个新的response,将继续调用下一个process_response】
【Request :这个request将被添加到请求队列,然后该response的process_response流程就结束了】
【抛出IgnoreRequest异常:将调用request.errback方法处理,如果该方法中没有对此异常进行处理,此异常 将被忽视】
process_exception : 【None : 继续调用其他process_exception处理这个异常】
【Response object:开始调用process_response方法】
【Request object: 此request将被添加到请求队列,process_exception流程就结束了】
process_exception是在下载处理器(download handler)或下载中间件的process_request抛出异常时被调用的。
from_crawler : 这个方法是scrapy的核心属性的一个入口,用于创建中间件实例 。如果需要用到signals,settings,spiders等,可以通过crawler.settings这种操作来
获取, cls(crawler.stats)是调用这个方法所在的class来实例化一个对象,crawler.stats相当于传给__init__(self,stats)的参数stats
@classmethod
from_crawler(cls,crawler):
instance = cls(crawler.stats)
return instance
自定义retry中间件
from scrapy.downloadermiddlewares.retry import RetryMiddleware
import time
class CustomRetryMiddleware(RetryMiddleware):
def __init__(self,settings):
self.request_error = 0
super(CustomRetryMiddleware, self).__init__(settings)
def process_response(self, request, response, spider):
if request.meta.get('dont_retry', False):
return response
if response.status in self.retry_http_codes:
if response.status==429: #在这里可以添加一些逻辑,在重试请求之前,
spider.logger.info("[response]retry Middleware,Got 429 error,would stop 6 minutes,%s",request.url)
time.sleep(60*6)
spider.logger.info("[response]Retry Middleware ,response.status :%d,will start retry request,%s",response.status,request.url)
reason = response_status_message(response.status)
return self._retry(request, reason, spider) or response
return response
def process_exception(self, request, exception, spider):
if isinstance(exception, self.EXCEPTIONS_TO_RETRY) \
and not request.meta.get('dont_retry', False):
spider.logger.info("[exception]Retry Middleware ,exception :%s,will start retry request,%s",exception,request.url)
#返回一个request,到schedule中,等待下载,从重新走所有的middleware。
return self._retry(request, exception, spider)
要启用自定义的retry middleware ,需要将默认的RetryMiddleware设置为None
'DOWNLOADER_MIDDLEWARES' :{
'dayspider.middlewares.my_retry_middleware.CustomRetryMiddleware': 550,'scrapy.downloadermiddlewares.retry.RetryMiddleware' : None,},
下载异常
- 像是 响应超时,网络连接异常, forbidden 502这类的没有response的异常 直接被process_exception 捕获
- 像是 429(请求太频繁,403(禁止访问)500(服务器端返回一个表示错误的代码),有收到response的异常,可以用process_response进行处理