コルーチン

バージョン 2.0 で追加.

Scrapy は、 コルーチン構文部分的にサポート しています。

呼び出し可能オブジェクト(callable)サポート

以下の呼び出し可能オブジェクト(callable)は、 async def を使用してコルーチンとして定義できるため、コルーチン構文を使用します(例: await, async for, async with):

使い方

Scrapyのコルーチンにはいくつかのユースケースがあります。 ダウンローダー・ミドルウェアやシグナル・ハンドラーなど、以前のScrapyバージョン用に記述されたときにDeferredを返すコードは、より短く、よりクリーンになるように書き直すことができます:

from itemadapter import ItemAdapter

class DbPipeline:
    def _update_item(self, data, item):
        adapter = ItemAdapter(item)
        adapter['field'] = data
        return item

    def process_item(self, item, spider):
        adapter = ItemAdapter(item)
        dfd = db.get_some_data(adapter['id'])
        dfd.addCallback(self._update_item, item)
        return dfd

上記は以下のようになります:

from itemadapter import ItemAdapter

class DbPipeline:
    async def process_item(self, item, spider):
        adapter = ItemAdapter(item)
        adapter['field'] = await db.get_some_data(adapter['id'])
        return item

コルーチンは、非同期コードを呼び出すために使用できます。 これには、他のコルーチン、Deferredを返す関数、および Future などの awaitableオブジェクト を返す関数が含まれます。 これは、そのようなコードを提供する多くの便利なPythonライブラリを使用できることを意味します:

class MySpider(Spider):
    # ...
    async def parse_with_deferred(self, response):
        additional_response = await treq.get('https://additional.url')
        additional_data = await treq.content(additional_response)
        # ... use response and additional_data to yield items and requests

    async def parse_with_asyncio(self, response):
        async with aiohttp.ClientSession() as session:
            async with session.get('https://additional.url') as additional_response:
                additional_data = await r.text()
        # ... use response and additional_data to yield items and requests

注釈

aio-libs などのコルーチンを使用する多くのライブラリは asyncio ループを必要とし、それらを使用するには Scrapyで非同期サポートを有効にする 必要があります。

非同期コードの一般的な使用例は以下のとおりです:

  • ウェブサイトとデータベースとその他のサービス(コールバック、パイプライン、ミドルウェア)からのデータのリクエスト。

  • (パイプラインおよびミドルウェアの)データベースにデータを保存する。

  • ( spider_opened ハンドラー内の)何らかの外部イベントまでスパイダーの初期化を遅らせる。

  • ExecutionEngine.download のような非同期Scrapyメソッドを呼び出す( スクリーンショット・パイプライン 参照)。