Scrapy 爬虫中的异常处理:如何处理 HTTP 错误和重定向?
在 Scrapy 爬虫中,我们可以使用中间件(Middleware)来处理 HTTP 错误和重定向。中间件是一种可以在请求和响应之间进行处理的组件。Scrapy 提供了一些内置的中间件来帮助我们处理 HTTP 错误和重定向。
首先,我们需要开启 Scrapy 的异常处理和重定向功能。在 settings.py 文件中添加以下配置:
HTTPERROR_ALLOWED_CODES = [404, 403] # 允许处理的 HTTP 错误码 REDIRECT_ENABLED = True # 开启重定向功能
然后,我们可以编写一个中间件来处理 HTTP 错误和重定向:
from scrapy import signals from scrapy.exceptions import IgnoreRequest, NotConfigured class HttpErrorAndRedirectMiddleware: @classmethod def from_crawler(cls, crawler): middleware = cls() crawler.signals.connect( middleware.spider_error, signal=signals.spider_error) return middleware def spider_error(self, failure, response, spider): if response is not None: # 处理 HTTP 错误 if response.status in self.settings.getlist('HTTPERROR_ALLOWED_CODES'): spider.logger.info('[Error] Ignoring response %s, code=%d', response.url, response.status) return None # 处理重定向 if response.status in [301, 302, 303, 307]: redirected_url = response.headers.get('Location').decode('utf-8') spider.logger.info('[Redirect] Redirecting %s to %s', response.url, redirected_url) new_request = response.request.replace(url=redirected_url) return new_request else: raise IgnoreRequest('[Error] Failure %s' % failure) def process_exception(self, request, exception, spider): if isinstance(exception, IgnoreRequest): spider.logger.info('[Error] Ignoring request %s', request.url) return None return request
在上面的代码中,我们定义了一个类 HttpErrorAndRedirectMiddleware,它实现了 Scrapy 的中间件接口。其中:
- from_crawler() 方法是 Scrapy 的钩子方法,用于获得 Scrapy 的设置和信号。在这个方法中,我们注册了一个 spider_error 信号,它会在爬虫遇到错误时被触发。
- spider_error() 方法接收一个 failure 对象、一个响应对象和一个 Spider 对象。其中,failure 对象是一个 Twisted 的 Failure 对象,它表示了错误的信息;响应对象是响应的信息;Spider 对象是爬虫对象。
- 如果响应对象不是 None,并且响应的状态码在允许处理的 HTTP 错误码范围内,那么我们就将其忽略;
- 如果响应对象不是 None,并且响应的状态码是重定向状态(301、302、303、307),那么我们就获取重定向的目标 URL,并创建一个新的请求对象,将其发送到新的 URL;
- 如果响应对象是 None,那么我们就抛出一个 IgnoreRequest 的异常,表示这个请求被忽略。
- process_exception() 方法是 Scrapy 的中间件接口方法,用于处理异常。在这个方法中,我们判断异常是否是 IgnoreRequest,如果是,那么我们就忽略这个请求,否则我们就将异常传递给下一个中间件。
最后,我们在 settings.py 文件中设置中间件:
DOWNLOADER_MIDDLEWARES = { 'myproject.middlewares.HttpErrorAndRedirectMiddleware': 100, }
这样,我们就成功地处理了 Scrapy 爬虫中的 HTTP 错误和重定向。下面是一个简单的演示:
import scrapy class PidancodeSpider(scrapy.Spider): name = 'pidancode' allowed_domains = ['pidancode.com'] start_urls = ['http://www.pidancode.com/'] def parse(self, response): raise scrapy.exceptions.CloseSpider('Test close spider with error')
在这个演示中,我们将爬虫的起始 URL 设置为 pidancode.com,然后在 parse() 方法中抛出了一个异常。如果我们没有创建上面的中间件来处理异常,那么这个异常会导致整个爬虫停止,我们将无法获得任何数据。但如果使用了我们创建的中间件,这个异常会被忽略,爬虫会继续运行。
以上就是 Scrapy 爬虫中处理 HTTP 错误和重定向的详细讲解,以及相应的代码演示。
相关文章