运行此命令时,它会使用响应代码逐一列出数据库中的网站,而浏览一个很小的列表大约需要10秒钟。它应该更快一些,并且不会异步运行,但我不确定为什么。
import dblogin
import aiohttp
import asyncio
import async_timeout
dbconn = dblogin.connect()
dbcursor = dbconn.cursor(buffered=True)
dbcursor.execute("SELECT thistable FROM adatabase")
website_list = dbcursor.fetchall()
async def fetch(session, url):
with async_timeout.timeout(30):
async with session.get(url, ssl=False) as response:
await response.read()
return response.status, url
async def main():
async with aiohttp.ClientSession() as session:
for all_urls in website_list:
url = all_urls[0]
resp = await fetch(session, url)
print(resp, url)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
dbcursor.close()
dbconn.close()
答案 0 :(得分:1)
This article解释了详细信息。您需要做的是在Future
对象中传递每个访存调用,然后根据需要将这些列表传递给asyncio.wait
或asyncio.gather
。
您的代码应如下所示:
async def fetch(session, url):
with async_timeout.timeout(30):
async with session.get(url, ssl=False) as response:
await response.read()
return response.status, url
async def main():
tasks = []
async with aiohttp.ClientSession() as session:
for all_urls in website_list:
url = all_urls[0]
task = asyncio.create_task(fetch(session, url))
tasks.append(task)
responses = await asyncio.gather(*tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
future = asyncio.create_task(main())
loop.run_until_complete(future)
此外,您确定需要loop.close()
通话吗?文档提到了
调用此函数时,循环不得运行。任何待处理的回调都将被丢弃。
此方法清除所有队列并关闭执行程序,但不等待执行程序完成。
正如docs和@ user4815162342发布的链接中所提到的,当我们知道该参数是a时,最好使用create_task
方法而不是ensure_future
方法。协程。请注意,它是在Python 3.7中添加的,因此以前的版本应继续使用ensure_future
。