什么是Item Exporters?
当你抓取了你想要的数据,你就会想要将他们持久化或导出它们,并应用在其他程序。这是整个抓取过程的目的。为此,Scrapy 提供了Item Exporters来创建不同的输出格式。
如何工作?
为了使用Item Exporter,你必须对Item Exporter及其参数实例化。每个Item Exporter需要考虑不同的参数。在实例化exporter之后,你必须:
- 调用方法
start_exporting()
以标识exporting过程的开始。 - 对要导出的每个项目调用
export_item()
方法。 - 最后调用
finish_exporting()
表示exporting过程的结束。
这里,你可以看到一个Item Pipeline,它使用Item Exporter导出items到不同的文件,每个spider一个:
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()
# spider启动信号和spider_opened函数绑定
crawler.signals.connect(pipeline.spider_opened,signals.spider_opened)
# spider关闭信号和spider_closed函数绑定
crawler.signals.connect(pipeline.spider_closed,signals.spider_closed)
return pipeline
# spider启动时的函数逻辑
def spider_opened(self,spider):
file=open('%s_products.xml' %spider.name,'wb')
self.files[spider]=file
self.exporter=XmlExportPipeline(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
序列化item fireld
默认情况下,该字段值将不变的传递到序列化库,如何对其进行序列化的决定被委托给一个特定的序列化库。
但是你也可以自定义每个字段值如何序列化在它内传递到序列化库之前。
- 在fireld类中声明一个serializer
可以在field metadata声明一个serializer。该serializer必须可调用,并返回它的序列化形式。
import scrapy
def serialize_price(value):
return '$ %s' % str(value)
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field(serializer=serialize_price)
- 覆盖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参考资料
下面是一些Scrapy内置的Item Exporters类
BaseItemExporter
class scrapy.contrib.exporter.BaseItemExporter(fields_to_export=None, export_empty_fields=False, encoding='utf-8')
这是一个对所有Item Exporters的父类。它对所有Item Exporters提供基本属性。
属性/方法 | 描述 |
---|---|
export_item(item) | 输出给定item,此方法必须在子类中实现 |
serialize_field(field, name, value) | 返回给定field的序列化值,可以覆盖此方法来控制序列化和输出指定fireld。默认情况下,此方法寻找一个serializer在item field中声明并返回它的值。如果没有发现serailzer,则值不会改变,除非你使用unicode值并编码到str。 |
start_exporting() | 表示exportering过程的开始 |
finish_exporting() | 表示exporting过程的结束 |
fields_to_export | 列出export什么field值,None表示export所有fields。默认值为None。 |
export_empty_fields | 是否在输出数据中包含为空的item fields。默认值是False。 |
encoding | Encoding属性将用于编码unicode值,其他值类型将不变的传递到指定的序列化库 |
XmlItemExporter
class scrapy.contrib.exporter.XmlItemExporter(file, item_element='item', root_element='items', **kwargs)
以XML格式exports Items到指定的文件类。
参数:
- file- 文件类
- root_element-XML根元素名
- item_element-XML item的元素名
构造器额外的关键字参数将传给BaseItemExporter
构造器。
一个典型的expoter实例:
<?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>
除了覆盖serlize_fireld方法,多个值的firelds会转化每个值到元素。
如:
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.contrib.exporter.CsvItemExporter(file, include_headers_line=True, join_multivalued=', ', **kwargs)
输出csv文件格式,如果添加fireld_to_export属性,它会按顺序定义CSV的列名。
参数:
- file-文件类
- include_headers_line-启用后exporter会输出第一行为列名,列名从
BaseItemExporter
构造器,其余的将传给csv.writer构造器,以此来定制exporter。
pickleItemExporter
scrapy.contrib.exporter.PickleItemExporter(file, protocol=0, **kwargs)
输出pickle文件格式。
参数:
- file-文件类
- protocol-pickle协议
PprintItemExpoter
scrapy.contrib.exporter.PprintItemExporter(file, **kwargs)
输出整齐打印的文件格式,此格式会根据行的长短进行调整。
JsonItemExpoter
class scrapy.contrib.exporter.JsonItemExporter(file, **kwargs)
输出JSON文件格式,所有对象将写进一个对象的列表。
实例
[{"name": "Color TV", "price": "1200"},
{"name": "DVD player", "price": "200"}]
JsonLinesItemExporter
class scrapy.contrib.exporter.JsonLinesItemExporter(file, **kwargs)
输出JSON文件格式,每行写一个JSON-encoded项,此构造器额外的关键字参数传给BaseItemExpoter构造器,其余的将传给JSONEncoder构造器。
实例:
{"name": "Color TV", "price": "1200"}
{"name": "DVD player", "price": "200"}
这个类能很好地处理大量数据。