Несколько циклов с асинхронным

Возможно ли иметь несколько циклов с 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.