在Scrapy中,异常处理是非常重要的一部分,它可以确保我们的爬虫程序在遇到意外错误时不会崩溃并停止工作。一些常见的异常包括:超时异常、下载异常、解析异常等等。在这里,我们将提供一份攻略,介绍如何在Scrapy中捕获并处理各种异常。
1. 下载中间件
Scrapy的下载中间件Middleware提供了处理异常的机制。可以通过编写自定义的中间件来捕获并处理异常。其中,建议在下载中间件中添加处理异常的代码,因为在下载过程中抛出的异常,大多数都是由于传输或连接错误(如超时和网络错误)导致的。以下是一个自定义下载中间件捕获所有下载异常的示例:
from scrapy import signals
from scrapy.exceptions import NotConfigured, IgnoreRequest
class DownloadErrorMiddleware(object):
@classmethod
def from_crawler(cls, crawler):
if not crawler.settings.getbool('MYEXT_ENABLED'):
raise NotConfigured
ext = cls()
crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)
return ext
def process_request(self, request, spider):
return None
def process_response(self, request, response, spider):
if response.status_code == 404: # 捕获HTTP错误
raise IgnoreRequest("Not Found: {}".format(response.url))
if response.status_code == 500: # 捕获HTTP错误
raise IgnoreRequest("Internal Server Error: {}".format(response.url))
return response
def process_exception(self, request, exception, spider):
if isinstance(exception, ConnectionRefusedError) # 捕获连接错误
raise IgnoreRequest("Connection Refused: {}".format(request.url))
if isinstance(exception, TimeoutError): # 捕获超时错误
raise IgnoreRequest("Timeout: {}".format(request.url))
if isinstance(exception, DownloadError): # 捕获下载错误
raise IgnoreRequest("Download Error: {}".format(request.url))
return None
def spider_closed(self, spider):
pass
2. 重试下载策略
另一种常见的方法是使用Scrapy内置的下载重试中间件RetryMiddleware。它可以重试下载多次,直到达到最大重试次数(由重试中间件设置的值)。 但值得注意的是,在通过配置RetryMiddleware时,如果设置了过低的重试次数(比如1或2),可能会导致爬虫在遇到可恢复的异常情况(如网络延迟)时过早地中止。
以下是一个关于如何配置RetryMiddleware的示例:
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.retry.RetryMiddleware': True,
}
RETRY_ENABLED = True # 是否开启重试
RETRY_TIMES = 5 # 重试次数
RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 408] # 重试的HTTP状态码
其中,RETRY_HTTP_CODES是最值得关注的选项之一。它的值应设置为需要重试的HTTP状态码列表。 Scrapy默认只在遇到HTTP状态码为500、502、503、504时进行重试。如果网站返回的实际状态码与RETRY_HTTP_CODES设置不同,则不会重试。
综上所述,在Scrapy中我们可以通过编写自定义下载中间件来捕获并处理各种异常,在下载重试中间件RetryMiddleware的帮助下实现重试下载,这样可以更好地为我们的爬虫程序提供异常处理机制,从而在爬取数据时实现更为健壮的程序。