调用Wordnik API出现SSL证书验证失败错误的原因及求助
问题
刚注册Wordnik API密钥,用Python3运行官网示例代码时遭遇SSL证书验证失败错误,但浏览器直接调用API+密钥能正常返回结果。需要排查问题原因,同时求可用的示例代码。
原示例代码
from wordnik import * apiUrl = 'http://api.wordnik.com/v4' apiKey = 'MY API KEY REMOVED FOR THIS POSTING' client = swagger.ApiClient(apiKey, apiUrl) wordApi = WordApi.WordApi(client) example = wordApi.getTopExample('irony') print(example.text)
报错信息
/Users/dkanze/PycharmProjects/pythonProject2/.venv/bin/python /Users/dkanze/Library/Application Support/JetBrains/PyCharmCE2024.2/scratches/scratch_14.py Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 1319, in do_open h.request(req.get_method(), req.selector, req.data, headers, ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ encode_chunked=req.has_header('Transfer-encoding')) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/http/client.py", line 1336, in request self._send_request(method, url, body, headers, encode_chunked) ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/http/client.py", line 1382, in _send_request self.endheaders(body, encode_chunked=encode_chunked) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/http/client.py", line 1091, in _send_output self.send(msg) ~~~~~~~~~^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/http/client.py", line 1035, in send self.connect() ~~~~~~~~~~~~^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/http/client.py", line 1477, in connect self.sock = self._context.wrap_socket(self.sock, ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^ server_hostname=server_hostname) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/ssl.py", line 455, in wrap_socket return self.sslsocket_class._create( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ sock=sock, ^^^^^^^^^^ ...<5 lines>... session=session ^^^^^^^^^^^^^^^ ) ^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/ssl.py", line 1076, in _create self.do_handshake() ~~~~~~~~~~~~~~~~~^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/ssl.py", line 1372, in do_handshake self._sslobj.do_handshake() ~~~~~~~~~~~~~~~~~~~~~~~~~^^ ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1020) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/dkanze/Library/Application Support/JetBrains/PyCharmCE2024.2/scratches/scratch_14.py", line 7, in example = wordApi.getTopExample('irony') File "/Users/dkanze/PycharmProjects/pythonProject2/.venv/lib/python3.13/site-packages/wordnik/WordApi.py", line 225, in getTopExample response = self.apiClient.callAPI(resourcePath, method, queryParams, postData, headerParams) File "/Users/dkanze/PycharmProjects/pythonProject2/.venv/lib/python3.13/site-packages/wordnik/swagger.py", line 73, in callAPI request = urllib.request.urlopen(requestParams) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 189, in urlopen return opener.open(url, data, timeout) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 495, in open response = meth(req, response) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 604, in http_response response = self.parent.error( 'http', request, response, code, msg, hdrs) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 527, in error result = self._call_chain(*args) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 466, in _call_chain result = func(*args) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 720, in http_error_302 return self.parent.open(new, timeout=req.timeout) ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 489, in open response = self._open(req, data) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 506, in _open result = self._call_chain(self.handle_open, protocol, protocol + '_open', req) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 466, in _call_chain result = func(*args) File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 1367, in https_open return self.do_open(http.client.HTTPSConnection, req, ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ context=self._context) ^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/urllib/request.py", line 1322, in do_open raise URLError(err) urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1020)> Process finished with exit code 1
问题原因
- HTTP跳转HTTPS引发验证问题:原代码用的是
http://api.wordnik.com/v4,Wordnik服务器会把HTTP请求重定向到HTTPS,但Python的urllib处理重定向时,若本地CA证书不完整,就会触发SSL验证失败。 - Python环境证书缺失:官方安装包(尤其macOS系统)的Python默认可能未正确配置系统CA证书,导致无法验证HTTPS证书。
修复后的示例代码
方案1:直接使用HTTPS地址(推荐)
改用HTTPS地址避免重定向,直接建立安全连接:
from wordnik import * # 替换为HTTPS地址 apiUrl = 'https://api.wordnik.com/v4' apiKey = '你的API密钥' client = swagger.ApiClient(apiKey, apiUrl) wordApi = WordApi.WordApi(client) try: example = wordApi.getTopExample('irony') print(example.text) except Exception as e: print(f"请求出错: {str(e)}")
方案2:补全Python的CA证书(解决环境问题)
若仍遇证书问题,可手动补全CA证书:
- macOS系统:找到Python安装目录下的
Install Certificates.command并运行,自动安装缺失证书。 - 其他系统:安装certifi库后指定证书路径:
import ssl from wordnik import * import certifi apiUrl = 'https://api.wordnik.com/v4' apiKey = '你的API密钥' # 指定SSL证书路径 ssl_context = ssl.create_default_context(cafile=certifi.where()) client = swagger.ApiClient(apiKey, apiUrl) # 给swagger客户端配置SSL上下文 client.setSSLSocketFactory(ssl_context) wordApi = WordApi.WordApi(client) try: example = wordApi.getTopExample('irony') print(example.text) except Exception as e: print(f"请求出错: {str(e)}")
注意事项
- 不要在代码中硬编码API密钥,建议通过环境变量读取,比如
import os; apiKey = os.getenv('WORDNIK_API_KEY')。 - 优先选方案1,直接用HTTPS既避免重定向问题,也更安全。
内容的提问来源于stack exchange,提问作者99Valk
相关产品推荐
相关产品推荐

