Mac上用aiohttp请求YouTube时关闭SSL验证的安全性及问题解决
问题描述
在2022款MacBook M2设备上使用Python的aiohttp库发送GET请求时,频繁遇到SSL验证失败异常。已参考相关问题并应用certifi补丁,但问题仍未解决。设置ssl=False参数后请求可正常工作,但清楚这并非正确做法,其危险性取决于请求场景。需求是从YouTube服务器获取数据并写入文件,虽已阅读过关闭SSL证书验证安全性的讨论,但仍不确定该场景下是否安全,因此咨询:
- 该场景下关闭SSL证书验证的安全性如何?
- 是否有其他解决SSL验证失败问题的方法?
附错误日志:
Traceback (most recent call last): File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/connector.py", line 980, in _wrap_create_connection return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 1112, in create_connection transport, protocol = await self._create_connection_transport( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 1145, in _create_connection_transport await waiter File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/sslproto.py", line 574, in _on_handshake_complete raise handshake_exc File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/sslproto.py", line 556, in _do_handshake self._sslobj.do_handshake() File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ssl.py", line 979, in do_handshake self._sslobj.do_handshake() ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:1002) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/Users/wade/test.py", line 12, in <module> asyncio.run(main()) File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/Users/wade/test.py", line 9, in main async with session.get(url) as resp: File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/client.py", line 1141, in __aenter__ self._resp = await self._coro ^^^^^^^^^^^^^^^^ File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/client.py", line 536, in _request conn = await self._connector.connect( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/connector.py", line 540, in connect proto = await self._create_connection(req, traces, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/connector.py", line 901, in _create_connection _, proto = await self._create_direct_connection(req, traces, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/connector.py", line 1206, in _create_direct_connection raise last_exc File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/connector.py", line 1175, in _create_direct_connection transp, proto = await self._wrap_create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/wade/Library/Python/3.11/lib/python/site-packages/aiohttp/connector.py", line 984, in _wrap_create_connection raise ClientConnectorSSLError(req.connection_key, exc) from exc aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host stackoverflow.com:443 ssl:default [[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:1002)]
解决方案与安全性分析
一、关闭SSL证书验证的安全性风险
别以为只是获取YouTube公开数据就没事——关闭SSL验证等于直接放弃了对服务器身份的校验,中间人可以轻松伪装成YouTube服务器:
- 给你返回篡改过的数据:比如把正常视频数据替换成带恶意代码的文件,写入本地后运行就会中招;
- 窃取你的请求信息:哪怕是GET请求,你的IP地址、访问记录等信息也可能被拦截;
- 无法保证数据真实性:你拿到的可能不是真正的YouTube数据,甚至被植入广告、恶意跳转链接等,后续处理会引发问题。
总之,不管什么场景,关闭SSL验证都是给自己埋安全隐患,绝对不能长期使用。
二、解决SSL验证失败的靠谱方法
1. 修复Mac Python的根证书(最常见解决办法)
Mac上的Python经常会出现系统根证书未正确加载的情况,直接找到Python安装目录里的Install Certificates.command脚本双击运行即可。
如果找不到脚本,在终端执行对应你Python版本的命令(以下是Python3.11的示例路径):
/opt/local/Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11 /opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/certifi/wincertstore.py
若你用Homebrew安装Python,路径会有所不同,搜索对应版本的Install Certificates.command即可。
2. 给aiohttp手动指定certifi证书
创建ClientSession时,明确告诉aiohttp使用certifi提供的证书:
import aiohttp import ssl import certifi async def main(): # 创建带正确证书的SSL上下文 ssl_ctx = ssl.create_default_context(cafile=certifi.where()) # 将上下文传入aiohttp连接器 async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=ssl_ctx)) as session: async with session.get("你的YouTube请求URL") as resp: data = await resp.read() # 写入文件操作 with open("output_file", "wb") as f: f.write(data)
3. 检查代理或VPN设置
有时候代理、VPN会拦截SSL连接,导致证书验证失败。先关闭代理/VPN后重新测试请求,若恢复正常,就需要调整代理的SSL相关设置。
4. 更新依赖库
老版本的aiohttp或certifi可能存在兼容性问题,在终端执行升级命令:
pip install --upgrade aiohttp certifi
内容的提问来源于stack exchange,提问作者Trevor Philip
相关产品推荐
相关产品推荐

