Asyncioで複数のループを持つことは可能ですか?応答が「はい」の場合、どうすればそれを行うことができますか?私のユースケースは次のとおりです。*非同期のWebサイトのリストからURLを抽出します*「サブURLリスト」ごとに、非同期でクロールします/
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が2番目のループを起動しようとすると、エラーが発生します。魔女は、ループがすでに実行されていると言います。
追伸:私のモジュール「extractsuburls」はaiohttpを使用してWebリクエストを実行します。
編集:
さて、私はこの解決策を試しました:
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()
しかし、私はこのエラーがあります:ループ引数はFutureと一致する必要があります
何か案が?
複数のイベントループは必要ありません。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
が終了するまでサブタスクを待機します。