アイテム・エクスポーター

アイテムをスクレイピングしたら、他のアプリケーションでデータを使用するために、それらのアイテムを永続化またはエクスポートすることがよくあります。 つまり、結局のところ、それがスクレイピング・プロセス全体の目的です。

この目的のために、Scrapyは、XML、CSV、JSONなどのさまざまな出力形式のアイテム・エクスポーターのコレクションを提供します。

アイテム・エクスポーターの使用

あなたが急いでいて、アイテム・エクスポータを使用してスクレイプ・データを出力するだけの場合は、 フィード・エクスポート を参照してください。それ以外の場合または、アイテム・エクスポータがどのように機能するかを知りたい場合または、またはより多くのカスタム機能(デフォルトのエクスポートではカバーされてない機能)が必要な場合は、以下をお読みください。

アイテム・エクスポーターを使用するには、必要な引数でインスタンス化する必要があります。 各アイテム・エクスポーターには異なる引数が必要なため、 組み込みアイテム・エクスポーター・リファレンス で各エクスポーターのドキュメントを確認してください。エクスポーターをインスタンス化した後、以下の作業が必要です:

1.エクスポート・プロセスの開始を通知するために、メソッド start export() を呼び出します。

2.エクスポートする各アイテムに対して export_item() メソッドを呼び出します

3.最後に finish export() を呼び出して、エクスポート・プロセスの終了を通知します

以下の アイテム・パイプライン をご覧ください。これは、複数のアイテム・エクスポーターを使用して、それらのフィールドの値に従って、スクレイプされたアイテムを異なるファイルにグループ化します:

from itemadapter import ItemAdapter
from scrapy.exporters import XmlItemExporter

class PerYearXmlExportPipeline:
    """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, xml_file in self.year_to_exporter.values():
            exporter.finish_exporting()
            xml_file.close()

    def _exporter_for_item(self, item):
        adapter = ItemAdapter(item)
        year = adapter['year']
        if year not in self.year_to_exporter:
            xml_file = open(f'{year}.xml', 'wb')
            exporter = XmlItemExporter(xml_file)
            exporter.start_exporting()
            self.year_to_exporter[year] = (exporter, xml_file)
        return self.year_to_exporter[year][0]

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

アイテム・フィールドのシリアル化

デフォルトでは、フィールド値は変更されずに基礎となるシリアル化ライブラリに渡され、それらをシリアル化する方法の決定は特定の各シリアル化ライブラリに委任されます。

ただし、あなたは、各フィールド値をシリアル化する方法を、 シリアル化ライブラリに渡す前の段階で カスタマイズできます。

フィールドのシリアル化方法をカスタマイズするには、以下の2つの方法があります。

1. フィールドでシリアライザーを宣言する

あなたが Item を使用する場合、 フィールド・メタ・データ でシリアライザーを宣言できます。シリアライザーは、値を受け取り、シリアル化された形式を返す、呼び出し可能オブジェクトでなければなりません。

例:

import scrapy

def serialize_price(value):
    return f'$ {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 f'$ {str(value)}'
        return super().serialize_field(field, name, value)

組み込みアイテム・エクスポーター・リファレンス

Scrapyにバンドルされているアイテム・エクスポーターのリストを次に示します。それらの一部には、以下の2つのアイテムをエクスポートすることを想定した出力例が含まれています:

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, dont_fail=False)[ソース]

これは、すべてのアイテム・エクスポーターの(抽象的な)基本クラスです。 エクスポートするフィールド、空のフィールドをエクスポートするか、使用するエンコードを定義するなど、すべての(具体的な)アイテム・エクスポーターで使用される共通機能のサポートを提供します。

これらの機能は、それぞれのインスタンス属性を設定する __init__ メソッド引数を介して構成できます。それらは、 fields_to_exportexport_empty_fieldsencodingindent です。

バージョン 2.0 で追加: dont_fail パラメータ

export_item(item)[ソース]

与えられたアイテムをエクスポートします。このメソッドはサブクラスで実装する必要があります。

serialize_field(field, name, value)[ソース]

指定のフィールドのシリアル化された値を返します。特定のフィールドまたは値をシリアル化/エクスポートする方法を制御する場合は、カスタム・アイテム・エクスポーターでこのメソッドをオーバーライドできます。

デフォルトでは、このメソッドは アイテムフィールドで宣言された シリアライザーを検索し、そして、そのシリアライザーを値に適用した結果を返します。 シリアライザーが見つからない場合は、値を変更せずに返します。

パラメータ
  • field (Field object or a dict instance) -- シリアル化されるフィールド。 ソースの アイテム・オブジェクト がフィールド・メタデータを定義していない場合、 field は空の辞書( dict )です。

  • name (str) -- シリアル化されるフィールドの名前

  • value -- シリアル化される値

start_exporting()[ソース]

エクスポート・プロセスの開始を通知します。一部のエクスポーターはこれを使用して、必要なヘッダー( XmlItemExporter など)を生成します。アイテムをエクスポートする前に、このメソッドを呼び出す必要があります。

finish_exporting()[ソース]

エクスポート・プロセスの終了を通知します。一部のエクスポーターはこれを使用して、必要なフッター(たとえば、 XmlItemExporter )を生成します。エクスポートするアイテムがなくなったら、常にこのメソッドを呼び出す必要があります。

fields_to_export

エクスポートされるフィールドの名前のリスト、またはすべてのフィールドをエクスポートする場合は None 。デフォルトは None です。

一部のエクスポーター( CsvItemExporter など)は、この属性で定義されたフィールドの順序を尊重します。

可能なすべてのフィールドを公開しない アイテム・オブジェクト を使用する場合、アイテムごとに異なるサブセットのフィールドのエクスポートをサポートしないエクスポーターは、最初にエクスポートされたアイテムで見つかったフィールドのみをエクスポートします。 fields_to_export を使用して、エクスポートするすべてのフィールドを定義します。

export_empty_fields

エクスポートされたデータに空/未入力の項目フィールドを含めるかどうか。デフォルトは False です。 一部のエクスポーター( CsvItemExporter など)はこの属性を無視し、常にすべての空のフィールドをエクスポートします。

このオプションは、辞書アイテムでは無視されます。

encoding

出力キャラクタ・エンコーディング

indent

各レベルで出力をインデントするために使用されるスペースの量。デフォルトは 0 です。

  • indent=None は、全てのアイテムを同一行にインテント無しで出力する、最もコンパクトな表現を選択します

  • indent<=0 はアイテム毎に行を分けますが、インデントはありません

  • indent>0 はアイテム毎に行を分け、指定した数値でインデントします

PythonItemExporter

class scrapy.exporters.PythonItemExporter(*, dont_fail=False, **kwargs)[ソース]

これは、ネストされたアイテムをサポートする BaseItemExporter を拡張するアイテム・エクスポーターの基本クラスです。

アイテムをPython組み込み型にシリアル化するため、シリアル化ライブラリ(例: json または msgpack )をその上で使用できます。

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の各アイテム要素の名前。

この __init__ メソッドの追加のキーワード引数は、 BaseItemExporter__init__ メソッドに渡されます。

このエクスポーターの典型的な出力は次のようになります:

<?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=',', errors=None, **kwargs)[ソース]

与えられたファイルのようなオブジェクトにCSV形式でアイテムをエクスポートします。 fields_to_export 属性が設定されている場合、CSV列とその順序を定義するために使用されます。 export_empty_fields 属性はこのエクスポーターには影響しません。

パラメータ
  • file -- データのエクスポートに使用するファイルのようなオブジェクト。 その write メソッドは bytes (バイナリ・モードで開かれたディスクファイルや、 io.BytesIO オブジェクトなど)を受け入れる必要があります

  • include_headers_line (str) -- 有効にすると、エクスポーターは BaseItemExporter.fields_to_export または最初にエクスポートされたアイテム・フィールドから取得したフィールド名を含むヘッダー行を出力します。

  • join_multivalued -- 複数値フィールドを結合するために使用される単一文字(または複数の文字)。

  • errors (str) -- エンコードおよびデコードエラーの処理方法を指定するオプションの文字列。 詳細については、 io.TextIOWrapper を参照してください。

この __init__ メソッドの追加のキーワード引数は BaseItemExporter__init__ メソッドに渡され、残りの引数は 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 を参照してください。

この __init__ メソッドの追加のキーワード引数は、 BaseItemExporter__init__ メソッドに渡されます。

pickleは人間が読める形式ではないため、出力例はありません。

PprintItemExporter

class scrapy.exporters.PprintItemExporter(file, **kwargs)[ソース]

指定のファイルオブジェクトにきれいな(pretty)印刷形式でアイテムをエクスポートします。

パラメータ

file -- データのエクスポートに使用するファイルのようなオブジェクト。 その write メソッドは bytes (バイナリ・モードで開かれたディスクファイルや、 io.BytesIO オブジェクトなど)を受け入れる必要があります

この __init__ メソッドの追加のキーワード引数は、 BaseItemExporter__init__ メソッドに渡されます。

このエクスポーターの典型的な出力は次のようになります:

{'name': 'Color TV', 'price': '1200'}
{'name': 'DVD player', 'price': '200'}

長大な行の場合は綺麗に(pretty)フォーマットされます。

JsonItemExporter

class scrapy.exporters.JsonItemExporter(file, **kwargs)[ソース]

アイテムをJSON形式で、指定のファイル様オブジェクトにエクスポートし、すべてのオブジェクトをオブジェクトのリストとして書き込みます。 追加の __init__ メソッドの引数は BaseItemExporter__init__ メソッドに渡され、残りの引数は JSONEncoder__init__ メソッドに渡されるため、あなたは任意の JSONEncoder__init__ メソッド引数を使用してこのエクスポーターをカスタマイズできます。

パラメータ

file -- データのエクスポートに使用するファイルのようなオブジェクト。 その write メソッドは bytes (バイナリ・モードで開かれたディスクファイルや、 io.BytesIO オブジェクトなど)を受け入れる必要があります

このエクスポーターの典型的な出力は次のようになります:

[{"name": "Color TV", "price": "1200"},
{"name": "DVD player", "price": "200"}]

警告

JSONは非常にシンプルで柔軟なシリアル化形式ですが、(すべての言語で)JSONパーサ間でインクリメンタル(別名ストリームモード)解析が(もしあれば)十分にサポートされていないため、大量のデータに対して適切に拡張できません。それらのほとんどは、メモリ内のオブジェクト全体を解析するだけです。よりストリーム・フレンドリーな形式でJSONのパワーとシンプルさを望む場合は、代わりに JsonLinesItemExporter を使用するか、出力を複数のチャンクに分割することを検討してください。

JsonLinesItemExporter

class scrapy.exporters.JsonLinesItemExporter(file, **kwargs)[ソース]

アイテムをJSON形式で、指定のファイル様オブジェクトにエクスポートし、1行に1つのJSONエンコードされたアイテムを書き込みます。 追加の __init__ メソッド引数は BaseItemExporter__init__ メソッドに渡され、残りの引数は JSONEncoder__init__ メソッドに渡されるため、あなたは任意の JSONEncoder__init__ メソッド引数を使用して、このエクスポーターをカスタマイズできます。

パラメータ

file -- データのエクスポートに使用するファイルのようなオブジェクト。 その write メソッドは bytes (バイナリ・モードで開かれたディスクファイルや、 io.BytesIO オブジェクトなど)を受け入れる必要があります

このエクスポーターの典型的な出力は次のようになります:

{"name": "Color TV", "price": "1200"}
{"name": "DVD player", "price": "200"}

JsonItemExporter によって生成される形式とは異なり、このエクスポーターによって生成される形式は、大量のデータをシリアル化するのに適しています。

MarshalItemExporter

class scrapy.exporters.MarshalItemExporter(file, **kwargs)[ソース]

Python固有のバイナリ形式でアイテムをエクスポートします( marshal 参照)。

パラメータ

file -- データのエクスポートに使用するファイルのようなオブジェクト。 その write メソッドは bytes (バイナリ・モードで開かれたディスク・ファイルや、 BytesIO オブジェクトなど)を受け入れる必要があります