Scrapy 作为 Python 生态中最强大的爬虫框架之一,其 Feed Exports 功能为爬取结果的导出提供了开箱即用的解决方案。除了基础的 JSON 格式导出,Scrapy 还支持 CSV、XML、Pickle 等多种格式,掌握多格式导出配置的进阶用法,能极大提升数据处理的灵活性和效率。本文将深入讲解 Scrapy Feed Exports 的核心配置逻辑,并结合实战案例演示多种格式的导出配置方法。
一、Feed Exports 核心原理
Feed Exports 的本质是 Scrapy 将爬虫产出的 Item 对象,通过内置的 Exporter 组件转换为指定格式,并输出到本地文件、云存储(如 S3)或其他存储介质。其核心配置通过settings.py或爬虫命令行参数实现,核心参数包括:
FEEDS:核心配置字典,用于定义导出文件的路径、格式、编码等FEED_EXPORT_ENCODING:导出文件的编码格式(默认 utf-8)FEED_EXPORT_FIELDS:指定导出的字段列表(按需导出,避免冗余)FEED_EXPORT_INDENT:格式化输出的缩进(JSON/XML 常用)
二、基础配置:单格式导出
在开始多格式导出前,先回顾单格式导出的基础配置,这是进阶用法的前提。
2.1 配置文件方式(settings.py)
python
运行
# settings.py
# JSON格式导出配置
FEEDS = {
# 导出路径支持时间戳、爬虫名等变量
'data/%(name)s_%(time)s.json': {
'format': 'json', # 导出格式
'encoding': 'utf-8', # 文件编码
'fields': ['title', 'url', 'content'], # 指定导出字段
'indent': 4, # JSON格式化缩进
'overwrite': False, # 是否覆盖已有文件(False则追加)
'store_empty': False, # 无数据时是否生成空文件
}
}
2.2 命令行方式
无需修改配置文件,直接通过运行命令指定导出格式:
bash
运行
scrapy crawl myspider -o data/result.csv -t csv --logfile=scrapy.log
三、进阶配置:多格式同时导出
Scrapy 支持在一次爬虫运行中,同时将数据导出为多种格式,核心是在FEEDS字典中配置多个导出目标。
3.1 基础多格式配置(settings.py)
python
运行
# settings.py 多格式导出核心配置
FEEDS = {
# 1. JSON格式:结构化存储,便于程序解析
'data/result.json': {
'format': 'json',
'encoding': 'utf-8',
'fields': None, # None表示导出所有字段
'indent': 4,
'overwrite': True,
},
# 2. CSV格式:便于Excel/表格工具处理
'data/result.csv': {
'format': 'csv',
'encoding': 'utf-8',
'fields': ['title', 'url', 'publish_time', 'content'],
# CSV特有配置:分隔符、是否包含表头
'delimiter': ',',
'headers': True,
},
# 3. XML格式:适用于需符合XML规范的场景
'data/result.xml': {
'format': 'xml',
'encoding': 'utf-8',
'indent': 2,
},
# 4. Pickle格式:Python专用二进制格式,保留数据类型
'data/result.pkl': {
'format': 'pickle',
'overwrite': True,
}
}
# 全局编码配置(可选,优先级低于FEEDS内的encoding)
FEED_EXPORT_ENCODING = 'utf-8'
# 全局字段配置(可选,优先级低于FEEDS内的fields)
# FEED_EXPORT_FIELDS = ['title', 'url']
3.2 动态命名与分文件导出
实际场景中,常需要按时间、爬虫名、页码等维度分文件导出,可通过 Scrapy 内置变量实现:
python
运行
FEEDS = {
# 按爬虫名+时间戳命名JSON文件
'data/%(name)s_%(time)s.json': {'format': 'json', 'indent': 4},
# 按日期分目录存储CSV文件(需手动创建目录)
'data/%(time)s/%(name)s.csv': {
'format': 'csv',
'headers': True,
'overwrite': False, # 追加模式
},
# 按Item数量分片导出(每1000条一个文件)
'data/result_%(batch)d.json': {
'format': 'json',
'batch_item_count': 1000, # 分片大小
}
}
3.3 命令行多格式导出
若不想修改settings.py,可通过命令行参数实现多格式导出:
bash
运行
# 同时导出JSON和CSV格式
scrapy crawl myspider \
-o data/result.json -t json \
-o data/result.csv -t csv \
--feed-export-fields=title,url,content
四、特殊格式与自定义 Exporter
4.1 JSON Lines 格式(每行一个 JSON 对象)
JSON Lines(jsonlines)是大数据场景的常用格式,适合流式处理:
python
运行
FEEDS = {
'data/result.jl': {
'format': 'jsonlines', # 注意格式名是jsonlines
'encoding': 'utf-8',
'overwrite': True,
}
}
4.2 自定义导出格式
若 Scrapy 内置格式无法满足需求,可自定义 Exporter:
python
运行
# 1. 自定义Exporter类(例如导出为TSV格式)
from scrapy.exporters import CsvItemExporter
class TsvItemExporter(CsvItemExporter):
def __init__(self, file, **kwargs):
# 重写分隔符为制表符
kwargs['delimiter'] = '\t'
super().__init__(file, **kwargs)
# 2. 注册自定义Exporter
FEED_EXPORTERS = {
'tsv': 'myproject.exporters.TsvItemExporter', # 替换为实际路径
}
# 3. 使用自定义格式
FEEDS = {
'data/result.tsv': {
'format': 'tsv',
'headers': True,
}
}
五、常见问题与优化
5.1 编码问题
- 统一使用
utf-8编码,避免中文乱码 - 若导出 CSV 在 Excel 中乱码,可尝试
gbk编码,或在导出后手动转换编码
5.2 大数据量导出优化
- 优先使用
jsonlines或csv格式,避免 JSON 格式的大文件加载问题 - 开启分片导出(
batch_item_count),防止单文件过大 - 禁用
indent格式化(节省磁盘空间,提升导出速度)
5.3 字段缺失处理
- 通过
FEED_EXPORT_FIELDS指定必填字段,缺失字段会显示为空 - 在 Item 中设置默认值,避免导出时出现
None
六、完整配置示例
以下是一个生产级别的多格式导出配置,包含核心参数和异常处理:
python
运行
# settings.py
import os
from datetime import datetime
# 创建导出目录(避免路径不存在报错)
export_dir = f'data/{datetime.now().strftime("%Y%m%d")}'
os.makedirs(export_dir, exist_ok=True)
# 多格式导出配置
FEEDS = {
# JSON Lines:流式处理,适合大数据
f'{export_dir}/%(name)s_%(time)s.jl': {
'format': 'jsonlines',
'encoding': 'utf-8',
'overwrite': True,
'batch_item_count': 5000, # 每5000条分片
},
# CSV:业务分析用
f'{export_dir}/%(name)s_analysis.csv': {
'format': 'csv',
'encoding': 'utf-8',
'fields': ['id', 'title', 'url', 'publish_time', 'source'],
'headers': True,
'delimiter': ',',
},
# XML:对接第三方系统
f'{export_dir}/%(name)s_api.xml': {
'format': 'xml',
'encoding': 'utf-8',
'indent': 2,
}
}
# 全局配置
FEED_EXPORT_ENCODING = 'utf-8'
FEED_EXPORT_FIELDS = None # 不限制字段
总结
- Scrapy Feed Exports 支持 JSON、CSV、XML、Pickle 等多种格式,核心通过
FEEDS字典配置,可同时导出多格式文件; - 动态命名、分片导出、字段筛选是提升导出灵活性的关键,可通过内置变量和专用参数实现;
- 实际使用中需根据场景选择格式(JSON Lines 适合大数据、CSV 适合表格处理、XML 适合系统对接),并注意编码和性能优化。
掌握 Scrapy Feed Exports 的进阶配置,能让爬虫产出的数据更好地适配不同的下游处理场景,从简单的文件导出升级为标准化、可扩展的数据交付方案。