代码示例
import aiohttp
import asyncio
async def main(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
print("Status:", response.status)
print("Content-type:", response.headers['content-type'])
html = await response.text()
print("Body:", html[:15], "...")
url = "https://shikimori.one/"
loop = asyncio.get_event_loop()
loop.run_until_complete(main(url))
回溯
Traceback (most recent call last):
File "D:\projects\parser\test\test_aiohttp.py", line 20, in <module>
loop.run_until_complete(main(url))
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
return future.result()
File "D:\projects\parser\test\test_aiohttp.py", line 8, in main
async with session.get(url) as response:
File "D:\projects\parser\venv\lib\site-packages\aiohttp\client.py", line 1117, in __aenter__
self._resp = await self._coro
File "D:\projects\parser\venv\lib\site-packages\aiohttp\client.py", line 520, in _request
conn = await self._connector.connect(
File "D:\projects\parser\venv\lib\site-packages\aiohttp\connector.py", line 535, in connect
proto = await self._create_connection(req, traces, timeout)
File "D:\projects\parser\venv\lib\site-packages\aiohttp\connector.py", line 892, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
File "D:\projects\parser\venv\lib\site-packages\aiohttp\connector.py", line 1051, in _create_direct_connection
raise last_exc
File "D:\projects\parser\venv\lib\site-packages\aiohttp\connector.py", line 1020, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
File "D:\projects\parser\venv\lib\site-packages\aiohttp\connector.py", line 971, in _wrap_create_connection
raise ClientConnectorCertificateError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host shikimori.one:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1129)')]
我的配置:
如果我收到带有 ssl=False 参数的请求,一切正常。但我认为这不是解决问题的正确方法。
所以你需要为你的Python版本安装证书。在 Mac 上,您可以在终端窗口中运行以下命令,它应该可以解决您的问题。
/Applications/Python\ 3.10/Install\ Certificates.command
我想我解决了问题。您可以安装 certifi 并使用其证书。
import aiohttp
import asyncio
import ssl
import certifi
async def main(url):
ssl_context = ssl.create_default_context(cafile=certifi.where())
conn = aiohttp.TCPConnector(ssl=ssl_context)
async with aiohttp.ClientSession(connector=conn) as session:
async with session.get(url) as response:
print("Status:", response.status)
url = "https://shikimori.one/"
loop = asyncio.get_event_loop()
loop.run_until_complete(main(url))
原因
出现此问题的原因是根证书“DST Root CA X3”证书已过期。证书的详细信息位于链接,https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/
尽管浏览器正常,但 Python SSL 库无法正确使用此证书。
补救措施
从可能存在的所有证书存储中删除证书“DST Root CA X3”。这将解决该问题。
详情
有关发生此问题的原因以及访问某些工具以获取更多详细信息,请查看此位置的自述文件https://github.com/vivekuppal/transcribe/tree/main/examples/deepgram
此链接讨论 SSL 验证失败的 Deepgram API 相关问题,但根本原因是相同的。