scrapy で カスタムアウトプットする。

scrapy crawl 'crawler' -o outpu.csv

というような方法で spiderを動かして結果をファイルに吐き出すことができます。

-o output.csvであればcsvで書き出されますし、-o output.jsonであればjsonで書き出されます。

この書き出し方について、カスタマイズしようという趣旨の話です。

scrapy rawl にて -oオプションを利用して出力する場合、 FeedExporterというものが利用されます。

これはscrapyの設定settings.pyにて利用するExporterを指定することができるようになっています。

具体的には

FEED_EXPORTERS = {
    'csv' = 'path.to.CustomExporter',
    'sample' = 'path.to.SampleExporter`
}

というように行うことで、拡張子ごとに利用するExporterを指定するという方法で行います。

では、Exporterはどう実装するのか。 公式ドキュメント Item Exporters — Scrapy 1.5.1 documentation に記載がありますが、

BaseItemExporterを継承し、__init__ でファイルオブジェクトを受取り、export_itemで受け取ったアイテムをファイルオブジェクトに書き出す。

というのが基本になります。

class SampleExporter(BaseItemExporter):
    def __init__(self, file, **kwargs):
        self.file = file
        super().__init__(**kwargs)

    def export_item(self, item):
        record = str(item).encode('utf-8') + b'\n'
        self.file.write(record)

のような形ですね。

この状態で scrapy crawl 'spider' -o output.sample とやると、単純にitemを文字列にシリアライズした結果が出力されていきます。

scrapy/exporters.py at master · scrapy/scrapy · GitHub にデフォルトで用意されているFeedExporterがありますので、参考にしましょう。