首页 文章

在Python 3.5中使用aiohttp获取多个URL

提问于
浏览
8

由于Python 3.5引入了 async withdocsaiohttp推荐的语法已经改变 . 现在要获得一个网址,他们建议:

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)

我怎样才能修改这个以获取网址集合而不只是一个网址?

在旧的 asyncio 示例中,您将设置一个任务列表,例如

tasks = [
            fetch(session, 'http://cnn.com'),
            fetch(session, 'http://google.com'),
            fetch(session, 'http://twitter.com')
            ]

我试图将这样的列表与上面的方法结合起来但是失败了 .

1 回答

  • 16

    对于并行执行,您需要一个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):
        results = await asyncio.gather(*[asyncio.create_task(fetch(session, url))
                                       for url in urls])
        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())
    

相关问题