Scrapy 代理中间件:Request 与 None 返回值
在给 Scrapy 分配代理后交还控制权,而不是在下载前无意中把同一个请求重新排队。
日志里代理地址变了。目标站点却从未出现在代理的访问日志里。检查你的中间件是否真的让请求到达了下载器。
在 Scrapy 的下载器中间件中,返回一个 Request 意味着把该请求重新排队。它的意思不是“带着我刚改过的元数据继续发送这个对象”。
对于只负责选择线路的选择器,正确的形式是:
def process_request(self, request):
request.meta['proxy'] = self.choose_proxy()
return None
这段代码展示的是当前的钩子写法;请使用已安装的 Scrapy 版本所支持的中间件接口。选择器必须返回一个有效的端点,并显式处理不可用的池。允许公共中转的公开抓取可以为该返回值从HTTP 代理列表中获取 HTTP 候选。
返回 None 会让其余请求中间件和下载器继续执行。返回另一个 Request 在你确实要替换或重试任务时才有用,但它需要理由和退出条件。
每次返回同一个请求的轮换器可能反复运行自己的选择代码,却始终没有建立到目标的连接。调高超时或开更多代理端口都无法修复那个控制流循环。
把中间件入口、返回行为和第一次真正的网络尝试当作独立事件来观察。写着“已选定代理”的日志行只能证明选择器运行过,并不能证明使用所选端点发出了请求。