python用requests请求百度接口报“SSL: CERTIFICATE_VERIFY_FAILED”

在尝试使用Python的requests库调用百度语音识别API时遇到SSL证书验证失败的问题。错误提示为'SSL: CERTIFICATE_VERIFY_FAILED'。该问题源于Python 2.7.9以后版本对HTTPS请求进行证书验证。解决方案包括为urllib提供不验证证书的context,或在requests的请求中设置verify参数为False来禁用证书验证。

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

今天想试用一下百度的语音识别API,附带步骤:

1. 先去百度开放云平台注册,成为开发者,审核可能需要时间的,我去年申过现在账号还在

2. 然后创建一个应用

3.为创建完的应用添加服务,有俩,语音识别和语音生成

4. 这样我就有一个调用他语音识别接口的access_token了,这个token由于我采用的是API For Rest,要拿API_key和secret_key通过一个http请求获得,问题就出在这儿了

我用request按照他文档的样子Post了一下,又Get了一下都报一个验证失败的错误。

requests.post('https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=xxxxxxx&client_secret=xxxxxxx').content

 

requests.get('https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=xxxxxxx&client_secret=xxxxxxx').content


他告诉我:

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

找了一下,有人说原因是这样的:

Python 2.7.9 之后引入了一个新特性
当你urllib.urlopen一个 https 的时候会验证一次 SSL 证书 
当目标使用的是自签名的证书时就会爆出一个 
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)> 的错误消息

确实我用urllib试了一下结果一样,requests跟urllib是一样的。

那么要解决这个问题,PEP-0476的文档说

For users who wish to opt out of certificate verification on a single connection, they can achieve this by providing the contextargument to urllib.urlopen :

import ssl

# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)

It is also possible, though highly discouraged , to globally disable verification by monkeypatching the ssl module in versions of Python that implement this PEP:

import ssl

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    ssl._create_default_https_context = _create_unverified_https_context

就是说你可以禁掉这个证书的要求,urllib来说有两种方式,一种是urllib.urlopen()有一个参数context,把他设成ssl._create_unverified_context或者修改现在的全局默认值

_create_unverified_https_context

ssl._create_default_https_context

ssl._create_unverified_context

测试了一下,确实可以,返回了几个token,那么requests呢,难道必须设置全局变量吗。其实request的post和get都有一个叫verify的参数,把他设成False就可以了。

print requests.get('https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=xxxxx&client_secret=xxxxxxxx', verify=False).content

 

 

 

 

 

 

 

 

 

 

 


 

Python 中,`SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed` 错误通常发生在尝试通过 HTTPS 连接某个服务器时,Python 无法验证 SSL 证书。这可能由于证书过期、证书不受信任、缺少根证书或网络环境配置问题等原因引起。以下是几种常见的解决方法: ### 1. 手动安装 Python 的根证书 在某些操作系统(如 macOS)上,Python 3.x 可能无法自动找到系统的根证书存储。这会导致 `urllib.request.urlopen()` 或 `requests.get()` 等方法在访问 HTTPS 网站时失败。解决方法是手动安装 `certifi` 包,并将其证书路径配置为 Python 的默认信任证书路径。 ```python import ssl import certifi import urllib.request # 使用 certifi 提供的证书路径进行 HTTPS 请求 context = ssl.create_default_context(cafile=certifi.where()) response = urllib.request.urlopen("https://example.com", context=context) ``` ### 2. 禁用 SSL 证书验证(不推荐用于生产环境) 如果你处于测试环境中,可以临时禁用 SSL 证书验证。但需要注意的是,这样做会使连接变得不安全,容易受到中间人攻击。 ```python import ssl import urllib.request # 忽略 SSL 证书验证 context = ssl._create_unverified_context() response = urllib.request.urlopen("https://example.com", context=context) ``` ### 3. 更新系统或 Python 的证书存储 在某些系统中,Python 使用的证书可能已过期或缺失。可以尝试手动更新这些证书。例如,在 macOS 上,可以运行以下命令来安装最新的证书: ```bash /Applications/Python\ 3.x/Install\ Certificates.command ``` 该命令通常位于 Python 安装目录中,用于更新 Python 的信任证书库。 ### 4. 使用 `requests` 库并指定 `verify` 参数 如果你使用的是 `requests` 库,可以通过设置 `verify` 参数来控制是否验证 SSL 证书。推荐的做法是使用 `certifi` 提供的 CA 证书包。 ```python import requests import certifi # 使用 certifi 的证书进行验证 response = requests.get("https://example.com", verify=certifi.where()) ``` ### 5. 检查系统时间和证书有效期 SSL 证书依赖于系统时间。如果系统时间不正确,可能会导致证书被认为已过期或尚未生效。请确保系统时间准确。 ### 6. 使用代理或企业证书 如果你在使用公司代理或企业内部证书,可能需要将这些证书添加到 Python 的信任链中。可以使用 `ssl.create_default_context()` 并加载自定义证书: ```python import ssl import urllib.request context = ssl.create_default_context() context.load_verify_locations(cafile="/path/to/company-ca.crt") response = urllib.request.urlopen("https://internal.example.com", context=context) ``` ### 7. 升级 Python 版本 旧版本的 Python(如 3.6 及以下)可能使用过时的 SSL/TLS 实现。升级到 Python 3.7 或更高版本可以改善 SSL 证书验证的行为,并支持更多现代加密协议。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值