💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 条目导出器 > 译者:[OSGeo 中国](https://www.osgeo.cn/) 一旦抓取了项目,您通常希望保留或导出这些项目,以便在其他应用程序中使用数据。这毕竟是抓取过程的全部目的。 为此,Scrapy为不同的输出格式(如XML、CSV或JSON)提供了一组项目导出器。 ## 使用项目导出器 如果您很着急,只想使用项目导出器输出抓取的数据,请参见 [Feed 导出](feed-exports.html#topics-feed-exports) . 否则,如果您想知道项目导出器是如何工作的,或者需要更多的自定义功能(不包括在默认导出中),请继续阅读下面的内容。 为了使用项导出器,必须用它所需的参数实例化它。每个项目导出器需要不同的参数,因此请检查每个导出器文档以确保 [内置项导出器引用](#topics-exporters-reference) . 在实例化导出器之后,必须: 1。调用方法 [`start_exporting()`](#scrapy.exporters.BaseItemExporter.start_exporting "scrapy.exporters.BaseItemExporter.start_exporting") 以便发出出口过程开始的信号 2。调用给 [`export_item()`](#scrapy.exporters.BaseItemExporter.export_item "scrapy.exporters.BaseItemExporter.export_item") 要导出的每个项的方法 三。最后调用给 [`finish_exporting()`](#scrapy.exporters.BaseItemExporter.finish_exporting "scrapy.exporters.BaseItemExporter.finish_exporting") 发出输出过程结束的信号 在这里你可以看到 [Item Pipeline](item-pipeline.html) 它使用多个项目导出器,根据其中一个字段的值将抓取的项目分组到不同的文件中: ```py 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`](items.html#scrapy.item.Item "scrapy.item.Item") 可以在中声明序列化程序 [field metadata](items.html#topics-items-fields) . 序列化程序必须是可调用的,它接收值并返回其序列化形式。 例子:: ```py 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()`](#scrapy.exporters.BaseItemExporter.serialize_field "scrapy.exporters.BaseItemExporter.serialize_field") 方法自定义字段值的导出方式。 确保调用基类 [`serialize_field()`](#scrapy.exporters.BaseItemExporter.serialize_field "scrapy.exporters.BaseItemExporter.serialize_field") 方法。 例子:: ```py 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) ``` ## 内置项导出器引用 这是与废料捆绑在一起的物品出口商名单。其中一些包含输出示例,假设您正在导出这两个项: ```py Item(name='Color TV', price='1200') Item(name='DVD player', price='200') ``` ### BaseItemExporter ```py class scrapy.exporters.BaseItemExporter(fields_to_export=None, export_empty_fields=False, encoding='utf-8', indent=0) ``` 这是所有项目导出器的(抽象)基类。它支持所有(具体)项目导出器使用的公共特性,例如定义要导出的字段、是否导出空字段或要使用的编码。 这些特性可以通过填充其各自实例属性的构造函数参数进行配置: [`fields_to_export`](#scrapy.exporters.BaseItemExporter.fields_to_export "scrapy.exporters.BaseItemExporter.fields_to_export") , [`export_empty_fields`](#scrapy.exporters.BaseItemExporter.export_empty_fields "scrapy.exporters.BaseItemExporter.export_empty_fields") , [`encoding`](#scrapy.exporters.BaseItemExporter.encoding "scrapy.exporters.BaseItemExporter.encoding") , [`indent`](#scrapy.exporters.BaseItemExporter.indent "scrapy.exporters.BaseItemExporter.indent") . ```py export_item(item) ``` 导出给定项。此方法必须在子类中实现。 ```py serialize_field(field, name, value) ``` 返回给定字段的序列化值。如果要控制特定字段或值的序列化/导出方式,可以重写此方法(在自定义项导出器中)。 默认情况下,此方法查找序列化程序 [declared in the item field](#topics-exporters-serializers) 并返回将该序列化程序应用于该值的结果。如果找不到序列化程序,它将返回除 `unicode` 编码到的值 `str` 使用中声明的编码 [`encoding`](#scrapy.exporters.BaseItemExporter.encoding "scrapy.exporters.BaseItemExporter.encoding") 属性。 | 参数: | * **field** ([`Field`](items.html#scrapy.item.Field "scrapy.item.Field") object or an empty dict) -- 正在序列化的字段。如果正在导出原始dict(不是 [`Item`](items.html#scrapy.item.Item "scrapy.item.Item") ) _field_ 值是空的dict。 * **name** (_str_) -- 正在序列化的字段的名称 * **value** -- 正在序列化的值 | | --- | --- | ```py start_exporting() ``` 指示导出过程的开始。某些导出器可能会使用此命令生成某些必需的头(例如, [`XmlItemExporter`](#scrapy.exporters.XmlItemExporter "scrapy.exporters.XmlItemExporter") )在导出任何项之前必须调用此方法。 ```py finish_exporting() ``` 发出输出过程结束的信号。一些导出器可能会使用此命令生成一些必需的页脚(例如, [`XmlItemExporter`](#scrapy.exporters.XmlItemExporter "scrapy.exporters.XmlItemExporter") )在没有其他要导出的项之后,必须始终调用此方法。 ```py fields_to_export ``` 具有要导出的字段名称的列表,如果要导出所有字段,则为“无”。默认为无。 一些出口商(如 [`CsvItemExporter`](#scrapy.exporters.CsvItemExporter "scrapy.exporters.CsvItemExporter") )遵守此属性中定义的字段的顺序。 有些导出者可能需要字段“到”导出列表,以便在spider返回dict时正确导出数据(而不是 `Item` 实例)。 ```py export_empty_fields ``` 是否在导出的数据中包含空/未填充的项字段。默认为 `False` . 一些出口商(如 [`CsvItemExporter`](#scrapy.exporters.CsvItemExporter "scrapy.exporters.CsvItemExporter") )忽略此属性并始终导出所有空字段。 对dict项忽略此选项。 ```py encoding ``` 将用于编码Unicode值的编码。这只影响unicode值(这些值总是使用此编码序列化到str)。其他值类型不变地传递给特定的序列化库。 ```py indent ``` 用于在每个级别上缩进输出的空间量。默认为 `0` . * `indent=None` 选择最紧凑的表示形式,同一行中的所有项都没有缩进 * `indent&lt;=0` 每个项目都在自己的行上,没有缩进 * `indent&gt;0` 每一项都在自己的行上,用提供的数值缩进 ### XmlItemExporter ```py 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`](#scrapy.exporters.BaseItemExporter "scrapy.exporters.BaseItemExporter") 建造师。 该出口商的典型产出为: ```py <?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()` 方法,多值字段通过序列化 `&lt;value&gt;` 元素。这是为了方便起见,因为多值字段非常常见。 例如,项目: ```py Item(name=['John', 'Doe'], age='23') ``` 将序列化为: ```py <?xml version="1.0" encoding="utf-8"?> <items> <item> <name> <value>John</value> <value>Doe</value> </name> <age>23</age> </item> </items> ``` ### CsvItemExporter ```py 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`](#scrapy.exporters.BaseItemExporter.fields_to_export "scrapy.exporters.BaseItemExporter.fields_to_export") 或第一个导出项字段。 * **join_multivalued** -- 如果找到,将用于联接多值字段的字符。 | | --- | --- | 此构造函数的其他关键字参数将传递给 [`BaseItemExporter`](#scrapy.exporters.BaseItemExporter "scrapy.exporters.BaseItemExporter") 构造函数,以及 [csv.writer](https://docs.python.org/2/library/csv.html#csv.writer) 构造函数,因此可以使用 `csv.writer` 自定义此导出程序的构造函数参数。 该出口商的典型产出为: ```py product,price Color TV,1200 DVD player,200 ``` ### PickleItemExporter ```py class scrapy.exporters.PickleItemExporter(file, protocol=0, **kwargs) ``` 将pickle格式的项导出到给定的文件(如对象)。 | 参数: | * **file** -- 用于导出数据的类似文件的对象。它的 `write` 方法应接受 `bytes` (以二进制模式打开的磁盘文件, `io.BytesIO` 物体等) * **protocol** (_int_) -- 要使用的pickle协议。 | | --- | --- | 有关详细信息,请参阅 [pickle module documentation](https://docs.python.org/2/library/pickle.html) . 此构造函数的其他关键字参数将传递给 [`BaseItemExporter`](#scrapy.exporters.BaseItemExporter "scrapy.exporters.BaseItemExporter") 建造师。 pickle不是人类可读的格式,因此没有提供输出示例。 ### PprintItemExporter ```py class scrapy.exporters.PprintItemExporter(file, **kwargs) ``` 以漂亮的打印格式将项目导出到指定的文件对象。 | 参数: | **file** -- 用于导出数据的类似文件的对象。它的 `write` 方法应接受 `bytes` (以二进制模式打开的磁盘文件, `io.BytesIO` 物体等) | | --- | --- | 此构造函数的其他关键字参数将传递给 [`BaseItemExporter`](#scrapy.exporters.BaseItemExporter "scrapy.exporters.BaseItemExporter") 建造师。 该出口商的典型产出为: ```py {'name': 'Color TV', 'price': '1200'} {'name': 'DVD player', 'price': '200'} ``` 较长的行(如果存在)的格式很好。 ### JsonItemExporter ```py class scrapy.exporters.JsonItemExporter(file, **kwargs) ``` 以JSON格式将项目导出到指定的文件(如对象),将所有对象作为对象列表写入。附加的构造函数参数传递给 [`BaseItemExporter`](#scrapy.exporters.BaseItemExporter "scrapy.exporters.BaseItemExporter") 构造函数,以及 [JSONEncoder](https://docs.python.org/2/library/json.html#json.JSONEncoder) 构造函数,因此可以使用 [JSONEncoder](https://docs.python.org/2/library/json.html#json.JSONEncoder) 自定义此导出程序的构造函数参数。 | 参数: | **file** -- 用于导出数据的类似文件的对象。它的 `write` 方法应接受 `bytes` (以二进制模式打开的磁盘文件, `io.BytesIO` 物体等) | | --- | --- | 该出口商的典型产出为: ```py [{"name": "Color TV", "price": "1200"}, {"name": "DVD player", "price": "200"}] ``` 警告 JSON是一种非常简单和灵活的序列化格式,但是由于是增量的(aka),它不能很好地扩展到大量的数据中。流模式)解析在JSON解析器(在任何语言上)中都不受很好的支持(如果有),而且大多数解析器只是解析内存中的整个对象。如果您希望JSON的强大性和简单性具有更流友好的格式,请考虑使用 [`JsonLinesItemExporter`](#scrapy.exporters.JsonLinesItemExporter "scrapy.exporters.JsonLinesItemExporter") 或者将输出分成多个块。 ### JsonLinesItemExporter ```py class scrapy.exporters.JsonLinesItemExporter(file, **kwargs) ``` 以JSON格式将项目导出到指定的文件(如对象),每行写入一个JSON编码的项目。附加的构造函数参数传递给 [`BaseItemExporter`](#scrapy.exporters.BaseItemExporter "scrapy.exporters.BaseItemExporter") 构造函数,以及 [JSONEncoder](https://docs.python.org/2/library/json.html#json.JSONEncoder) 构造函数,因此可以使用 [JSONEncoder](https://docs.python.org/2/library/json.html#json.JSONEncoder) 自定义此导出程序的构造函数参数。 | 参数: | **file** -- 用于导出数据的类似文件的对象。它的 `write` 方法应接受 `bytes` (以二进制模式打开的磁盘文件, `io.BytesIO` 物体等) | | --- | --- | 该出口商的典型产出为: ```py {"name": "Color TV", "price": "1200"} {"name": "DVD player", "price": "200"} ``` 不同于 [`JsonItemExporter`](#scrapy.exporters.JsonItemExporter "scrapy.exporters.JsonItemExporter") ,此导出程序生成的格式非常适合序列化大量数据。