python - MĂșltiples bucles con asyncio.
python-3.x asynchronous (1)
¿Es posible tener múltiples bucles con asyncio? Si la respuesta es sí, ¿cómo puedo hacer eso? Mi caso de uso es: * Extraigo las URL de una lista de sitios web en async * Para cada "lista de sub url", las rastrearía en async /
Ejemplo para extraer urls:
import asyncio
import aiohttp
from suburls import extractsuburls
@asyncio.coroutine
def extracturls(url):
subtasks = []
response = yield from aiohttp.request(''GET'', url)
suburl_list = yield from response.text()
for suburl in suburl_list:
subtasks.append(asyncio.Task(extractsuburls(suburl)))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*subtasks))
if __name__ == ''__main__'':
urls_list = [''http://example1.com'', ''http://example2.com'']
for url in url_list:
subtasks.append(asyncio.Task(extractsuburls(url)))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*subtasks))
loop.close()
Si ejecuto este código, tendré un error cuando Python intentará iniciar el segundo bucle, el cual dice que ya se está ejecutando un bucle.
PD: mi módulo "extractuburls" utiliza aiohttp para realizar la solicitud web.
EDITAR:
Bueno, he intentado esta solución:
import asyncio
import aiohttp
from suburls import extractsuburls
@asyncio.coroutine
def extracturls( url ):
subtasks = []
response = yield from aiohttp.request(''GET'', url)
suburl_list = yield from response.text()
jobs_loop = asyncio.new_event_loop()
for suburl in suburl_list:
subtasks.append(asyncio.Task(extractsuburls(suburl)))
asyncio.new_event_loop(jobs_loop)
jobs_loop.run_until_complete(asyncio.gather(*subtasks))
jobs_loop.close()
if __name__ == ''__main__'':
urls_list = [''http://example1.com'', ''http://example2.com'']
for url in url_list:
subtasks.append(asyncio.Task(extractsuburls(url)))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*subtasks))
loop.close()
Pero tengo este error: el argumento loop debe estar de acuerdo con el futuro
¿Alguna idea?
No necesita varios bucles de eventos, solo use el yield from gather(*subtasks)
en extracturls()
coroutine:
import asyncio
import aiohttp
from suburls import extractsuburls
@asyncio.coroutine
def extracturls(url):
subtasks = []
response = yield from aiohttp.request(''GET'', url)
suburl_list = yield from response.text()
for suburl in suburl_list:
subtasks.append(extractsuburls(suburl))
yield from asyncio.gather(*subtasks)
if __name__ == ''__main__'':
urls_list = [''http://example1.com'', ''http://example2.com'']
for url in url_list:
subtasks.append(extractsuburls(url))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*subtasks))
loop.close()
Como resultado, obtienes la espera de subtareas hasta que finalicen las extracturls
.