使用Python requests调用Pushbullet API时遭遇SSLError问题求助
这个问题我碰到过不少次,核心原因是你用的Python 2.7环境里,requests和urllib3的版本太老,不支持Pushbullet API要求的现代TLS协议版本。下面给你拆解分析和具体的解决办法:
问题根源
你看到的SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure错误,本质是客户端(你的Python请求)和Pushbullet服务器的TLS协议不兼容。Pushbullet API现在只认TLS 1.2及以上版本,但Python 2.7自带的requests/urllib3版本(从路径/usr/lib/python2.7/dist-packages/requests/能看出来是系统预装的旧版)默认只启用了TLS 1.0这类老协议,自然握手失败。
至于curl能成功、谷歌接口能调用,是因为现代curl默认支持TLS 1.2+,而谷歌为了兼容性还保留了对旧协议的支持,刚好避开了这个问题。
具体解决方案
1. 升级requests和urllib3版本
先把环境里的requests和urllib3更到支持TLS1.2的版本,执行这条命令:
pip install --upgrade requests urllib3
如果是系统自带的requests(比如通过apt装的),可以加--ignore-installed强制覆盖:
pip install --upgrade --ignore-installed requests urllib3
(注意:强制覆盖系统包可能影响其他依赖,操作前最好确认环境)
2. 强制指定TLS1.2协议发起请求
如果升级后还是不行,就手动写个适配器,强制requests用TLS1.2发请求:
import requests import ssl from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager from urllib3.util import ssl_ # 自定义适配器,强制使用TLS1.2 class TLS12Adapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): ctx = ssl_.create_urllib3_context(ssl.PROTOCOL_TLSv1_2) self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx ) headers = {'Access-Token': '<my-access-token>'} url = 'https://api.pushbullet.com/v2/users/me' # 创建session并挂载适配器 session = requests.Session() session.mount('https://', TLS12Adapter()) # 这里建议去掉verify=False,除非你确实需要跳过证书验证(不安全) r = session.get(url, headers=headers) print(r.json())
3. 长远方案:迁移到Python3
Python 2.7早就停止维护了,很多库都不再更新对它的协议支持,包括TLS相关的适配。如果条件允许,赶紧转到Python3.x版本,不仅能彻底解决这类SSL问题,还能获得更安全的环境和更丰富的库支持。
验证
按上面的方法调整后,再执行请求,应该就能拿到和curl一样的Pushbullet用户信息了。
内容的提问来源于stack exchange,提问作者MohitC

