在 Python 3.5 中使用 aiohttp 获取多个 url
Posted
技术标签:
【中文标题】在 Python 3.5 中使用 aiohttp 获取多个 url【英文标题】:Fetching multiple urls with aiohttp in Python 3.5 【发布时间】:2016-06-23 03:07:10 【问题描述】:自从 Python 3.5 引入 async with
以来,docs 中为 aiohttp
推荐的语法已经改变。现在获取他们建议的单个网址:
import aiohttp
import asyncio
async def fetch(session, url):
with aiohttp.Timeout(10):
async with session.get(url) as response:
return await response.text()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
with aiohttp.ClientSession(loop=loop) as session:
html = loop.run_until_complete(
fetch(session, 'http://python.org'))
print(html)
如何修改它以获取一组 url 而不是一个 url?
在旧的asyncio
示例中,您将设置一个任务列表,例如
tasks = [
fetch(session, 'http://cnn.com'),
fetch(session, 'http://google.com'),
fetch(session, 'http://twitter.com')
]
我尝试将这样的列表与上述方法结合起来,但失败了。
【问题讨论】:
你能解释一下你的失败吗? @AndrewSvetlov 很高兴收到您的来信。我的意思是我不明白该怎么做。当我定义一个任务列表然后使用results = loop.run_until_complete(tasks)
时,我得到一个运行时错误。 async with
是一个新功能,文献很少,如果aiohttp
文档显示了一个抓取多个 url 的示例,那么对于学习使用它的人来说会非常方便。图书馆看起来很棒,只需要一点手就可以开始。谢谢!
【参考方案1】:
对于并行执行,您需要asyncio.Task
我已将您的示例转换为从多个来源获取并发数据:
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
if response.status != 200:
response.raise_for_status()
return await response.text()
async def fetch_all(session, urls):
tasks = []
for url in urls:
task = asyncio.create_task(fetch(session, url))
tasks.append(task)
results = await asyncio.gather(*tasks)
return results
async def main():
urls = ['http://cnn.com',
'http://google.com',
'http://twitter.com']
async with aiohttp.ClientSession() as session:
htmls = await fetch_all(session, urls)
print(htmls)
if __name__ == '__main__':
asyncio.run(main())
【讨论】:
感谢一百万!接受您的回答,但是... 1. 括号的位置仍然有错字。如果你不介意我会编辑它。 2. 在我看来,我想打印print(html)
行欺骗的实际结果,而您实际上需要print('\n'.join(list((str(some_task._result) for some_tuple in html for some_task in some_tuple))))
之类的东西,也许可以将其添加到答案中? 3. 这看起来真的很有用,我建议在阅读文档中添加类似的内容。再次感谢! :)
安德鲁,我可以在哪里进行像if response.status == 200
这样的测试?如果一个 url 不存在,脚本会中断,我不明白在哪里检查 async with session.get(url) as response: return await response.text()
中的响应
感谢之前留下评论的其他人。我已经开始new question 澄清这一点。
aiohttp.ClientSession(loop=loop) 不再是有效的语法我收到错误:Use async with instead
请您更新答案以反映更改
asyncio.create_task
部分不是必需的。任务是从 3.7 中的协程创建的。以上是关于在 Python 3.5 中使用 aiohttp 获取多个 url的主要内容,如果未能解决你的问题,请参考以下文章