You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy解析页面遇JSON错误时如何重爬?及代码合理性验证

Scrapy爬虫错误处理疑问解答及优化建议

问题1:无效页面是否会导致无限循环?

你的当前代码会陷入逻辑上的无效循环(实际重试不生效),核心原因有两点:

  • Scrapy默认重试机制仅针对特定HTTP错误状态码(如500、502、403等),页面返回200但内容缺失JSON的情况不会触发默认重试。
  • 你在except块中用return response.follow(...)试图重试,但Scrapy的回调函数需要返回可迭代对象(如yield生成的请求/条目,或包含请求的列表),单个return Request不会被Scrapy调度——也就是说你的重试逻辑根本没生效,遇到错误后回调直接终止,不会发起重试。

如果改成yield response.follow(...)但不加次数限制,爬虫会一直重复请求该无效URL直到手动停止。正确的做法是通过meta传递重试计数,达到上限后停止:

def parse(self, response):
    retry_count = response.meta.get('retry_count', 0)
    max_retry = self.settings.get('RETRY_TIMES', 3)  # 复用全局重试配置或自定义次数
    json_str = response.xpath("<xpath_to_json>").get()

    try:
        items = json.loads(json_str)["items"]
    except (JSONDecodeError, TypeError) as e:  # 同时捕获json_str为None的TypeError
        if retry_count < max_retry:
            yield response.follow(
                url=response.url,
                callback=self.parse,
                meta={'retry_count': retry_count + 1}
            )
            self.logger.warning(f"Retry {retry_count+1}/{max_retry} for invalid JSON: {response.url}")
        else:
            self.logger.error(f"Failed after {max_retry} retries: invalid JSON at {response.url}")
        return

    for i in items:
        # 处理条目逻辑
        yield item  # 记得yield生成Item对象

问题2:用return终止方法执行是否可行?

可行,但需分场景:

  • 如果只是想终止当前回调的执行(比如放弃处理该页面),return完全没问题,Scrapy会直接结束该回调流程。
  • 但如果你的目的是返回请求让Scrapy调度,return单个Request/Item是无效的,必须用yield或者返回包含请求的列表(如return [response.follow(...)]),否则Scrapy不会处理这个请求。

其他优化建议

  • 扩大异常捕获范围:除了JSONDecodeError,还要捕获TypeError(json_str为None时触发)和KeyError(解析后的字典无items键时触发),避免漏处理异常场景。
  • 提前判断空值:在解析JSON前先检查json_str是否存在,减少不必要的异常捕获:
    if not json_str:
        # 处理空值逻辑,重试或记录日志
        ...
    
  • 统一重试规则:如果想批量处理这类“200但内容无效”的情况,可以自定义RetryMiddleware,通过response.meta标记是否需要重试,让全局重试逻辑更统一。
  • 增加日志细节:在异常处理中记录响应的状态码、部分HTML内容(如response.text[:500]),方便排查是页面临时异常还是永久无效。

内容的提问来源于stack exchange,提问作者Jossy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:42:41