私のコードは次のとおりです:
import asyncio
import aiohttp
urls = [
'http://www.163.com/',
'http://www.sina.com.cn/',
'https://www.hupu.com/',
'http://www.csdn.net/'
]
async def get_url_data(u):
"""
read url data
:param u:
:return:
"""
print('running ', u)
resp = await aiohttp.ClientSession().get(url=u)
headers = resp.headers
print(u, headers)
return headers
async def request_url(u):
"""
main func
:param u:
:return:
"""
res = await get_url_data(u)
return res
loop = asyncio.get_event_loop()
task_lists = asyncio.wait([request_url(u) for u in urls])
loop.run_until_complete(task_lists)
loop.close()
コードを実行すると、警告メッセージが表示されます:nclosed client session
誰かが私にそれについていくつかの解決策を与えることができますか?
どうもありがとう
最後に接続を閉じる必要があります。次の2つのオプションがあります。
手動で接続を閉じることができます:
import aiohttp
session = aiohttp.ClientSession()
# use the session here
session.close()
または、contexマネージャで使用できます。
import aiohttp
import asyncio
async def fetch(client):
async with client.get('http://python.org') as resp:
assert resp.status == 200
return await resp.text()
async def main(loop):
async with aiohttp.ClientSession(loop=loop) as client:
html = await fetch(client)
print(html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
クライアントセッションは、セルフクローズ用のコンテキストマネージャプロトコルをサポートしています。
リソースを適切にブロック/解放するには、非同期コンテキストマネージャを使用してClientSession
を使用する必要があります。
async def get_url_data(u):
"""
read url data
:param u:
:return:
"""
print('running ', u)
async with aiohttp.ClientSession() as session:
resp = await session.get(url=u)
headers = resp.headers
print(u, headers)
return headers
コンテキストマネージャを使用していない場合は、適切に閉じる方法でもawait
が必要になります。ほとんどの人がより便利なコンテキストマネージャーを使用しているためと考えられ、インターネット上の多くの回答はその部分を見逃しており、実際にそれに気づく人はほとんどいません。ただし、unittest
ingを実行するときにawait session.close()
内のクラス全体のセッションを閉じる場合、手動のtearDownClass()
は不可欠です。
import aiohttp
session = aiohttp.ClientSession()
# use the session here
await session.close()