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

Scrapy添加cb_kwargs传参后parseMain回调不执行无爬取数据

问题根因
  • 最核心的错误是回调入口逻辑写反:Scrapy爬虫启动后默认调用parse方法处理start_urls返回的响应,你把列表提取、分页逻辑全部放在parseMain方法中,却没有在初始请求阶段指定parseMain作为列表页的回调函数,默认的parse方法拿到列表页响应后,根本匹配不到详情页的官网链接提取规则,既不会产出数据,也不会生成指向parseMain的请求,最终表现就是parseMain完全不执行,只有框架启动日志。
  • 传参或回调名拼写错误:如果生成Request时callback参数的方法名拼写和实际定义的方法名大小写/字符不一致(比如写的callback=self.parse_main但实际方法是parseMain),或是cb_kwargs传的键名和parseMain定义的形参名不匹配,默认日志等级下Scrapy不会打印醒目的报错,只会直接跳过回调执行,表现和没触发方法一致。
  • 请求被过滤拦截:如果allowed_domains配置漏加了目标域名、分页url拼接错误生成无效地址,Scrapy自带的去重/域名过滤器会直接丢弃对应请求,不会交给回调处理,也会出现无数据的现象。
修复方案
  1. 重写start_requests方法指定初始回调,不要依赖默认的parse做入口:
    from scrapy import Request, Spider
    
    class YourSpider(Spider):
        name = "your_spider"
        allowed_domains = ["rynekpierwotny.pl"]
        start_urls = []
    
        def start_requests(self):
            # 启动后首先请求列表第一页,直接绑定parseMain做回调
            yield Request(
                url="https://rynekpierwotny.pl/deweloperzy/?page=1",
                callback=self.parseMain
            )
    
  2. 理顺两个回调的调用顺序,保证传参匹配:
    • parseMain只负责处理列表页响应:提取当前页的项目名、地址、详情页链接,拼接分页url生成分页请求(回调同样绑定parseMain);对提取到的详情页链接,生成详情页请求,回调绑定parse方法,需要跨回调传递的字段通过cb_kwargs传递,键名必须和parse方法的形参完全一致。
    • parse只负责处理详情页响应:提取官网链接,补全从cb_kwargs拿到的基础字段,直接yield完整item即可。
      参考写法:
    def parseMain(self, response):
        # 提取当前页所有条目
        for item in response.css("开发商条目选择器"):
            base_item = {
                "project_name": item.css("项目名选择器::text").get(),
                "address": item.css("地址选择器::text").get(),
                "detail_url": item.css("详情链接选择器::attr(href)").get()
            }
            # 补全详情页绝对地址
            detail_url = response.urljoin(base_item["detail_url"])
            yield Request(
                url=detail_url,
                callback=self.parse,
                cb_kwargs={"base_item": base_item} # 键名必须和parse形参一致
            )
        # 分页逻辑
        next_page = response.css("下一页按钮选择器::attr(href)").get()
        if next_page:
            yield Request(
                url=response.urljoin(next_page),
                callback=self.parseMain
            )
    
    def parse(self, response, base_item):
        # 提取官网链接补全item
        base_item["websiteurl"] = response.css("官网链接选择器::attr(href)").get()
        yield base_item
    
  3. 排查拦截问题:调试阶段可以在生成Request时临时加dont_filter=True参数,如果加完之后回调正常执行,就逐一检查allowed_domains配置、url拼接逻辑,确认没有误拦截合法请求后再移除该参数,避免出现重复爬取。
  4. 快速定位技巧:在两个回调方法的第一行加日志打印当前访问的url,比如self.logger.info(f"当前处理url: {response.url}, 所在方法: parseMain"),通过日志输出就能直接判断哪个环节断了。
验证步骤
  • 先关闭分页逻辑,只跑第一页列表,确认parseMain能正常提取条目、生成详情页请求
  • 验证详情页请求能正常进入parse方法,官网链接提取正确,item字段完整
  • 最后打开分页逻辑,确认分页url生成正确,能连续爬取多页数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:27:14