前言:
首先,确保大家都明白,无论我们做得多么小心,异常情况在爬虫中总会发生。比如说,服务器可能会突然宕机,或者页面结构变了导致我们的爬虫拿不到正确的数据。这就是为什么记录异常非常关键,这样当事情不按计划发生时,我们可以回过头去看看出了什么问题。
正文:
1.重试机制(用一个运维的例子来说明):
就像是,当你去银行取钱,假设ATM机出了问题,你不会立马放弃吧,你可能会再试一次。同样,如果我们的爬虫在抓取数据时遇到问题,我们也要让它重试几次。在Scrapy中,设置这个其实超简单,只需要在settings.py里设置RETRY_TIMES这个变量,例如设为2,就像给ATM机两次机会一样。
----要实现这个需求,首先需要为Scrapy爬虫添加重试机制
在 `settings.py` 文件中,设置重试次数。添加或修改以下设置:
# 设置失败时重试的次数,默认是2
RETRY_TIMES = 2
这样就行了,剩余的交给scrapy自己去处理!
2. 要捕获异常并生成txt报告,需要自定义中间件。
自定义中间件(这里可以用个报告问题的例子):
比如说,当你发现项目中出现问题时,你需要填写一个异常报告,方便日后的跟踪和修复。在Scrapy中,我们通过创建一个名为ExceptionLoggingMiddleware的中间件来做这件事。无论是因为请求失败了,还是出了别的什么状况,只要有什么事情偏离了正轨,这个中间件就会记录下所有细节,包括哪个URL出问题了,错误的状态是什么,然后把这些信息存进一个error_report.txt,就好比异常的档案文件。
在 `middlewares.py` 文件中(如果不存在,则需要创建该文件,并在 `settings.py` 中启用它),添加一个新的中间件类:
from scrapy import signals
import logging
class ExceptionLoggingMiddleware:
def process_response(self, request, response, spider):
# 如果响应是异常的
if response.status != 200: # Or use any other criteria for error
logging.error(f"Error! Response Status: {response.status}, URL: {response.url}")
with open("error_report.txt", "a") as file:
file.write(f"Error! Response Status: {response.status}, URL: {response.url}\n")
return response
def process_exception(self, request, exception, spider):
logging.error(f"Exception caught: {exception}, URL: {request.url}")
with open("error_report.txt", "a") as file:
file.write(f"Exception caught: {exception}, URL: {request.url}\n")
# 回到重试中间件
return None
然后在 `settings.py` 文件中启用中间件:
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.ExceptionLoggingMiddleware': 540,
}
确保 `process_item` 方法在 `pipelines.py` 中处理异常,并正确地返回 `Request` 或 `Item` 对象。如果返回的是 `Request` 对象,Scrapy 会重新爬取该请求。
注:有些异常并不会经过 `process_exception` 方法,特别是那些在下载器中间件发生的异常(如连接错误)。
补充:
当你在设置的时候,就会发现有两个中间件:
DOWNLOADER_MIDDLEWARES和SPIDER_MIDDLEWARES
# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
SPIDER_MIDDLEWARES = {
"ip_pool.middlewares.IpPoolSpiderMiddleware": 543,
}
# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
"ip_pool.middlewares.IpPoolDownloaderMiddleware": 543,
"ip_pool.middlewares.ExceptionLoggingMiddleware": 544,
}
那么他们之间的区别是什么呢?
区别DOWNLOADER_MIDDLEWARES和SPIDER_MIDDLEWARES(这里可以用赛车比喻):
想象一下,Scrapy就像一辆赛车:
DOWNLOADER_MIDDLEWARES----好比是赛车的发动机和底盘,负责确保赛车(也就是我们的请求)能够顺利的从起点(发送请求)前进到终点(获取响应)。它们允许你控制请求的发送,比如改变油门深度(设置代理),或者调整方向盘(修改请求头)。
SPIDER_MIDDLEWARES----就像是赛车的导航团队和战术管理,它们处理从终点回到赛车队的数据(响应),并确保数据信息正确无误地被分析,并且转换成为有用的洞察(解析出来的Items),以便赛车队可以利用这些信息做出战略决策。
**DOWNLOADER_MIDDLEWARES**:
这些中间件作用于Scrapy的Downloader,即发送HTTP请求之前和接收HTTP响应之后的时刻。它们允许处理(修改、丢弃、重定向)请求和响应。
重要的用处包括:
- 设置代理服务器
- 修改User-Agent或其他请求头
- 自动重定向处理
- 请求/响应重写,如填充默认表单数据
- 请求重试,捕获并处理下载过程中的异常
**SPIDER_MIDDLEWARES**:
这些中间件作用于Spider,即响应传递给Spider解析之前以及Spider解析出来的数据项(Items)和新的请求(Requests)返回给引擎之后的时刻。
主要用于:
- 修改进入Spider的响应
- 修改从Spider出来的结果(Items和Requests)
- 捕获Spider处理过程中的异常
- 收集统计数据
- 扩展Spider进行请求的深度限制或宽度优先/深度优先排序