Scrapy中response.follow传入response.url时回调不触发问题
Scrapy同页回调未触发问题解决方案
问题原因
你写的同URL请求不触发parse_menu回调,核心原因是Scrapy默认开启重复请求过滤机制:当前地址response.url已经完成过一次请求,框架会默认把后续指向同一地址的请求判定为重复爬取内容,直接过滤丢弃,根本不会走到下载、触发回调的流程,无论使用response.follow还是手动构造scrapy.Request都会被该规则拦截。
另外这个实现思路本身存在冗余:你需要处理的是已经加载完成的当前页数据,重新发起HTTP请求只会额外消耗带宽和爬虫性能,完全没有必要。
正确实现方式
方案1:直接调用回调函数(优先推荐,零额外开销)
不需要构造新请求,直接把当前响应对象作为参数传入parse_menu,通过yield from迭代交付结果即可,代码如下:
# 复用已拿到的当前页响应,无额外网络请求 yield from self.parse_menu(response)
parse_menu本身是生成器函数,yield from会直接把它产出的Item、后续爬取请求交给Scrapy引擎处理,执行逻辑和正常请求触发的回调完全一致,是当前场景下的最优写法。
方案2:强制发起重复请求(仅特殊场景使用)
如果确实有重新请求当前页的需求(比如页面内容动态更新,需要拉取最新数据),可以在构造请求时传入dont_filter=True参数,告诉框架跳过这个请求的去重校验:
# response.follow 写法 yield response.follow( url=response.url, callback=self.parse_menu, dont_filter=True ) # 手动构造Request写法 from scrapy import Request yield Request( url=response.url, callback=self.parse_menu, dont_filter=True )
注意:非必要不要开
dont_filter,该参数会关闭当前请求的去重逻辑,如果回调里存在循环指向当前地址的代码,会触发无限爬取同一地址的问题,白白消耗资源。
内容的提问来源于stack exchange,提问作者Danf
相关产品推荐
相关产品推荐

