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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:55:22