首页 > 解决方案 > 尝试在 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)

标签: python-3.x

解决方案


好的,我实际上找到了一个似乎适用于此的解决方案。以下代码使我能够更新和/或安装我的系统似乎没有或没有注意到的任何所需的 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 程序,现在成功接收到请求的坐标。

我希望这是有帮助的!


推荐阅读