1. 程式人生 > >Scrapy——Item Exporters

Scrapy——Item Exporters

什麼是Item Exporters?

當你抓取了你想要的資料,你就會想要將他們持久化或匯出它們,並應用在其他程式。這是整個抓取過程的目的。為此,Scrapy 提供了Item Exporters來建立不同的輸出格式。

如何工作?

為了使用Item Exporter,你必須對Item Exporter及其引數例項化。每個Item Exporter需要考慮不同的引數。在例項化exporter之後,你必須:

  1. 呼叫方法start_exporting()以標識exporting過程的開始。
  2. 對要匯出的每個專案呼叫export_item()方法。
  3. 最後呼叫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

預設情況下,該欄位值將不變的傳遞到序列化庫,如何對其進行序列化的決定被委託給一個特定的序列化庫。 但是你也可以自定義每個欄位值如何序列化在它內傳遞到序列化庫之前。

  1. 在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)
  1. 覆蓋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"}

這個類能很好地處理大量資料。