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

Scrapy中parse_cat函数else分支不触发的问题排查及可行性咨询

问题解答

核心错误原因

  • 第一个错误:response.css()返回的是SelectorList类型,哪怕没有匹配到任何元素,也永远不会等于None,所以你的if search_prod is not None判断永远为真,else分支完全不会触发。正确的判断方式是直接判断if search_prod:,空的SelectorList在布尔判断里会返回False。
  • 第二个错误:你在else分支里发起的请求url是当前parse_cat处理的分类页url,但是回调设置成了parse_sub_cat,parse_sub_cat的逻辑是提取子分类导航链接,用分类页的响应去跑子分类页的解析逻辑,完全匹配不到对应的XPath规则,不可能得到预期结果。
  • 第三个错误:Scrapy默认开启请求去重,你重复请求同一个url会被自动过滤掉,哪怕逻辑对了请求也发不出去,需要加dont_filter=True参数才能强制发起请求。
  • 额外语法问题:你粘贴的代码没有遵守Python的缩进规则,函数体没有缩进会直接触发语法报错;同时变量名ulr_product拼写错误,后续调用也会出现异常。

需求实现方案

你的需求完全可以实现,如果你要的效果是「当前分类页没有匹配到商品时,重试当前分类页请求」,修正后代码如下:

import scrapy

def parse_sub_cat(self, response):
    # 修正缩进
    for i in response.xpath('//a[@data-track-action="CategoryOverviewNavigation"]'):
        goods_url = response.urljoin(i.xpath("./@href").get())
        product_parent = i.xpath("./text()").get()
        yield response.follow(
            url=goods_url,
            callback=self.parse_cat,
            # 新增重试次数字段,避免无限循环
            cb_kwargs=dict(product_parent=product_parent, retry_count=0)
        )

def parse_cat(self, response, **cb_kwargs):
    # 修正缩进
    search_prod = response.css('article.m-grid-tile').css('div.m-grid-tile--image')
    # 修正判断逻辑
    if search_prod:
        for i in search_prod:
            # 修正变量名拼写
            url_product = response.urljoin(i.css('a::attr("href")').get())
            cb_kwargs['model'] = i.css('a::attr("aria-label")').get()
            yield response.follow(
                url=url_product,
                callback=self.parse_product,
                cb_kwargs=cb_kwargs
            )
    else:
        retry_count = cb_kwargs.get('retry_count', 0)
        # 最多重试3次,避免页面本身无商品时进入死循环
        if retry_count < 3:
            cb_kwargs['retry_count'] = retry_count + 1
            yield scrapy.Request(
                url=response.url,
                callback=self.parse_cat,
                cb_kwargs=cb_kwargs,
                # 跳过请求去重
                dont_filter=True
            )

如果你确实需要回退到上一级子分类列表页,只需要在parse_sub_cat跳转的时候把上级页面的url也通过cb_kwargs传下来,else分支里请求上级页面的url即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:48:01