Scrapy爬虫过滤过度或重复抓取 不知如何设置dont_filter且翻页报KeyError
问题原因及修复方案
1. 翻页KeyError问题修复
该问题根源是parse_z方法中发起翻页请求时,没有将当前请求携带的分类、系列、型号等meta参数向下传递,导致下一页执行response.request.meta['model']这类取值代码时找不到对应key。
修复方式:修改parse_z中的翻页请求代码,完整传递meta参数:
# 位于parse_z方法末尾的翻页逻辑 if next_page: yield scrapy.Request( url=next_page_full, callback=self.parse_z, # 直接传递当前请求的完整meta参数即可 meta=response.meta )
2. 请求被过度过滤问题解决
日志中dupefilter/filtered: 10704的大量过滤请求,优先排查无需加dont_filter=True的常规原因,不要盲目开启跳过去重,避免产生大量重复请求甚至死循环:
优先解决协议混用问题
你的代码中同时使用了http和https两种协议拼接URL:比如分类页拼接用的是https://www.zandparts.com,但翻页、商品页拼接用的是http://www.zandparts.com,同一个资源的http请求会301跳转到https,scrapy会将重复发起的http请求判定为重复请求过滤。
把所有URL拼接的前缀统一改为https://www.zandparts.com即可解决大部分过滤问题,同时日志中924个301响应也会消失。
确实需要加dont_filter=True的场景和位置
只有确认某类请求需要重复发起、不需要被去重时,才在对应Request对象中添加该参数:
- 如果你确认商品页有更新需要重复采集:在
SeleniumRequest中添加dont_filter=True - 分类、系列、模型、翻页类请求不需要添加,否则会导致循环请求
修改后的SeleniumRequest示例:
yield SeleniumRequest( url = absolute_url, callback = self.parse_m, wait_time=10, wait_until=EC.element_to_be_clickable((By.LINK_TEXT, 'Tillgängliga alternativ')), meta={'links':absolute_url, 'model':response.request.meta['model'],'series':response.request.meta['series2'],'category':response.request.meta['category3']}, # 确认需要跳过去重时再加该参数 dont_filter=True )
额外优化建议
代码中部分xpath取值后直接调用strip(),如果xpath匹配不到内容会返回None,调用方法会报错,建议对get()结果做空值判断后再做字符串处理。
内容的提问来源于stack exchange,提问作者Reggie18
相关产品推荐
相关产品推荐

