简单的一个响应码处理中间件
在HTTP协议中,响应状态码 429 Too Many Requests 表示在一定的时间内用户发送了太多的请求,即超出了“频次限制”。
在响应中,可以提供一个 Retry-After 首部来提示用户需要等待多长时间之后再发送新的请求。
服务器不主动拒绝请求,不封ip,但是会限制请求频率,所有我们要尊重服务器的设置,适当降低请求频率,不要试图解决它。
们可以修改scrapy的中间件,以便收到错误时暂停。等待一会儿后再继续执行爬虫。
from scrapy.downloadermiddlewares.retry import RetryMiddleware from scrapy.utils.response import response_status_message import time class TooManyRequestsRetryMiddleware(RetryMiddleware): def __init__(self, crawler): super(TooManyRequestsRetryMiddleware, self).__init__(crawler.settings) self.crawler = crawler @classmethod def from_crawler(cls, crawler): return cls(crawler) def process_response(self, request, response, spider): if request.meta.get('dont_retry', False): return response elif response.status == 429: self.crawler.engine.pause() time.sleep(60) # If the rate limit is renewed in a minute, put 60 seconds, and so on. self.crawler.engine.unpause() reason = response_status_message(response.status) return self._retry(request, reason, spider) or response elif response.status in self.retry_http_codes: reason = response_status_message(response.status) return self._retry(request, reason, spider) or response return response
在请求出现429的时候,我们的程序将会停止运行,根据设置的等待时间开始等待,我这里设置的时60s,当然你也可以设置得更久。
添加429以重试代码 settings.py
RETRY_HTTP_CODES = [429] DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.retry.RetryMiddleware': None, 'xx.middlewares.TooManyRequestsRetryMiddleware': 543, }