Feed 导出¶
在实现爬虫时,最常需要的功能之一是能够正确存储抓取的数据,通常这意味着生成一个包含抓取数据的“导出文件”(通常称为“导出源”),以供其他系统使用。
Scrapy 提供了开箱即用的功能,即 Feed Exports,它允许您使用多种序列化格式和存储后端生成包含抓取项目的 feeds。
本页面提供了所有数据导出功能的详细文档。如果您正在寻找逐步指南,请查看Zyte的导出指南。
序列化格式¶
为了序列化抓取的数据,feed导出使用Item exporters。这些格式是开箱即用的:
但你也可以通过
FEED_EXPORTERS 设置来扩展支持的格式。
JSON¶
FEEDS设置中format键的值:json使用的导出器:
JsonItemExporter如果您在使用JSON处理大量数据时,请参阅此警告。
JSON行¶
FEEDS设置中format键的值:jsonlines使用的导出器:
JsonLinesItemExporter
CSV¶
FEEDS设置中format键的值:csv使用的导出器:
CsvItemExporter要指定导出的列、它们的顺序以及列名,请使用
FEED_EXPORT_FIELDS。其他导出器也可以使用此选项,但对于CSV来说尤为重要,因为与许多其他导出格式不同,CSV使用固定的表头。
XML¶
FEEDS设置中format键的值:xml使用的导出器:
XmlItemExporter
Pickle¶
FEEDS设置中format键的值:pickle使用的导出器:
PickleItemExporter
元帅¶
FEEDS设置中format键的值:marshal使用的导出器:
MarshalItemExporter
存储¶
在使用feed导出时,您可以通过一个或多个URIs定义存储feed的位置(通过FEEDS设置)。feed导出支持多种存储后端类型,这些类型由URI方案定义。
支持的存储后端包括:
如果所需的外部库不可用,某些存储后端可能不可用。例如,只有在安装了boto3库时,S3后端才可用。
存储URI参数¶
存储URI还可以包含在创建feed时被替换的参数。这些参数是:
%(time)s- 在创建feed时被时间戳替换%(name)s- 被蜘蛛名称替换
任何其他命名参数都会被同名的蜘蛛属性替换。例如,%(site_id)s 在创建feed时会被 spider.site_id 属性替换。
以下是一些示例来说明:
使用每个爬虫一个目录存储在FTP中:
ftp://user:password@ftp.example.com/scraping/feeds/%(name)s/%(time)s.json
使用每个爬虫一个目录的方式存储在S3中:
s3://mybucket/scraping/feeds/%(name)s/%(time)s.json
注意
Spider arguments 成为蜘蛛属性,因此它们也可以用作存储URI参数。
存储后端¶
本地文件系统¶
数据源存储在本地文件系统中。
URI 方案:
file示例URI:
file:///tmp/export.csv所需的外部库:无
请注意,对于本地文件系统存储(仅限),如果您指定像/tmp/export.csv(仅限Unix系统)这样的绝对路径,则可以省略方案。或者,您也可以使用pathlib.Path对象。
FTP¶
数据存储在FTP服务器中。
URI 方案:
ftp示例URI:
ftp://user:pass@ftp.example.com/path/to/export.csv所需的外部库:无
FTP支持两种不同的连接模式:主动或被动。Scrapy默认使用被动连接模式。要使用主动连接模式,请将FEED_STORAGE_FTP_ACTIVE设置为True。
此存储后端的FEEDS中overwrite键的默认值为:True。
注意
在overwrite中使用值True将导致您丢失数据的先前版本。
此存储后端使用延迟文件交付。
S3¶
数据源存储在Amazon S3上。
URI 方案:
s3示例URI:
s3://mybucket/path/to/export.csvs3://aws_key:aws_secret@mybucket/path/to/export.csv
所需的外部库:boto3 >= 1.20.0
AWS 凭证可以作为 URI 中的用户/密码传递,也可以通过以下设置传递:
您还可以使用以下设置为导出的feeds定义自定义ACL、自定义端点和区域名称:
此存储后端的FEEDS中overwrite键的默认值为:True。
注意
在overwrite中使用值True将导致您丢失数据的先前版本。
此存储后端使用延迟文件交付。
Google 云存储 (GCS)¶
新版本2.3新增。
数据源存储在Google Cloud Storage上。
URI 方案:
gs示例URI:
gs://mybucket/path/to/export.csv
所需的外部库:google-cloud-storage。
有关身份验证的更多信息,请参阅Google Cloud 文档。
您可以通过以下设置来设置项目ID和访问控制列表(ACL):
此存储后端的FEEDS中overwrite键的默认值为:True。
注意
在overwrite中使用值True将导致您丢失数据的先前版本。
此存储后端使用延迟文件交付。
标准输出¶
feeds被写入Scrapy进程的标准输出。
URI 方案:
stdout示例URI:
stdout:所需的外部库:无
延迟文件交付¶
如上所述,一些描述的存储后端使用延迟文件交付。
这些存储后端不会在抓取项目时将它们上传到feed URI。相反,Scrapy将项目写入一个临时的本地文件,只有在所有文件内容都写入后(即在爬取结束时),该文件才会上传到feed URI。
如果您希望在使用这些存储后端时更早开始项目交付,请使用FEED_EXPORT_BATCH_ITEM_COUNT将输出项目分割成多个文件,每个文件包含指定的最大项目数。这样,一旦文件达到最大项目数,该文件就会被交付到feed URI,从而允许项目交付在爬取结束之前就开始。
项目过滤¶
新版本2.6.0中新增。
您可以通过在feeds options中使用item_classes选项来筛选您希望允许特定订阅源的项目。只有指定类型的项目才会被添加到订阅源中。
item_classes 选项由 ItemFilter 类实现,该类是 item_filter feed option 的默认值。
你可以通过实现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。
项目过滤器¶
后处理¶
新版本2.6.0中新增。
Scrapy 提供了一个选项来激活插件,以便在将数据导出到存储之前对数据进行后处理。除了使用 内置插件 外,你还可以创建自己的 插件。
这些插件可以通过feed的postprocessing选项激活。
该选项必须按照您希望feed处理的顺序传递一个后处理插件列表。这些插件可以声明为导入字符串或插件的导入类。可以通过feed选项传递插件参数。有关示例,请参见feed options。
内置插件¶
- 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)¶
处理和写入数据 (
bytes或memoryview) 到插件的目标文件中。 它必须返回写入的字节数。
- close(self)¶
清理插件。
例如,您可能想要关闭一个文件包装器,该包装器可能用于压缩写入到在
__init__方法中接收的文件中的数据。警告
不要从
__init__方法中关闭文件。
要向您的插件传递参数,请使用feed options。然后,您可以从插件的__init__方法中访问这些参数。
设置¶
这些是用于配置feed导出的设置:
FEEDS(必填)
动态¶
新版本2.1新增。
默认值:{}
一个字典,其中每个键都是一个feed URI(或一个pathlib.Path对象),每个值都是一个包含特定feed配置参数的嵌套字典。
此设置是启用数据导出功能所必需的。
请参阅存储后端以了解支持的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: 要导出的item classes列表。如果未定义或为空,则导出所有项目。
新版本2.6.0中新增。
item_filter: 一个filter class用于过滤要导出的项目。ItemFilter默认使用。新版本2.6.0中新增。
indent: 回退到FEED_EXPORT_INDENT。item_export_kwargs:dict包含对应 item exporter class 的关键字参数。版本2.4.0新增。
overwrite: 如果文件已经存在,是否覆盖文件 (True) 或追加到其内容 (False)。默认值取决于存储后端:
本地文件系统:
FalseFTP:
True注意
一些FTP服务器可能不支持追加文件(
APPEFTP命令)。S3:
True(不支持追加)Google Cloud Storage (GCS):
True(不支持追加)Standard output:
False(不支持覆盖)
版本2.4.0新增。
store_empty: 回退到FEED_STORE_EMPTY.uri_params: 回退到FEED_URI_PARAMS.postprocessing: 用于后处理的插件列表。插件将按照传递的列表顺序使用。
新版本2.6.0中新增。
FEED_EXPORT_ENCODING¶
默认值:None
用于提要的编码。
如果未设置或设置为None(默认),则对所有内容使用UTF-8编码,除了JSON输出,
由于历史原因,JSON输出使用安全的数字编码(\uXXXX序列)。
如果你想在JSON中也使用UTF-8,请使用utf-8。
在版本2.8中更改:startproject 命令现在将此设置设置为
utf-8 在生成的 settings.py 文件中。
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
是否在将数据导出到FTP服务器时使用主动连接模式
(True) 或使用被动连接模式 (False, 默认)。
有关FTP连接模式的信息,请参阅主动和被动FTP有什么区别?。
FEED_STORAGE_S3_ACL¶
默认值:''(空字符串)
一个字符串,包含由您的项目导出到Amazon S3的feed的自定义ACL。
有关可用值的完整列表,请访问Amazon S3文档中的Canned 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存储后端的字典。你可以通过将None分配给它们的URI方案来禁用这些后端中的任何一个,例如在FEED_STORAGES中。例如,要禁用内置的FTP存储后端(无需替换),请将此放入你的settings.py中:
FEED_STORAGES = {
"ftp": None,
}
FEED_EXPORTERS¶
默认值:{}
一个包含您的项目支持的额外导出器的字典。键是序列化格式,值是指向Item exporter类的路径。
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-style string formatting来 更改数字格式。例如,要使批次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
一个字符串,包含用于设置参数的函数的导入路径,这些参数将使用 printf-style string formatting 应用到 feed URI。
函数签名应如下所示:
- scrapy.extensions.feedexport.uri_params(params, spider)¶
返回一个键值对的
dict,使用printf-style字符串格式化应用到feed URI。- Parameters:
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"