python用requests請求百度介面報“SSL: CERTIFICATE_VERIFY_FAILED”
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按照他文件的樣子
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