使用Scrapy CrawlerProcess将多爬虫数据导出至同一文件的问题
解决Scrapy多爬虫导出同一文件的格式问题
当你用CrawlerProcess启动多个爬虫并导出到同一文件时,出现JSON多组括号、CSV重复表头的核心原因是:每个爬虫会独立初始化导出器,JSON会生成多个独立的数组(形如[{},{}][{},{}]),CSV则每个爬虫都输出一次表头。下面提供两种可行的解决方法:
方法一:自定义统一导出管道(兼容所有Scrapy版本)
自己实现一个管道,统一处理所有爬虫的Item,只初始化一次导出器,从根源避免重复初始化问题。
1. 编写自定义管道
在项目的pipelines.py中添加以下代码:
from scrapy.exporters import JsonItemExporter, CsvItemExporter from scrapy.utils.project import get_project_settings class UnifiedExportPipeline: def __init__(self): settings = get_project_settings() # 初始化JSON导出器 self.json_file = open(settings.get('UNIFIED_JSON_PATH'), 'wb') self.json_exporter = JsonItemExporter( self.json_file, ensure_ascii=False, indent=4 ) self.json_exporter.start_exporting() # 初始化CSV导出器 self.csv_file = open(settings.get('UNIFIED_CSV_PATH'), 'wb') self.csv_exporter = CsvItemExporter( self.csv_file, encoding='utf-8' ) self.csv_exporter.start_exporting() self.csv_header_written = False def process_item(self, item, spider): # 导出到JSON self.json_exporter.export_item(item) # 导出到CSV,确保表头只写一次 if not self.csv_header_written: # 第一次导出时自动写入表头 self.csv_exporter.export_item(item) self.csv_header_written = True else: # 后续只写入数据行,跳过表头逻辑 self.csv_exporter._write_headers_and_set_fields_to_export(item) self.csv_exporter.export_item(item) return item def close_spider(self, spider): # 结束导出并关闭文件 self.json_exporter.finish_exporting() self.json_file.close() self.csv_exporter.finish_exporting() self.csv_file.close()
2. 配置项目settings
在settings.py中添加以下配置:
# 定义统一导出文件的路径 UNIFIED_JSON_PATH = './unified_output.json' UNIFIED_CSV_PATH = './unified_output.csv' # 启用自定义管道,禁用默认导出逻辑 ITEM_PIPELINES = { '你的项目名.pipelines.UnifiedExportPipeline': 300, } FEED_EXPORT_ENCODING = None
3. 启动爬虫的代码保持不变
比如你的启动脚本:
from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from 你的项目名.spiders.toscrape import ToScrapeSpiderXPath process = CrawlerProcess(get_project_settings()) process.crawl(ToScrapeSpiderXPath) process.crawl(ToScrapeSpiderXPath) process.start()
方法二:使用Scrapy Feed Exports全局模式(Scrapy 2.0+ 推荐)
Scrapy 2.0及以上版本支持全局Feed配置,让多个爬虫共享同一个导出流,自动处理表头和JSON数组问题。
直接在settings.py中配置FEEDS参数:
FEEDS = { './unified_output.json': { 'format': 'json', 'encoding': 'utf-8', 'overwrite': True, 'store_empty': False, 'item_export_kwargs': { 'ensure_ascii': False, 'indent': 4 } }, './unified_output.csv': { 'format': 'csv', 'encoding': 'utf-8', 'overwrite': True, 'store_empty': False, 'feed_export_kwargs': { 'write_header': True } } } # 禁用自定义管道(如果之前配置过) ITEM_PIPELINES = {}
启动爬虫的代码无需修改,Scrapy会自动将所有爬虫的Item合并到同一个JSON数组中,CSV也只会写入一次表头。
注意事项
- 若使用Feed Exports方式,必须保证Scrapy版本≥2.0,低版本不支持全局共享导出流。
- 自定义管道方式更灵活,可在管道中添加数据过滤、预处理等逻辑,兼容所有Scrapy版本。
- 导出文件路径建议使用绝对路径,避免因工作目录变化导致文件找不到。
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

