协同程序¶
2.0 新版功能.
刮痧 partial support 对于 coroutine syntax .
支持的可调用项¶
以下可调用项可以定义为使用 async def
,因此使用协同程序语法(例如。 await
, async for
, async with
):
Request
回电。注解
在整个回调完成之前,不会处理回调输出。
作为副作用,如果回调引发异常,则不会处理其任何输出。
这是对当前实现的一个已知警告,我们将在Scrapy的未来版本中解决这个问题。
这个
process_item()
方法 item pipelines .这个
process_request()
,process_response()
和process_exception()
方法 downloader middlewares .
使用¶
Scrapy中有几个协同程序的用例。在为以前的垃圾版本(如下载程序中间件和信号处理程序)编写时,会返回延迟的代码可以重写为更简短、更干净:
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
异步协同程序可用于调用。这包括其他协同程序、返回延迟的函数和返回的函数 awaitable objects 如 Future
. 这意味着您可以使用许多有用的Python库来提供以下代码:
class MySpiderDeferred(Spider):
# ...
async def parse(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
class MySpiderAsyncio(Spider):
# ...
async def parse(self, response):
async with aiohttp.ClientSession() as session:
async with session.get('https://additional.url') as additional_response:
additional_data = await additional_response.text()
# ... use response and additional_data to yield items and requests
注解
例如许多类库 aio-libs ,需要 asyncio
循环并使用它们你需要 enable asyncio support in Scrapy .
注解
如果你想 await
在使用异步反应器时,您需要 wrap them 。
异步代码的常见用例包括:
从网站、数据库和其他服务(回调、管道和中间件)请求数据;
在数据库中存储数据(在管道和中间件中);
将spider初始化延迟到某个外部事件(在
spider_opened
经办人);调用诸如
ExecutionEngine.download
(见 the screenshot pipeline example )