在前面的问题中,《aiohttp》的一位作者好心地建议使用Python 3.5中新的async with语法:

import aiohttp
import asyncio

async def fetch(session, url):
    with aiohttp.Timeout(10):
        async with session.get(url) as response:
            return await response.text()

async def fetch_all(session, urls, loop):
    results = await asyncio.wait([loop.create_task(fetch(session, url))
                                  for url in urls])
    return results

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    # breaks because of the first url
    urls = ['http://SDFKHSKHGKLHSKLJHGSDFKSJH.com',
            'http://google.com',
            'http://twitter.com']
    with aiohttp.ClientSession(loop=loop) as session:
        the_results = loop.run_until_complete(
            fetch_all(session, urls, loop))
        # do something with the the_results

然而,当session.get(url)个请求中的一个中断时(如上所述,由于http://SDFKHSKHGKLHSKLJHGSDFKSJH.com),错误不会得到处理,整个过程也会中断.

我想办法插入关于session.get(url)的测试结果,例如寻找try ... except ...if response.status != 200:的位置,但我不知道如何处理async withawait和各种对象.

由于async with仍然是非常新的,所以没有太多的例子.如果一个asyncio向导能演示如何做到这一点,对很多人都会很有帮助.毕竟,大多数人想用asyncio测试的第一件事就是同时获得多个资源.

Goal

我们的目标是,我们可以判断the_results个,并很快看到:

  • 此url失败(以及原因:状态代码,可能是异常名称),或
  • 这个url有效,下面是一个有用的响应对象

推荐答案

我将使用gather而不是wait,后者可以将异常作为对象返回,而不引发异常.然后,您可以判断每个结果,如果它是某个异常的实例.

import aiohttp
import asyncio

async def fetch(session, url):
    with aiohttp.Timeout(10):
        async with session.get(url) as response:
            return await response.text()

async def fetch_all(session, urls, loop):
    results = await asyncio.gather(
        *[fetch(session, url) for url in urls],
        return_exceptions=True  # default is false, that would raise
    )

    # for testing purposes only
    # gather returns results in the order of coros
    for idx, url in enumerate(urls):
        print('{}: {}'.format(url, 'ERR' if isinstance(results[idx], Exception) else 'OK'))
    return results

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    # breaks because of the first url
    urls = [
        'http://SDFKHSKHGKLHSKLJHGSDFKSJH.com',
        'http://google.com',
        'http://twitter.com']
    with aiohttp.ClientSession(loop=loop) as session:
        the_results = loop.run_until_complete(
            fetch_all(session, urls, loop))

测验:

$python test.py 
http://SDFKHSKHGKLHSKLJHGSDFKSJH.com: ERR
http://google.com: OK
http://twitter.com: OK

Python-3.x相关问答推荐

网站抓取:当我使用Chrome DevTools中的网络选项卡时,找不到正确的URL来提供我想要的数据

如果行在所有上级索引中都为0,如何删除下级索引行?

Python避免捕获特定异常

当索引大于一个整数而小于前一个索引时,我如何返回列值?

文件名中的文件打开和撇号

如何定义部署用 Python 编写的 Firestore 第二代函数的区域/位置?

torch.stack([t1, t1, t1], dim=1)与torch.hstack([t1, t1, t1])之间有什么区别?

在REPLACE INTO中引用变量会抛出sqlite3.OperationalError

使用Python按照其组/ID的紧密值的递增顺序映射数据框的两列

TypeError: issubclass() arg 1 在 Flask 中导入 langchain 时必须是一个类

有没有一种方法可以通过输入从 0 到 255 的 R、G 和 B 值来生成 RGB colored颜色 ,而无需使用 python 中的 matplotlib 模块?

如何在 20 秒后重复使用 Pillow 在现有图像上创建新图像?

将字典列表展平为数据框列

魔术8球txt文件列表

具有函数值的 Python 3 枚举

错误:预期语句,发现 py:Dedent

创建一个可旋转的 3D 地球

Python 解包运算符 (*)

在 Pandas 数据框中显示对图

为什么某些代码在 Python2 中是确定性的,而在 Python 3 中是非确定性的?