Несколько циклов с асинхронным
Возможно ли иметь несколько циклов с asyncio? Если да, то как я могу это сделать?
Мой вариант использования: * Я извлекаю URL-адреса из списка сайтов в async * Для каждого "списка юг-url" я сканирую их в async/
Пример для извлечения URL:
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()
Если я выполню этот код, у меня будет ошибка, когда python попытается запустить второй цикл, ведьма говорит, что цикл уже запущен.
P.S: мой модуль "extractsuburls" использует aiohttp для выполнения веб-запроса.
EDIT:
Ну, я попробовал это решение:
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()
Но у меня есть эта ошибка: аргумент loop должен соглашаться с Future
Любая идея?
Ответы
Ответ 1
Вам не нужно несколько циклов событий, просто используйте yield from gather(*subtasks)
в extracturls()
сопрограмме:
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()
В результате вы ожидаете подзадачи до завершения extracturls
.