Scrapy爬虫:内存传递raw_data与cleaned_data遇空输出,求解决方案
爬虫内存数据传递问题解决方案
问题核心原因
- 实例不匹配:你在
spider_closed回调里新建的RawDataPipeline()和CleanedDataPipeline()是全新的空对象,和爬虫运行时实际处理数据的Pipeline实例完全无关,自然拿不到爬取到的数据。 - 信号不匹配: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
相关产品推荐
相关产品推荐

