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

Scrapy爬虫:内存传递raw_data与cleaned_data遇空输出,求解决方案

爬虫内存数据传递问题解决方案

问题核心原因

  1. 实例不匹配:你在spider_closed回调里新建的RawDataPipeline()和CleanedDataPipeline()是全新的空对象,和爬虫运行时实际处理数据的Pipeline实例完全无关,自然拿不到爬取到的数据。
  2. 信号不匹配:Pipeline里发送的是自定义spider.custom_close_signal,但run_spider.py监听的是Scrapy默认的signals.spider_closed,两者没有关联,数据无法传递到回调。

修复步骤

1. 修改Pipelines代码,将数据挂载到Spider实例

直接把处理好的raw_data和cleaned_data绑定到当前爬取的spider对象上,无需自定义信号:

# pipelines.py
from itemadapter import ItemAdapter

class RawDataPipeline:
    def __init__(self):
        self.raw_data = []
    
    def process_item(self, item, spider):
        adapter = ItemAdapter(item)
        if adapter.get('project_source'):
            self.raw_data.append(adapter.asdict())
        return item
    
    def close_spider(self, spider):
        # 将数据挂载到spider实例
        spider.raw_data = self.raw_data

class CleanedDataPipeline:
    def __init__(self):
        self.cleaned_data = []
        self.list_dic = {}
    
    def clean_item(self, item):
        # 保留你原本的清洗逻辑
        cleaned = ItemAdapter(item).asdict()
        return cleaned
    
    def convert_to_list(self, item, key):
        # 保留你原本的转换逻辑
        pass
    
    def process_item(self, item, spider):
        cleaned_item = self.clean_item(item)
        self.cleaned_data.append(cleaned_item)
        return item
    
    def close_spider(self, spider):
        # 执行原本的转换逻辑
        for key in self.list_dic:
            for cleaned_item in self.cleaned_data:
                self.convert_to_list(cleaned_item, key)
        # 将清洗后的数据挂载到spider实例
        spider.cleaned_data = self.cleaned_data

2. 修改run_spider.py的回调函数,从Spider实例获取数据

回调里的sender参数就是爬取完成的spider对象,直接从它上面读取挂载的数据:

# run_spider.py
from scrapy.crawler import CrawlerProcess
from scrapy import signals
from your_spider_module import NieuwbouwspiderSpider
import settings

def spider_closed(signal, sender, **kwargs):
    # 做容错处理,避免属性不存在导致报错
    raw_data = sender.raw_data if hasattr(sender, 'raw_data') else []
    cleaned_data = sender.cleaned_data if hasattr(sender, 'cleaned_data') else []

    print("Raw Data:", raw_data)
    print("Cleaned Data:", cleaned_data)

def run_spider():
    process = CrawlerProcess(settings)
    # 连接默认的spider_closed信号到回调
    signals.connect(spider_closed, signal=signals.spider_closed)
    process.crawl(NieuwbouwspiderSpider)
    process.start()

run_spider()

3. 确保Pipelines在Settings中正确启用

检查settings.py的ITEM_PIPELINES配置,确保两个Pipeline被注册(优先级数字越小越先执行):

# settings.py
ITEM_PIPELINES = {
    'your_package_name.pipelines.RawDataPipeline': 300,
    'your_package_name.pipelines.CleanedDataPipeline': 400,
}

方案说明

Scrapy启动爬虫时,会为每个爬虫实例初始化配置好的Pipeline实例,这些实例全程参与数据处理。把数据绑定到spider实例上,利用了spider的全局唯一性,让回调函数可以直接获取爬取过程中生成的真实数据,彻底解决实例不匹配的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:47:46