python python-3.x asynchronous python-asyncio aiohttp

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 .