Feed 导出¶
在实现爬虫时,最常需要的功能之一就是能够正确地存储抓取到的数据,并且通常这意味着生成一个包含抓取数据的“导出文件”(通常称为“导出 Feed”),以便其他系统使用。
Scrapy 通过 Feed 导出功能开箱即用地提供了此功能,它允许您使用多种序列化格式和存储后端生成包含抓取项目的 Feed。
此页面提供了所有 Feed 导出功能的详细文档。如果您正在寻找分步指南,请查看 Zyte 的导出指南。
序列化格式¶
为了序列化抓取的数据,Feed 导出使用 项目导出器。这些格式开箱即用地受支持。
但是,您还可以通过 FEED_EXPORTERS
设置扩展受支持的格式。
JSON¶
FEEDS
设置中format
键的值:json
使用的导出器:
JsonItemExporter
如果您在 JSON 中使用大型 Feed,请参阅 此警告。
JSON Lines¶
FEEDS
设置中format
键的值:jsonlines
使用的导出器:
JsonLinesItemExporter
CSV¶
FEEDS
设置中format
键的值:csv
使用的导出器:
CsvItemExporter
要指定要导出的列、它们的顺序和列名,请使用
FEED_EXPORT_FIELDS
。其他 Feed 导出器也可以使用此选项,但对于 CSV 来说它很重要,因为与许多其他导出格式不同,CSV 使用固定的标题。
XML¶
FEEDS
设置中format
键的值:xml
使用的导出器:
XmlItemExporter
Pickle¶
FEEDS
设置中format
键的值:pickle
使用的导出器:
PickleItemExporter
Marshal¶
FEEDS
设置中format
键的值:marshal
使用的导出器:
MarshalItemExporter
存储¶
使用 Feed 导出时,您可以使用一个或多个 URI(通过 FEEDS
设置)定义存储 Feed 的位置。Feed 导出支持多种存储后端类型,这些类型由 URI 方案定义。
开箱即用地支持的存储后端包括
如果所需的外部库不可用,则某些存储后端可能不可用。例如,如果未安装 boto3 库,则 S3 后端不可用。
存储 URI 参数¶
存储 URI 还可以包含在创建 Feed 时替换的参数。这些参数包括
%(time)s
- 在创建 Feed 时替换为时间戳%(name)s
- 替换为爬虫名称
任何其他命名参数都将替换为名称相同的爬虫属性。例如,%(site_id)s
将在创建 Feed 时替换为 spider.site_id
属性。
以下是一些示例来说明
使用每个爬虫一个目录存储到 FTP 中
ftp://user:[email protected]/scraping/feeds/%(name)s/%(time)s.json
使用每个爬虫一个目录存储到 S3 中
s3://mybucket/scraping/feeds/%(name)s/%(time)s.json
注意
爬虫参数 成为爬虫属性,因此它们也可以用作存储 URI 参数。
存储后端¶
本地文件系统¶
Feed 存储在本地文件系统中。
URI 方案:
file
URI 示例:
file:///tmp/export.csv
所需的外部库:无
请注意,对于本地文件系统存储(仅限于此),如果您指定绝对路径(例如 /tmp/export.csv
)(仅限 Unix 系统),则可以省略该方案。或者,您也可以使用 pathlib.Path
对象。
FTP¶
Feed 存储在 FTP 服务器上。
URI 方案:
ftp
URI 示例:
ftp://user:[email protected]/path/to/export.csv
所需的外部库:无
FTP 支持两种不同的连接模式:主动或被动。Scrapy 默认使用被动连接模式。要改为使用主动连接模式,请将 FEED_STORAGE_FTP_ACTIVE
设置设置为 True
。
此存储后端中 FEEDS
的 overwrite
键的默认值为:True
。
注意
overwrite
中的 True
值会导致您丢失数据的先前版本。
此存储后端使用 延迟文件传递。
S3¶
Feed 存储在 Amazon S3 上。
URI 方案:
s3
URI 示例
s3://mybucket/path/to/export.csv
s3://aws_key:aws_secret@mybucket/path/to/export.csv
所需外部库:boto3 >= 1.20.0
AWS 凭证可以通过 URI 中的用户名/密码传递,也可以通过以下设置传递
您还可以使用以下设置定义自定义 ACL、自定义端点和导出 Feed 的区域名称
此存储后端中 FEEDS
的 overwrite
键的默认值为:True
。
注意
overwrite
中的 True
值会导致您丢失数据的先前版本。
此存储后端使用 延迟文件传递。
Google Cloud Storage (GCS)¶
2.3 版新增功能。
Feed 存储在Google Cloud Storage 上。
URI 方案:
gs
URI 示例
gs://mybucket/path/to/export.csv
所需外部库:google-cloud-storage。
有关身份验证的更多信息,请参阅Google Cloud 文档。
您可以通过以下设置设置项目 ID 和访问控制列表 (ACL)
此存储后端中 FEEDS
的 overwrite
键的默认值为:True
。
注意
overwrite
中的 True
值会导致您丢失数据的先前版本。
此存储后端使用 延迟文件传递。
标准输出¶
Feed 写入到 Scrapy 进程的标准输出。
URI 方案:
stdout
URI 示例:
stdout:
所需的外部库:无
延迟文件交付¶
如上所述,一些描述的存储后端使用延迟文件交付。
这些存储后端不会在抓取这些项目时将项目上传到 Feed URI。相反,Scrapy 将项目写入一个临时的本地文件,并且只有在所有文件内容都写入后(即在抓取结束时),该文件才会上传到 Feed URI。
如果您希望在使用这些存储后端之一时尽早开始项目交付,请使用FEED_EXPORT_BATCH_ITEM_COUNT
将输出项目拆分为多个文件,每个文件具有指定的最大项目数。这样,一旦某个文件达到最大项目数,该文件就会交付到 Feed URI,从而允许项目交付在抓取结束之前开始。
项目过滤¶
2.6.0 版新增功能。
您可以通过在Feed 选项中使用item_classes
选项来过滤要允许用于特定 Feed 的项目。只有指定类型的项目才会添加到 Feed 中。
item_classes
选项由ItemFilter
类实现,它是item_filter
Feed 选项的默认值。
您可以通过实现ItemFilter
的accepts
方法并以feed_options
作为参数来创建您自己的自定义过滤类。
例如
class MyCustomFilter:
def __init__(self, feed_options):
self.feed_options = feed_options
def accepts(self, item):
if "field1" in item and item["field1"] == "expected_data":
return True
return False
您可以将自定义过滤类分配给Feed 的选项中的item_filter
。有关示例,请参阅FEEDS
。
ItemFilter¶
后处理¶
2.6.0 版新增功能。
Scrapy 提供了一个选项来激活插件,以在将 Feed 导出到 Feed 存储之前对其进行后处理。除了使用内置插件之外,您还可以创建自己的插件。
这些插件可以通过 Feed 的postprocessing
选项激活。该选项必须传递一个按您希望 Feed 处理的顺序排列的后处理插件列表。这些插件可以声明为导入字符串,也可以使用插件的导入类。插件的参数可以通过 Feed 选项传递。有关示例,请参阅Feed 选项。
内置插件¶
- class scrapy.extensions.postprocessing.GzipPlugin(file: BinaryIO, feed_options: dict[str, Any])[source]¶
使用gzip压缩接收到的数据。
接受的
feed_options
参数gzip_compresslevel
gzip_mtime
gzip_filename
有关参数的更多信息,请参阅
gzip.GzipFile
。
自定义插件¶
每个插件都是一个类,必须实现以下方法
- __init__(self, file, feed_options)¶
初始化插件。
- write(self, data)¶
处理并将 data (
bytes
或memoryview
) 写入插件的目标文件。它必须返回写入的字节数。
- close(self)¶
清理插件。
例如,您可能希望关闭一个文件包装器,您可能已使用该包装器来压缩写入在
__init__
方法中接收的文件中的数据。警告
不要从
__init__
方法中关闭文件。
要将参数传递给您的插件,请使用 供稿选项。然后,您可以从插件的 __init__
方法中访问这些参数。
设置¶
这些是用于配置供稿导出的设置
FEEDS
(必填)
FEEDS¶
版本 2.1 中的新功能。
默认值:{}
一个字典,其中每个键都是一个供稿 URI(或 pathlib.Path
对象),每个值都是一个嵌套字典,包含特定供稿的配置参数。
此设置对于启用供稿导出功能是必需的。
有关支持的 URI 方案,请参阅 存储后端。
例如
{
'items.json': {
'format': 'json',
'encoding': 'utf8',
'store_empty': False,
'item_classes': [MyItemClass1, 'myproject.items.MyItemClass2'],
'fields': None,
'indent': 4,
'item_export_kwargs': {
'export_empty_fields': True,
},
},
'/home/user/documents/items.xml': {
'format': 'xml',
'fields': ['name', 'price'],
'item_filter': MyCustomFilter1,
'encoding': 'latin1',
'indent': 8,
},
pathlib.Path('items.csv.gz'): {
'format': 'csv',
'fields': ['price', 'name'],
'item_filter': 'myproject.filters.MyCustomFilter2',
'postprocessing': [MyPlugin1, 'scrapy.extensions.postprocessing.GzipPlugin'],
'gzip_compresslevel': 5,
},
}
以下是接受的键的列表以及如果未为特定供稿定义提供该键则用作回退值的设置
format
:序列化格式。此设置是必需的,没有回退值。
batch_item_count
:回退到FEED_EXPORT_BATCH_ITEM_COUNT
。版本 2.3.0 中的新功能。
encoding
:回退到FEED_EXPORT_ENCODING
。fields
:回退到FEED_EXPORT_FIELDS
。item_classes
:要导出的 项目类 列表。如果未定义或为空,则导出所有项目。
2.6.0 版新增功能。
item_filter
:一个 过滤器类,用于过滤要导出的项目。ItemFilter
默认使用。2.6.0 版新增功能。
indent
:回退到FEED_EXPORT_INDENT
。item_export_kwargs
:包含对应 项目导出器类 的关键字参数的dict
。版本 2.4.0 中的新功能。
overwrite
:如果文件已存在则覆盖文件(True
)还是追加到其内容(False
)。默认值取决于 存储后端
本地文件系统:
False
FTP:
True
注意
某些 FTP 服务器可能不支持追加到文件(
APPE
FTP 命令)。S3:
True
(不支持追加)Google Cloud Storage (GCS):
True
(不支持追加)标准输出:
False
(不支持覆盖)
版本 2.4.0 中的新功能。
store_empty
:回退到FEED_STORE_EMPTY
。uri_params
:回退到FEED_URI_PARAMS
。postprocessing
:要用于后处理的 插件 列表。插件将按传递的列表顺序使用。
2.6.0 版新增功能。
FEED_EXPORT_ENCODING¶
默认值:None
供稿要使用的编码。
如果未设置或设置为 None
(默认值),则对除了 JSON 输出之外的所有内容都使用 UTF-8,出于历史原因,JSON 输出使用安全的数字编码(\uXXXX
序列)。
如果您希望 JSON 也使用 UTF-8,请使用 utf-8
。
版本 2.8 中的更改: startproject
命令现在在生成的 settings.py
文件中将此设置设置为 utf-8
。
FEED_EXPORT_FIELDS¶
默认值:None
使用 FEED_EXPORT_FIELDS
设置定义要导出的字段、它们的顺序及其输出名称。有关更多信息,请参阅 BaseItemExporter.fields_to_export
。
FEED_EXPORT_INDENT¶
默认值:0
在每个级别上用于缩进输出的空格数。如果 FEED_EXPORT_INDENT
是一个非负整数,则数组元素和对象成员将以该缩进级别进行漂亮打印。缩进级别为 0
(默认值)或负数,将把每个项目放在新的一行上。None
选择最紧凑的表示形式。
目前仅由 JsonItemExporter
和 XmlItemExporter
实现,即当您导出到 .json
或 .xml
时。
FEED_STORE_EMPTY¶
默认值:True
是否导出空 Feed(即没有项目的 Feed)。如果 False
,并且没有项目要导出,则不会创建新文件,也不会修改现有文件,即使启用了 覆盖 Feed 选项。
FEED_STORAGES¶
默认值:{}
一个字典,包含项目支持的其他 Feed 存储后端。键是 URI 方案,值是存储类的路径。
FEED_STORAGE_FTP_ACTIVE¶
默认值:False
将 Feed 导出到 FTP 服务器时是否使用主动连接模式(True
)还是使用被动连接模式(False
,默认值)。
有关 FTP 连接模式的信息,请参阅 主动 FTP 和被动 FTP 有什么区别?。
FEED_STORAGE_S3_ACL¶
默认值:''
(空字符串)
一个字符串,包含项目导出到 Amazon S3 的 Feed 的自定义 ACL。
有关可用值的完整列表,请访问 Amazon S3 文档中的 预设 ACL 部分。
FEED_STORAGES_BASE¶
默认值
{
"": "scrapy.extensions.feedexport.FileFeedStorage",
"file": "scrapy.extensions.feedexport.FileFeedStorage",
"stdout": "scrapy.extensions.feedexport.StdoutFeedStorage",
"s3": "scrapy.extensions.feedexport.S3FeedStorage",
"ftp": "scrapy.extensions.feedexport.FTPFeedStorage",
}
一个字典,包含 Scrapy 支持的内置 Feed 存储后端。可以通过在 FEED_STORAGES
中将其 URI 方案分配为 None
来禁用这些后端中的任何一个。例如,要禁用内置的 FTP 存储后端(不进行替换),请将其放在 settings.py
中
FEED_STORAGES = {
"ftp": None,
}
FEED_EXPORTERS¶
默认值:{}
一个字典,包含项目支持的其他导出器。键是序列化格式,值是 项目导出器 类的路径。
FEED_EXPORTERS_BASE¶
默认值
{
"json": "scrapy.exporters.JsonItemExporter",
"jsonlines": "scrapy.exporters.JsonLinesItemExporter",
"jsonl": "scrapy.exporters.JsonLinesItemExporter",
"jl": "scrapy.exporters.JsonLinesItemExporter",
"csv": "scrapy.exporters.CsvItemExporter",
"xml": "scrapy.exporters.XmlItemExporter",
"marshal": "scrapy.exporters.MarshalItemExporter",
"pickle": "scrapy.exporters.PickleItemExporter",
}
一个字典,包含 Scrapy 支持的内置 Feed 导出器。可以通过在 FEED_EXPORTERS
中将其序列化格式分配为 None
来禁用这些导出器中的任何一个。例如,要禁用内置的 CSV 导出器(不进行替换),请将其放在 settings.py
中
FEED_EXPORTERS = {
"csv": None,
}
FEED_EXPORT_BATCH_ITEM_COUNT¶
版本 2.3.0 中的新功能。
默认值:0
如果分配了一个大于 0
的整数,则 Scrapy 会生成多个输出文件,每个输出文件最多存储指定数量的项目。
生成多个输出文件时,必须在 Feed URI 中使用以下占位符中的至少一个来指示如何生成不同的输出文件名
%(batch_time)s
- 在创建 Feed 时替换为时间戳(例如2020-03-28T14-45-08.237134
)%(batch_id)d
- 替换为批次的从 1 开始的序列号。使用 printf 样式字符串格式化 来更改数字格式。例如,要使批次 ID 成为一个 5 位数字(根据需要引入前导零),请使用
%(batch_id)05d
(例如3
变成00003
,123
变成00123
)。
例如,如果您的设置包含
FEED_EXPORT_BATCH_ITEM_COUNT = 100
并且您的 crawl
命令行是
scrapy crawl spidername -o "dirname/%(batch_id)d-filename%(batch_time)s.json"
上面的命令行可以生成如下目录树
->projectname
-->dirname
--->1-filename2020-03-28T14-45-08.237134.json
--->2-filename2020-03-28T14-45-09.148903.json
--->3-filename2020-03-28T14-45-10.046092.json
其中第一个和第二个文件正好包含 100 个项目。最后一个包含 100 个或更少的项目。
FEED_URI_PARAMS¶
默认值:None
一个字符串,包含一个函数的导入路径,用于设置要应用于 Feed URI 的参数,使用 printf 样式字符串格式化。
函数签名应如下所示
- scrapy.extensions.feedexport.uri_params(params, spider)¶
返回一个
dict
,其中包含键值对,用于使用 printf 样式字符串格式化 应用于 Feed URI。- 参数:
params (dict) –
默认键值对
具体来说
batch_id
:文件批次的 ID。参见FEED_EXPORT_BATCH_ITEM_COUNT
。如果
FEED_EXPORT_BATCH_ITEM_COUNT
为0
,则batch_id
始终为1
。版本 2.3.0 中的新功能。
batch_time
:UTC 日期和时间,采用 ISO 格式,其中:
替换为-
。参见
FEED_EXPORT_BATCH_ITEM_COUNT
。版本 2.3.0 中的新功能。
time
:batch_time
,微秒设置为0
。
spider (scrapy.Spider) – Feed 项目的源蜘蛛
注意
该函数应返回一个新字典,就地修改接收到的
params
已被弃用。
例如,要在 Feed URI 中包含源蜘蛛的 name
在项目中的某个地方定义以下函数
# myproject/utils.py def uri_params(params, spider): return {**params, "spider_name": spider.name}
在您的设置中将
FEED_URI_PARAMS
指向该函数# myproject/settings.py FEED_URI_PARAMS = "myproject.utils.uri_params"
在您的 Feed URI 中使用
%(spider_name)s
scrapy crawl <spider_name> -o "%(spider_name)s.jsonl"