如何解决使用urllib而不绕过SSL验证时出现[SSL: CERTIFICATE_VERIFY_FAILED]错误

问题描述 投票:0回答:2
import urllib.request
import json
    
gojson = 'https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=17025436&class=highway&addressdetails=1&hierarchy=0&group_hierarchy=1&format=json&polygon_geojson=1'
res_body = urllib.request.urlopen(gojson).read()

错误:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1129)>

我知道我可以使用此代码来解决该错误:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

但我更想知道如何解决这个问题。我在网上搜索时无法找到解决方案。有什么建议吗?

python ssl urllib
2个回答
1
投票

一种方法是传递

urllib.request.urlopen()
可选的“cafile”参数以及受信任 CA 包的完整路径,例如由 certifi 生成的“cacert.pem”文件。这可以使用
certifi
包中的 certifi.where() 来完成。

示例,使用您的代码片段:

import certifi  #added import
import json
import urllib.request


gojson = 'https://nominatim.openstreetmap.org/details.php?osmtype=W&osmid=17025436&class=highway&addressdetails=1&hierarchy=0&group_hierarchy=1&format=json&polygon_geojson=1'
res_body = urllib.request.urlopen(gojson, cafile=certifi.where()).read() #modified function call to add cafile argument

当然,您可以使用您想要的任何文件或路径,我只是提供了上面的示例,因为它需要在本地文件系统上进行较少的探索,并且对于最少的工作量来说似乎相对值得信赖。通常,使用经过验证/受信任的 CA 捆绑包而不是关闭 ssl 验证是一种更安全的做法,这是一个很好的问题。

我的环境: macOS 大苏尔, Python 3.9

参考资料:

  1. [用于提供 Mozilla 的 CA Bundle 的 Python 包。] https://pypi.org/project/certifi/
  2. [软件包存储库] https://github.com/certifi/python-certifi
  3. 【功能详情】https://docs.python.org/3.9/library/urllib.request.html?highlight=urlopen#urllib.request.urlopen
  4. [证书颁发机构] https://www.ssl.com/faqs/what-is-a-certificate-authority/

0
投票

如果您使用的是 Ubuntu 机器,那么:

sudo apt install ca-certificates
sudo update-ca-certificates --fresh
export SSL_CERT_DIR=/etc/ssl/certs

如果您使用的是 Mac 或者需要以其他方式处理,请参考以下答案:

urllib 和“SSL:CERTIFICATE_VERIFY_FAILED”错误

© www.soinside.com 2019 - 2024. All rights reserved.