コルーチン¶
バージョン 2.0 で追加.
Scrapy は、 コルーチン構文 を 部分的にサポート しています。
呼び出し可能オブジェクト(callable)サポート¶
以下の呼び出し可能オブジェクト(callable)は、 async def
を使用してコルーチンとして定義できるため、コルーチン構文を使用します(例: await
, async for
, async with
):
Request
コールバック。注釈
コールバックの出力は、コールバック全体が終了するまで処理されません。
よって、その副作用として、コールバックで例外が発生した場合、その出力は処理されません。
これは、Scrapyの将来のバージョンでは対処することを目指してはいますが、現在の実装で判明している注意事項です。
アイテム・パイプライン の
process_item()
メソッド。ダウンローダー・ミドルウェア の
process_request()
とprocess_response()
とprocess_exception()
メソッド。
使い方¶
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メソッドを呼び出す( スクリーンショット・パイプライン 参照)。