Scrapy提供了Item Exporters 来创建不同的输出格式,如XML,CSV或JSON。

使用 Item Exporter

为了使用 Item Exporter,你必须对 Item Exporter 及其参数 (args) 实例化。每个 Item Exporter 需要不同的参数,详细请查看 Item Exporters 参考资料 。在实例化了 exporter 之后,你必须:

  1. 调用方法 start_exporting() 以标识 exporting 过程的开始。
  2. 对要导出的每个项目调用 export_item() 方法。
  3. 最后调用 finish_exporting() 表示 exporting 过程的结束
from scrapy import signals
from scrapy.contrib.exporter import XmlItemExporter

class XmlExportPipeline(object):

    def __init__(self):
        self.files = {}

     @classmethod
     def from_crawler(cls, crawler):
         pipeline = cls()
         crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
         crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
         return pipeline

    def spider_opened(self, spider):
        file = open('%s_products.xml' % spider.name, 'w+b')
        self.files[spider] = file
        self.exporter = XmlItemExporter(file)
        self.exporter.start_exporting()

    def spider_closed(self, spider):
        self.exporter.finish_exporting()
        file = self.files.pop(spider)
        file.close()

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item

默认情况下,该字段值将不变的传递到序列化库,如何对其进行序列化的决定被委托给每一个特定的序列化库。

有两种方法可以自定义一个字段如何被序列化,请看下文

1. 在 field 类中声明一个 serializer

import scrapy

def serialize_price(value):
    return '$ %s' % str(value)

class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field(serializer=serialize_price)

2. 覆盖(overriding) serialize_field() 方法

你可以覆盖 serialize_field() 方法来自定义如何输出你的数据。

在你的自定义代码后确保你调用父类的 serialize_field() 方法。

from scrapy.contrib.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 Exporters 参考资料

BaseItemExporter

class scrapy.contrib.exporter.BaseItemExporter(fields_to_export=None, export_empty_fields=False, encoding='utf-8')