python-3.x - 尝试在 geopy 中运行地理编码器时出现 [SSL: CERTIFICATE_VERIFY_FAILED] 错误如何验证证书以获得所需的输出?
问题描述
我正在学习 Python 的 Udemy 课程,并且正在使用 pandas。目前,我正在使用 geopy 来尝试返回输入地址的坐标。特别是,我正在运行 ArcGIS 地理编码,但是当我运行它时,我收到一个 SSL 错误,说它无法获得 SSL 证书。我将在此处包含代码和错误:
这是我试图与我应该得到的输出一起运行的代码。下面是我实际得到的输出:
In [1]: from geopy.geocoders import ArcGIS
...: nom = ArcGIS()
...: nom.geocode("3995 23rd St, San Francisco, CA 94114")
Out[1]: Location(3995 23rd St, San Francisco, California, 94114, (37.75298458728149, -122.4317017142651, 0.0))
>>> import geopy
>>> from geopy import ArcGIS
>>> nom = ArcGIS()
>>> nom.geocode("3995 23rd St, San Francisco, CA 94114")
回溯(最后一次调用):文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py”,第 1317 行,在 do_open encode_chunked=req.has_header('Transfer- encoding')) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第 1229 行,在请求中 self._send_request(method, url, body, headers, encode_chunked ) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第 1275 行,_send_request self.endheaders(body, encode_chunked=encode_chunked) 文件“/Library/Frameworks /Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第 1224 行,在 endheaders self._send_output(message_body, encode_chunked=encode_chunked) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第 1016 行,在 _send_output self.send(msg) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7 /http/client.py”,第 956 行,在发送 self.connect() 文件中“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第 1392 行,在连接 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)
在处理上述异常的过程中,又出现了一个异常:
Traceback(最近一次调用最后):文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/geopy/geocoders/base.py”,第344行,在_call_geocoder页面=请求者(req, timeout=timeout, **kwargs) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py”,第 525 行,打开响应 = self._open( req,数据)文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py”,第543行,在_open'_open',req)文件“/Library/Frameworks/ Python.framework/Versions/3.7/lib/python3.7/urllib/request.py”,第 503 行,在 _call_chain 结果 = func(*args) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/ python3.7/urllib/request.py",第 1360 行,在 https_open context=self 中。_context, check_hostname=self._check_hostname) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py”,第 1319 行,在 do_open 中引发 URLError(err) urllib.error。网址错误:
在处理上述异常的过程中,又出现了一个异常:
Traceback(最近一次调用最后一次):文件“”,第 1 行,在文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/geopy/geocoders/arcgis.py”中,第 195 行,在地理编码响应 = self._call_geocoder(url, timeout=timeout) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/geopy/geocoders/base.py” ,第 375 行,在 _call_geocoder 中引发 GeocoderServiceError(message) geopy.exc.GeocoderServiceError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1056)
解决方案
好的,我实际上找到了一个似乎适用于此的解决方案。以下代码使我能够更新和/或安装我的系统似乎没有或没有注意到的任何所需的 SSL 证书。我将附上代码以及我发现工作解决方案的堆栈和源代码所在的 Github:
# install_certifi.py
#
# sample script to install or update a set of default Root Certificates
# for the ssl module. Uses the certificates provided by the certifi package:
# https://pypi.org/project/certifi/
import os
import os.path
import ssl
import stat
import subprocess
import sys
STAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
| stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
| stat.S_IROTH | stat.S_IXOTH )
def main():
openssl_dir, openssl_cafile = os.path.split(
ssl.get_default_verify_paths().openssl_cafile)
print(" -- pip install --upgrade certifi")
subprocess.check_call([sys.executable,
"-E", "-s", "-m", "pip", "install", "--upgrade", "certifi"])
import certifi
# change working directory to the default SSL directory
os.chdir(openssl_dir)
relpath_to_certifi_cafile = os.path.relpath(certifi.where())
print(" -- removing any existing file or link")
try:
os.remove(openssl_cafile)
except FileNotFoundError:
pass
print(" -- creating symlink to certifi certificate bundle")
os.symlink(relpath_to_certifi_cafile, openssl_cafile)
print(" -- setting permissions")
os.chmod(openssl_cafile, STAT_0o775)
print(" -- update complete")
if __name__ == '__main__':
main()
这是我找到解决方案的堆栈。 这是源代码所在的 Github。
我亲自将这段代码复制到 Sublime 中并保存为 .py 文件,然后在 python3 中运行程序。运行程序后,我尝试使用 ArcGIS 重新运行我的 geopy 程序,现在成功接收到请求的坐标。
我希望这是有帮助的!
推荐阅读
- python - 当我运行 ./darknet detection demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -ext_output test.mp4 时到底在运行什么?
- google-apps-script - 更改单元格选择时显示警报弹出窗口 (onSelectionChange)
- python - TypeError:迭代 0 维数组 Python(图像检测)
- php - 在 PHP 开发服务器 win 10 上更改 imagick 的权限或更改 tmp 目录
- grails - Grails 4.0.1 应用程序第一次加载页面在重启后需要一些时间
- ios - UIView 渐变作为多次应用的扩展
- python - python----错误的名字是'TypeError: not all arguments conversion during string formatting'(っ°Д°;)っ
- haskell - 无法在 Haskell IDE 的 Playground 中编写类型声明
- vue.js - 如何将引导程序添加到 Vue CLI 4 项目?
- laravel - 其他 Laravel 的选定值的下拉问题