2

我正在尝试使用 python 包resuqests_html异步 get() 一个 URL 列表,类似于使用 Python 3.6.5 和 requests_html 0.10.0的 README 中的异步示例。

我的理解是 AsyncHTMLSession.run() 应该与 asyncio.gather() 的工作方式非常相似:你给它一堆等待,它运行所有的。这是不正确的吗?

这是我正在尝试的代码,我希望它应该获取页面并存储响应:

from requests_html import AsyncHTMLSession

async def get_link(url):
    r = await asession.get(url)
    return r

asession = AsyncHTMLSession()
results = asession.run(get_link("http://google.com"), get_link("http://yahoo.com"))

但我得到了这个例外:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    results = asession.run(get_link("google.com"), get_link("yahoo.com"))
  File ".\venv\lib\site-packages\requests_html.py", line 772, in run
    asyncio.ensure_future(coro()) for coro in coros
  File ".\venv\lib\site-packages\requests_html.py", line 772, in <listcomp>
    asyncio.ensure_future(coro()) for coro in coros
TypeError: 'coroutine' object is not callable
sys:1: RuntimeWarning: coroutine 'get_link' was never awaited

难道我做错了什么?

4

1 回答 1

3

难道我做错了什么?

你没有asession.run正确调用。

asyncio.gather接受等待对象,例如通过调用协程(异步)函数获得的协程对象。asession.run另一方面,它接受callables,例如异步函数,它将调用它来产生 awaitables。区别就像一个函数接受一个可迭代的,你可以传递一个实例化的生成器,另一个接受一个可调用的返回一个迭代的函数,你可以传递一个生成器函数本身。

由于你的异步函数有参数,你不能只传递get_linkasession.run; 您必须使用functools.partialor lambda 本身:

results = asession.run(
    lambda: get_link("http://google.com"),
    lambda: get_link("http://yahoo.com"),
)
于 2019-11-13T22:47:56.190 回答