1. ホーム
  2. python

[解決済み] 1つのScrapyプロジェクトで、スパイダーごとにパイプラインを使い分けるには?

2023-01-26 04:15:33

質問

私は複数のスパイダーを含むscrapyプロジェクトを持っています。 どのパイプラインをどのスパイダーに使用するかを定義する方法はありますか?私が定義したパイプラインのすべてが、すべてのスパイダーに適用されるわけではありません。

ありがとうございます。

どのように解決するのですか?

構築する Pablo Hoffmanによる解決策 の解決策をもとに、次のようなデコレータを process_item メソッドをチェックするようにします。 pipeline 属性をチェックします。例えば

def check_spider_pipeline(process_item_method):

    @functools.wraps(process_item_method)
    def wrapper(self, item, spider):

        # message template for debugging
        msg = '%%s %s pipeline step' % (self.__class__.__name__,)

        # if class is in the spider's pipeline, then use the
        # process_item method normally.
        if self.__class__ in spider.pipeline:
            spider.log(msg % 'executing', level=log.DEBUG)
            return process_item_method(self, item, spider)

        # otherwise, just return the untouched item (skip this step in
        # the pipeline)
        else:
            spider.log(msg % 'skipping', level=log.DEBUG)
            return item

    return wrapper

このデコレータが正しく動作するためには、スパイダーは、例えばアイテムを処理するために使用したい Pipeline オブジェクトのコンテナを持つ pipeline 属性を持っている必要があります。

class MySpider(BaseSpider):

    pipeline = set([
        pipelines.Save,
        pipelines.Validate,
    ])

    def parse(self, response):
        # insert scrapy goodness here
        return item

そして、その中に pipelines.py というファイルを作成します。

class Save(object):

    @check_spider_pipeline
    def process_item(self, item, spider):
        # do saving here
        return item

class Validate(object):

    @check_spider_pipeline
    def process_item(self, item, spider):
        # do validating here
        return item

すべてのパイプラインオブジェクトは、設定のITEM_PIPELINESで定義されるべきです(正しい順序で -- Spiderでも順序を指定できるように変更されるとよいでしょう)。