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
但我更想知道如何解决这个问题。我在网上搜索时无法找到解决方案。有什么建议吗?
一种方法是传递
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
参考资料:
如果您使用的是 Ubuntu 机器,那么:
sudo apt install ca-certificates
sudo update-ca-certificates --fresh
export SSL_CERT_DIR=/etc/ssl/certs
如果您使用的是 Mac 或者需要以其他方式处理,请参考以下答案: