我正在使用 Python 3.7.3 对我网站上托管的 PHP 文件运行 GET 请求。但是,当我运行它时,我收到以下错误。我已经requests
通过pip3
Homebrew 安装了。我正在使用 macOS Mojave。
回溯(最近调用最后):
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py”,第 600 行,在 urlopen chunked=chunked)
文件中“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py”,第 343 行,在 _make_request self._validate_conn(conn)
文件“/Library/Frameworks/Python .framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py”,第 839 行,在 _validate_conn conn.connect()
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib /python3.7/site-packages/urllib3/connection.py”,第 344 行,在连接 ssl_context=context 中)
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/util/ssl_.py”,第 344 行,在 ssl_wrap_socket
返回 context.wrap_socket(sock, server_hostname=server_hostname)
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py”,第 412 行,在 wrap_socket session=session
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib /python3.7/ssl.py”,第 853 行,在 _create self.do_handshake()
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py”,第 1117 行,在do_handshake self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1056)在处理上述异常的过程中,又出现了一个异常:
追溯(最近调用最后):
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/adapters.py”,第 449 行,在发送超时=超时
文件“ /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py”,第 638 行,在 urlopen _stacktrace=sys.exc_info()[2])
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/util/retry.py”,第 398 行,递增 raise MaxRetryError(_pool, url, error or ResponseError(原因)) urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='ijetlab.com', port=443): 最大重试次数超过 url: /api/api.php?one=1&two=2 (由 SSLError(SSLCertVerificationError(1 , '[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1056)')))在处理上述异常的过程中,又出现了一个异常:
回溯(最近一次调用最后一次):
文件“/Users/maxwellnewberry/Documents/test.py”,第 12 行,在 r = requests.get(url = URL, params = PARAMS)
文件“/Library/Frameworks/Python.framework /Versions/3.7/lib/python3.7/site-packages/requests/api.py”,第 75 行,在 get return request('get', url, params=params, **kwargs)
File “/Library/Frameworks /Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/api.py”,第60行,在请求返回session.request(method=method, url=url, **kwargs)
File” /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py”,第 533 行,请求 resp = self.send(prep, **send_kwargs)
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py”,第 646 行,在 send r = adapter.send(request, **kwargs)
文件中“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/adapters.py”,第 514 行,在发送中引发 SSLError(e, request=request) requests.exceptions.SSLError : HTTPSConnectionPool(host='ijetlab.com', port=443): 最大重试次数超过 url: /api/api.php?one=1&two=2 (由 SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书引起验证失败:无法获取本地颁发者证书 (_ssl.c:1056)')))
这是代码:
# importing the requests library
import requests
# api-endpoint
URL = "https://ijetlab.com/api/api.php"
# defining a params dict for the parameters to be sent to the API
PARAMS = {'one':1, 'two':2}
# sending get request and saving the response as response object
r = requests.get(url = URL, params = PARAMS)
# extracting data in json format
data = r.json()
print(data['response'])
所有搜索都告诉我运行“Install Certificates.command”,我已经运行了大约 100 次。我也让客户安装了证书。
长话短说
远程网站似乎是问题所在,而不是 Python。除了修复网站外,可能没有其他解决方法。
更长的解释
您正在处理的网站/服务器显然配置不正确。这与 Python 没有直接关系。也就是说,您可以忽略任何证书错误,例如:
或者您可以尝试将 Python 指向丢失的证书(正如 @dave_thompson_085 在评论中指出的那样)。
但是,这不太可能起到任何作用,因为服务器随后显然会响应一个
500: Internal Server Error
(已验证curl
)和一个Content-Length: 0
,这似乎表明其api.php
自身处理过程中存在错误(即无论如何都没有要处理的 JSON)。如果您在解密流量的企业环境中工作,或者可能是代理服务器作为 VPN 的一部分,那么我发现该
certifi
库无法在证书包中包含解密服务器的证书。这使您只剩下 1 个好的解决方案、1 个平庸的解决方案和 1 个糟糕的解决方案。糟糕的解决方案是不验证证书。平庸的解决方案是要求您的 IT 部门将您尝试联系的网站列入白名单,但对于您尝试联系的每个新网站,您都必须一遍又一遍地询问他们。David Tippet 在以下链接中有一篇关于此问题的非常好的文章。 https://levelup.gitconnected.com/fixing-your-ssl-verify-errors-in-python-71c2201db4b2
那么,什么是好的解决方案呢?您必须首先在您的 IT 部门找到可以为您提供 SSL 解密服务器的 URL 或 IP 地址的人,或者您可以要求他们为您提供服务器的 base64 格式的 .pem 文件。这是一个人类可读的明文文件,看起来像这样:
证书示例
它将有 7 行,以注释开头
#
,一行说-----BEGIN CERTIFICATE-----
,一行以 结尾-----END CERTIFICATE-----
。打开你的 python 环境并检查你是否有
certifi
命令:import certifi
然后找出 Python 正在使用的证书链在您的计算机上的位置
certifi.where()
导航到 返回的文件路径
certifi.where()
并制作该文件的副本,以防您破坏某些内容。我的位置在这里:'C:\Users\user_name\Anaconda3\envs\gispy\lib\site-packages\certifi\cacert.pem'
打开该 .txt 文件并将代理/解密服务器的整个证书复制并粘贴到
cacert.pem
文件末尾。现在你的requests
电话应该工作了。我认为服务器不一定是问题所在。我正在做类似的事情,但我的前两行如下。
将熊猫导入为 pd
BCD = pd.read_csv(' https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer/breast-cancer.data ')
我在装有 Mojave 10.14.6 的 MacBook Pro 和装有 Windows 10 企业版 10.0.17134 的 Microsoft Surface 上同时执行此操作,两者都使用 Jupyter。我的 Python 安装都是 3.7.3。
两者都通过同一个家庭 Wi-Fi 访问互联网。
Surface 在第一次尝试时就抓住了它。MacBook 给了我与 OP 相同的错误。
所以,UCI 数据库的服务器不太可能是问题所在。
在我们的案例中,问题与由自己的 CA 根证书和中间证书签署的 SSL 证书有关。解决方案是 - 在找到 certifi 的 cacert.pem 文件的位置(导入 certifi;certifi.where())之后 - 将自己的 CA Root & Intermediates 附加到 cacert.pem 文件。当然,那些自己的证书是 PEM 格式的。