You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python访问ECMWF数据库遇SSL证书验证失败问题求助

问题:ECMWF API 遭遇SSL证书验证失败错误

我在Windows 8系统上使用Python 3.6.5,按照ECMWF官方指南尝试下载ERA-Interim数据,多次重试后还是碰到了ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]错误,以下是完整报错栈和示例代码,求解决办法。

环境信息

  • Python版本:3.6.5
  • 操作系统:Windows 8
  • ECMWF API版本:1.5.0

完整报错信息

================== RESTART: C:\Users\Giulio\Desktop\test.py ==================
2018-05-21 12:08:29 ECMWF API python library 1.5.0
2018-05-21 12:08:29 ECMWF API at https://api.ecmwf.int/v1
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Error contacting the WebAPI, retrying in 60 seconds ...
Could not contact the WebAPI after 10 tries, failing !
Traceback (most recent call last):
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 1318, in do_open
    encode_chunked=req.has_header('Transfer-encoding'))
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1026, in _send_output
    self.send(msg)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 964, in send
    self.connect()
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1400, in connect
    server_hostname=server_hostname)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 407, in wrap_socket
    _context=self, _session=session)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 814, in __init__
    self.do_handshake()
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 1068, in do_handshake
    self._sslobj.do_handshake()
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Giulio\Desktop\test.py", line 19, in <module>
    "target": "test.nc"
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\site-packages\ecmwfapi\api.py", line 519, in retrieve
    c = APIRequest(self.url, "datasets/%s" % (dataset,), self.email, self.key, self.trace, verbose=self.verbose)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\site-packages\ecmwfapi\api.py", line 391, in __init__
    user = self.connection.call("%s/%s" % (self.url, "who-am-i"))
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\site-packages\ecmwfapi\api.py", line 172, in wrapped
    raise last_error
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\site-packages\ecmwfapi\api.py", line 140, in wrapped
    return func(self, *args, **kwargs)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\site-packages\ecmwfapi\api.py", line 273, in call
    res = opener.open(req)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 526, in open
    response = self._open(req, data)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 544, in _open
    '_open', req)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 504, in _call_chain
    result = func(*args)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 1361, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "C:\Users\Giulio\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 1320, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>

示例代码

#!/usr/bin/env python
from ecmwfapi import ECMWFDataServer
server = ECMWFDataServer(
    url="https://api.ecmwf.int/v1",
    email="your-email@example.com",
    key="your-api-key"
)
server.retrieve({
    "dataset": "interim",
    "stream": "oper",
    "type": "an",
    "levtype": "sfc",
    "param": "167.128",
    "date": "2018-01-01",
    "time": "12:00:00",
    "target": "test.nc"
})

解决办法

我碰到过不少Windows 8 + Python 3.x用户遇到这个ECMWF API的SSL证书问题,给你几个靠谱的解决方案,按推荐程度排序:

1. 优先更新Python的根证书

Python 3.6在Windows上自带的根证书库往往比较老旧,没法识别ECMWF服务器的新证书。你可以这么操作:

  • 下载Mozilla官方维护的最新根证书文件cacert.pem
  • 找到你的Python安装路径下的Lib\site-packages\certifi文件夹,把里面原有的cacert.pem替换成刚下载的新版本
  • 或者不用替换,直接设置系统环境变量REQUESTS_CA_BUNDLE,让它指向你下载的新证书文件路径

2. 临时禁用SSL验证(仅限测试)

如果你只是临时跑测试,不想折腾证书,可以跳过SSL验证,但生产环境绝对别用,不安全:

  • 最简单的方式是在你的脚本最开头加上这两行:
    import ssl
    ssl._create_default_https_context = ssl._create_unverified_context
    
  • 或者你想更精准地修改ECMWF API的逻辑,找到ecmwfapi/api.py里的call方法,把创建opener的部分改成带未验证上下文的:
    import ssl
    context = ssl._create_unverified_context()
    opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=context))
    

3. 检查系统代理设置

Windows 8的代理经常会干扰SSL连接,尤其是公司网络下的代理:

  • 先试试关闭系统代理,直接连接网络看能不能解决
  • 如果必须用代理,确保代理的SSL证书已经被系统信任,或者在初始化ECMWF服务器时指定代理:
    server = ECMWFDataServer(
        url="https://api.ecmwf.int/v1",
        email="your-email@example.com",
        key="your-api-key",
        proxy="http://your-proxy-address:port"
    )
    

4. 升级ECMWF API库

你现在用的是1.5.0版本,这是2018年的老版本了,新版本大概率修复了不少SSL相关的兼容性问题:
打开命令提示符,执行升级命令:

pip install --upgrade ecmwf-api-client

内容的提问来源于stack exchange,提问作者giulio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:31:39