Desde que Python 3.5 introdujo async with
la syntax recomendada en los documentos para aiohttp
ha cambiado. Ahora para obtener un solo url sugieren:
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)
¿Cómo puedo modificar esto para obtener una colección de urls en lugar de solo una url?
En los viejos ejemplos de asyncio
usted configuraría una lista de tareas como
tasks = [ fetch(session, 'http://cnn.com'), fetch(session, 'http://google.com'), fetch(session, 'http://twitter.com') ]
Intenté combinar una lista como esta con el enfoque anterior, pero fracasé.
Para la ejecución paralela necesitas un asyncio.Task
He convertido su ejemplo a la obtención simultánea de datos de varias fonts:
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())