译者:OSGeo 中国
一旦抓取了项目,您通常希望保留或导出这些项目,以便在其他应用程序中使用数据。这毕竟是抓取过程的全部目的。
为此,Scrapy为不同的输出格式(如XML、CSV或JSON)提供了一组项目导出器。
使用项目导出器
如果您很着急,只想使用项目导出器输出抓取的数据,请参见 Feed 导出 . 否则,如果您想知道项目导出器是如何工作的,或者需要更多的自定义功能(不包括在默认导出中),请继续阅读下面的内容。
为了使用项导出器,必须用它所需的参数实例化它。每个项目导出器需要不同的参数,因此请检查每个导出器文档以确保 内置项导出器引用 . 在实例化导出器之后,必须:
1。调用方法 start_exporting()
以便发出出口过程开始的信号
2。调用给 export_item()
要导出的每个项的方法
三。最后调用给 finish_exporting()
发出输出过程结束的信号
在这里你可以看到 Item Pipeline 它使用多个项目导出器,根据其中一个字段的值将抓取的项目分组到不同的文件中:
from scrapy.exporters import XmlItemExporter
class PerYearXmlExportPipeline(object):
"""Distribute items across multiple XML files according to their 'year' field"""
def open_spider(self, spider):
self.year_to_exporter = {}
def close_spider(self, spider):
for exporter in self.year_to_exporter.values():
exporter.finish_exporting()
exporter.file.close()
def _exporter_for_item(self, item):
year = item['year']
if year not in self.year_to_exporter:
f = open('{}.xml'.format(year), 'wb')
exporter = XmlItemExporter(f)
exporter.start_exporting()
self.year_to_exporter[year] = exporter
return self.year_to_exporter[year]
def process_item(self, item, spider):
exporter = self._exporter_for_item(item)
exporter.export_item(item)
return item
项字段的序列化
默认情况下,字段值是未修改地传递给基础序列化库的,如何序列化字段值的决定被委托给每个特定的序列化库。
但是,您可以自定义每个字段值的序列化方式。 在传递到序列化库之前.
有两种方法可以自定义字段序列化的方式,下面将介绍这两种方法。
1。在字段中声明序列化程序
如果你使用 Item
可以在中声明序列化程序 field metadata . 序列化程序必须是可调用的,它接收值并返回其序列化形式。
例子::
import scrapy
def serialize_price(value):
return '$ %s' % str(value)
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field(serializer=serialize_price)
2。重写serialize_field()方法
您还可以覆盖 serialize_field()
方法自定义字段值的导出方式。
确保调用基类 serialize_field()
方法。
例子::
from scrapy.exporter import XmlItemExporter
class ProductXmlExporter(XmlItemExporter):
def serialize_field(self, field, name, value):
if field == 'price':
return '$ %s' % str(value)
return super(Product, self).serialize_field(field, name, value)
内置项导出器引用
这是与废料捆绑在一起的物品出口商名单。其中一些包含输出示例,假设您正在导出这两个项:
Item(name='Color TV', price='1200')
Item(name='DVD player', price='200')
BaseItemExporter
class scrapy.exporters.BaseItemExporter(fields_to_export=None, export_empty_fields=False, encoding='utf-8', indent=0)
这是所有项目导出器的(抽象)基类。它支持所有(具体)项目导出器使用的公共特性,例如定义要导出的字段、是否导出空字段或要使用的编码。
这些特性可以通过填充其各自实例属性的构造函数参数进行配置: fields_to_export
, export_empty_fields
, encoding
, indent
.
export_item(item)
导出给定项。此方法必须在子类中实现。
serialize_field(field, name, value)
返回给定字段的序列化值。如果要控制特定字段或值的序列化/导出方式,可以重写此方法(在自定义项导出器中)。
默认情况下,此方法查找序列化程序 declared in the item field 并返回将该序列化程序应用于该值的结果。如果找不到序列化程序,它将返回除 unicode
编码到的值 str
使用中声明的编码 encoding
属性。
| 参数: |
- field (
Field
object or an empty dict) — 正在序列化的字段。如果正在导出原始dict(不是Item
) field 值是空的dict。 - name (str) — 正在序列化的字段的名称
- value — 正在序列化的值 | | | —- |
start_exporting()
指示导出过程的开始。某些导出器可能会使用此命令生成某些必需的头(例如, XmlItemExporter
)在导出任何项之前必须调用此方法。
finish_exporting()
发出输出过程结束的信号。一些导出器可能会使用此命令生成一些必需的页脚(例如, XmlItemExporter
)在没有其他要导出的项之后,必须始终调用此方法。
fields_to_export
具有要导出的字段名称的列表,如果要导出所有字段,则为“无”。默认为无。
一些出口商(如 CsvItemExporter
)遵守此属性中定义的字段的顺序。
有些导出者可能需要字段“到”导出列表,以便在spider返回dict时正确导出数据(而不是 Item
实例)。
export_empty_fields
是否在导出的数据中包含空/未填充的项字段。默认为 False
. 一些出口商(如 CsvItemExporter
)忽略此属性并始终导出所有空字段。
对dict项忽略此选项。
encoding
将用于编码Unicode值的编码。这只影响unicode值(这些值总是使用此编码序列化到str)。其他值类型不变地传递给特定的序列化库。
indent
用于在每个级别上缩进输出的空间量。默认为 0
.
indent=None
选择最紧凑的表示形式,同一行中的所有项都没有缩进indent<=0
每个项目都在自己的行上,没有缩进indent>0
每一项都在自己的行上,用提供的数值缩进
XmlItemExporter
class scrapy.exporters.XmlItemExporter(file, item_element='item', root_element='items', **kwargs)
将XML格式的项导出到指定的文件对象。
| 参数: |
- file — 用于导出数据的类似文件的对象。它的
write
方法应接受bytes
(以二进制模式打开的磁盘文件,io.BytesIO
物体等) - root_element (str) — 导出的XML中根元素的名称。
- item_element (str) — 导出的XML中每个item元素的名称。 | | | —- |
此构造函数的其他关键字参数将传递给 BaseItemExporter
建造师。
该出口商的典型产出为:
<?xml version="1.0" encoding="utf-8"?>
<items>
<item>
<name>Color TV</name>
<price>1200</price>
</item>
<item>
<name>DVD player</name>
<price>200</price>
</item>
</items>
除非在 serialize_field()
方法,多值字段通过序列化 <value>
元素。这是为了方便起见,因为多值字段非常常见。
例如,项目:
Item(name=['John', 'Doe'], age='23')
将序列化为:
<?xml version="1.0" encoding="utf-8"?>
<items>
<item>
<name>
<value>John</value>
<value>Doe</value>
</name>
<age>23</age>
</item>
</items>
CsvItemExporter
class scrapy.exporters.CsvItemExporter(file, include_headers_line=True, join_multivalued=', ', **kwargs)
将csv格式的项目导出到给定的文件(如对象)。如果 fields_to_export
属性已设置,将用于定义csv列及其顺序。这个 export_empty_fields
属性对此导出程序没有影响。
| 参数: |
- file — 用于导出数据的类似文件的对象。它的
write
方法应接受bytes
(以二进制模式打开的磁盘文件,io.BytesIO
物体等) - include_headers_line (str) — 如果启用,则使导出器输出一个标题行,其中字段名取自
BaseItemExporter.fields_to_export
或第一个导出项字段。 - join_multivalued — 如果找到,将用于联接多值字段的字符。 | | | —- |
此构造函数的其他关键字参数将传递给 BaseItemExporter
构造函数,以及 csv.writer 构造函数,因此可以使用 csv.writer
自定义此导出程序的构造函数参数。
该出口商的典型产出为:
product,price
Color TV,1200
DVD player,200
PickleItemExporter
class scrapy.exporters.PickleItemExporter(file, protocol=0, **kwargs)
将pickle格式的项导出到给定的文件(如对象)。
| 参数: |
- file — 用于导出数据的类似文件的对象。它的
write
方法应接受bytes
(以二进制模式打开的磁盘文件,io.BytesIO
物体等) - protocol (int) — 要使用的pickle协议。 | | | —- |
有关详细信息,请参阅 pickle module documentation .
此构造函数的其他关键字参数将传递给 BaseItemExporter
建造师。
pickle不是人类可读的格式,因此没有提供输出示例。
PprintItemExporter
class scrapy.exporters.PprintItemExporter(file, **kwargs)
以漂亮的打印格式将项目导出到指定的文件对象。
参数: | file — 用于导出数据的类似文件的对象。它的 write 方法应接受 bytes (以二进制模式打开的磁盘文件, io.BytesIO 物体等) |
---|---|
此构造函数的其他关键字参数将传递给 BaseItemExporter
建造师。
该出口商的典型产出为:
{'name': 'Color TV', 'price': '1200'}
{'name': 'DVD player', 'price': '200'}
较长的行(如果存在)的格式很好。
JsonItemExporter
class scrapy.exporters.JsonItemExporter(file, **kwargs)
以JSON格式将项目导出到指定的文件(如对象),将所有对象作为对象列表写入。附加的构造函数参数传递给 BaseItemExporter
构造函数,以及 JSONEncoder 构造函数,因此可以使用 JSONEncoder 自定义此导出程序的构造函数参数。
参数: | file — 用于导出数据的类似文件的对象。它的 write 方法应接受 bytes (以二进制模式打开的磁盘文件, io.BytesIO 物体等) |
---|---|
该出口商的典型产出为:
[{"name": "Color TV", "price": "1200"},
{"name": "DVD player", "price": "200"}]
警告
JSON是一种非常简单和灵活的序列化格式,但是由于是增量的(aka),它不能很好地扩展到大量的数据中。流模式)解析在JSON解析器(在任何语言上)中都不受很好的支持(如果有),而且大多数解析器只是解析内存中的整个对象。如果您希望JSON的强大性和简单性具有更流友好的格式,请考虑使用 JsonLinesItemExporter
或者将输出分成多个块。
JsonLinesItemExporter
class scrapy.exporters.JsonLinesItemExporter(file, **kwargs)
以JSON格式将项目导出到指定的文件(如对象),每行写入一个JSON编码的项目。附加的构造函数参数传递给 BaseItemExporter
构造函数,以及 JSONEncoder 构造函数,因此可以使用 JSONEncoder 自定义此导出程序的构造函数参数。
参数: | file — 用于导出数据的类似文件的对象。它的 write 方法应接受 bytes (以二进制模式打开的磁盘文件, io.BytesIO 物体等) |
---|---|
该出口商的典型产出为:
{"name": "Color TV", "price": "1200"}
{"name": "DVD player", "price": "200"}
不同于 JsonItemExporter
,此导出程序生成的格式非常适合序列化大量数据。