アイテム・エクスポーター¶
アイテムをスクレイピングしたら、他のアプリケーションでデータを使用するために、それらのアイテムを永続化またはエクスポートすることがよくあります。 つまり、結局のところ、それがスクレイピング・プロセス全体の目的です。
この目的のために、Scrapyは、XML、CSV、JSONなどのさまざまな出力形式のアイテム・エクスポーターのコレクションを提供します。
アイテム・エクスポーターの使用¶
あなたが急いでいて、アイテム・エクスポータを使用してスクレイプ・データを出力するだけの場合は、 フィード・エクスポート を参照してください。それ以外の場合または、アイテム・エクスポータがどのように機能するかを知りたい場合または、またはより多くのカスタム機能(デフォルトのエクスポートではカバーされてない機能)が必要な場合は、以下をお読みください。
アイテム・エクスポーターを使用するには、必要な引数でインスタンス化する必要があります。 各アイテム・エクスポーターには異なる引数が必要なため、 組み込みアイテム・エクスポーター・リファレンス で各エクスポーターのドキュメントを確認してください。エクスポーターをインスタンス化した後、以下の作業が必要です:
1.エクスポート・プロセスの開始を通知するために、メソッド start export()
を呼び出します。
2.エクスポートする各アイテムに対して export_item()
メソッドを呼び出します
3.最後に finish export()
を呼び出して、エクスポート・プロセスの終了を通知します
以下の アイテム・パイプライン をご覧ください。これは、複数のアイテム・エクスポーターを使用して、それらのフィールドの値に従って、スクレイプされたアイテムを異なるファイルにグループ化します:
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
アイテム・フィールドのシリアル化¶
デフォルトでは、フィールド値は変更されずに基礎となるシリアル化ライブラリに渡され、それらをシリアル化する方法の決定は特定の各シリアル化ライブラリに委任されます。
ただし、あなたは、各フィールド値をシリアル化する方法を、 シリアル化ライブラリに渡す前の段階で カスタマイズできます。
フィールドのシリアル化方法をカスタマイズするには、以下の2つの方法があります。
1. フィールドでシリアライザーを宣言する¶
あなたが Item
を使用する場合、 フィールド・メタ・データ でシリアライザーを宣言できます。シリアライザーは、値を受け取り、シリアル化された形式を返す、呼び出し可能オブジェクトでなければなりません。
例:
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()
メソッドをオーバーライドして、フィールド値のエクスポート方法をカスタマイズすることもできます。
カスタムコードの後に必ずベースクラス serialize_field()
メソッドを呼び出してください。
例:
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)
組み込みアイテム・エクスポーター・リファレンス¶
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)¶ これは、すべてのアイテム・エクスポーターの(抽象的な)基本クラスです。 エクスポートするフィールド、空のフィールドをエクスポートするか、使用するエンコードを定義するなど、すべての(具体的な)アイテム・エクスポーターで使用される共通機能のサポートを提供します。
これらの機能は、それぞれのインスタンス属性を設定するコンストラクター引数で構成(configure)できます:
fields_to_export
、export_empty_fields
、encoding
、indent
-
export_item
(item)¶ 与えられたアイテムをエクスポートします。このメソッドはサブクラスで実装する必要があります。
-
serialize_field
(field, name, value)¶ 指定のフィールドのシリアル化された値を返します。特定のフィールドまたは値をシリアル化/エクスポートする方法を制御する場合は、カスタム・アイテム・エクスポーターでこのメソッドをオーバーライドできます。
デフォルトでは、このメソッドは 項目フィールドで宣言 されたシリアライザーを探し、そして、そのシリアライザーを値に適用した結果を返します。シリアライザーが見つからない場合、
encoding
属性で宣言されたエンコーディングを使用してstr
にエンコードされるunicode
値を除いて、値を変更せずに返します。
-
start_exporting
()¶ エクスポート・プロセスの開始を通知します。一部のエクスポーターはこれを使用して、必要なヘッダー(
XmlItemExporter
など)を生成します。アイテムをエクスポートする前に、このメソッドを呼び出す必要があります。
-
finish_exporting
()¶ エクスポート・プロセスの終了を通知します。一部のエクスポーターはこれを使用して、必要なフッター(たとえば、
XmlItemExporter
)を生成します。エクスポートするアイテムがなくなったら、常にこのメソッドを呼び出す必要があります。
-
fields_to_export
¶ エクスポートされるフィールドの名前のリスト、またはすべてのフィールドをエクスポートする場合はNone。デフォルトはNoneです。
一部のエクスポーター(
CsvItemExporter
など)は、この属性で定義されたフィールドの順序を尊重します。一部のエクスポーターは、スパイダーが辞書を返すときにデータを適切にエクスポートするために、fields_to_exportリストを必要とする場合があります(
Item
インスタンスではありません)。
-
export_empty_fields
¶ エクスポートされたデータに空/未入力の項目フィールドを含めるかどうか。デフォルトは
False
です。 一部のエクスポーター(CsvItemExporter
など)はこの属性を無視し、常にすべての空のフィールドをエクスポートします。このオプションは、辞書アイテムでは無視されます。
-
encoding
¶ ユニコード値をエンコードするために使用されるエンコード。これは、ユニコード値(このエンコードを使用して常にstrにシリアル化される)にのみ影響します。他の値の型は変更されずに特定のシリアル化ライブラリに渡されます。
-
indent
¶ 各レベルで出力をインデントするために使用されるスペースの量。デフォルトは
0
です。indent=None
は、全てのアイテムを同一行にインテント無しで出力する、最もコンパクトな表現を選択しますindent<=0
はアイテム毎に行を分けますが、インデントはありませんindent>0
はアイテム毎に行を分け、指定した数値でインデントします
-
PythonItemExporter¶
XmlItemExporter¶
-
class
scrapy.exporters.
XmlItemExporter
(file, item_element='item', root_element='items', **kwargs)¶ 指定のファイルオブジェクトにアイテムをXML形式でエクスポートします。
- パラメータ
このコンストラクタの追加のキーワード引数は、
BaseItemExporter
コンストラクタに渡されます。このエクスポーターの典型的な出力は次のようになります:
<?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=', ', **kwargs)¶ 与えられたファイルのようなオブジェクトにCSV形式でアイテムをエクスポートします。
fields_to_export
属性が設定されている場合、CSV列とその順序を定義するために使用されます。export_empty_fields
属性はこのエクスポーターには影響しません。- パラメータ
file -- データのエクスポートに使用するファイルのようなオブジェクト。 その
write
メソッドはbytes
(バイナリ・モードで開かれたディスクファイルや、io.BytesIO
オブジェクトなど)を受け入れる必要がありますinclude_headers_line (str) -- 有効にすると、エクスポーターは
BaseItemExporter.fields_to_export
または最初にエクスポートされたアイテム・フィールドから取得したフィールド名を含むヘッダー行を出力します。join_multivalued -- 複数値フィールドを結合するために使用される単一文字(または複数の文字)。
このコンストラクタの追加のキーワード引数は
BaseItemExporter
コンストラクタに渡され、残りの引数は 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 module documentation を参照してください。
このコンストラクタの追加のキーワード引数は、
BaseItemExporter
コンストラクタに渡されます。pickleは人間が読める形式ではないため、出力例はありません。
PprintItemExporter¶
-
class
scrapy.exporters.
PprintItemExporter
(file, **kwargs)¶ 指定のファイルオブジェクトにきれいな(pretty)印刷形式でアイテムをエクスポートします。
- パラメータ
file -- データのエクスポートに使用するファイルのようなオブジェクト。 その
write
メソッドはbytes
(バイナリ・モードで開かれたディスクファイルや、io.BytesIO
オブジェクトなど)を受け入れる必要があります
このコンストラクタの追加のキーワード引数は、
BaseItemExporter
コンストラクタに渡されます。このエクスポーターの典型的な出力は次のようになります:
{'name': 'Color TV', 'price': '1200'} {'name': 'DVD player', 'price': '200'}
(存在する場合)長い行はきれいに(pretty)フォーマットされます。
JsonItemExporter¶
-
class
scrapy.exporters.
JsonItemExporter
(file, **kwargs)¶ アイテムをJSON形式で、指定されたファイルのようなオブジェクトにエクスポートし、すべてのオブジェクトをオブジェクトのリストとして書き込みます。追加のコンストラクター引数は
BaseItemExporter
コンストラクターに、残りの引数は JSONEncoder コンストラクターに渡されるため、任意の JSONEncoder コンストラクター引数を使用してこのエクスポーターをカスタマイズできます。- パラメータ
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行にJSONエンコードされたアイテムを1つ書き込みます。追加のコンストラクター引数は
BaseItemExporter
コンストラクターに、残りの引数は JSONEncoder コンストラクターに渡されるため、任意の JSONEncoder コンストラクター引数を使用してこのエクスポーターをカスタマイズできます。- パラメータ
file -- データのエクスポートに使用するファイルのようなオブジェクト。 その
write
メソッドはbytes
(バイナリ・モードで開かれたディスクファイルや、io.BytesIO
オブジェクトなど)を受け入れる必要があります
このエクスポーターの典型的な出力は次のようになります:
{"name": "Color TV", "price": "1200"} {"name": "DVD player", "price": "200"}
JsonItemExporter
によって生成される形式とは異なり、このエクスポーターによって生成される形式は、大量のデータをシリアル化するのに適しています。