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

如何解决Python下载NOAA数据时的SSL CERTIFICATE_VERIFY_FAILED错误

问题描述

在Airflow 2.1(运行于Amazon Linux 2的EC2实例,Python 3.7)上运行DAG从NOAA公开数据集下载文件时,持续遭遇SSL证书验证错误:

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1091)>

负责下载的代码片段:

import urllib.request
from contextlib import closing
from shutil import copyfileobj
from time import sleep
from airflow import AirflowException
import certifi
import ssl 


# Set the SSL certificate authority bundle to use certifi
ssl_context = ssl.create_default_context(cafile=certifi.where())
        
# download file
tries = 0
while tries < 5:
    try:
        with closing(urllib.request.urlopen(url, context=ssl_context)) as r:
            with open(cdc_file, "wb") as f:
                copyfileobj(r, f)
            print("File has been downloaded and copied successfully")
            break
    except Exception as e:
        print(f"####### Error: {str(e)} #######")
        print("####### Sleeping for 10 secs before trying again #######")
        sleep(10)
        print("####### Trying again #######")
        tries += 1
        if tries >= 5:
            raise AirflowException("It wasn't possible to download NOAA files due to connection refused by NOAA's server")
        continue

已尝试但无效的方法:

  • 开发环境创建未验证SSL上下文(生产环境不可用,且返回403 Forbidden)
  • 添加10秒休眠的循环重试机制
  • 更新certifi和ssl包
  • 通过openssl s_client -connect downloads.psl.noaa.gov:443 -showcerts获取CA证书并创建自定义pem文件
可行解决方法

方法1:使用系统级CA证书替代certifi

Amazon Linux 2的系统CA证书存储在/etc/pki/tls/certs/ca-bundle.crt,直接指定该路径创建SSL上下文:

# 替换原SSL上下文初始化代码
ssl_context = ssl.create_default_context(cafile="/etc/pki/tls/certs/ca-bundle.crt")

系统级CA bundle通常包含更完整的公共CA证书,可覆盖certifi缺失的根CA。

方法2:追加自定义CA证书到系统CA bundle

若之前通过openssl获取的CA证书有效,将其追加到系统默认CA文件:

sudo cat /path/to/your/custom-noaa-ca.pem >> /etc/pki/tls/certs/ca-bundle.crt

之后重启Airflow服务,确保进程读取更新后的CA列表:

sudo systemctl restart airflow-webserver airflow-scheduler

方法3:排查代理证书问题

如果EC2通过企业代理访问外网,代理可能替换SSL证书,需添加代理CA到信任列表:

  1. 获取代理CA证书并保存为proxy-ca.pem
  2. 追加到系统CA bundle:
sudo cat proxy-ca.pem >> /etc/pki/tls/certs/ca-bundle.crt
  1. 在Airflow配置中设置代理(或代码中配置):
    修改airflow.cfg:
[core]
http_proxy = http://your-proxy:port
https_proxy = https://your-proxy:port

或在代码中添加代理配置:

proxy_handler = urllib.request.ProxyHandler({'http': 'http://your-proxy:port', 'https': 'https://your-proxy:port'})
opener = urllib.request.build_opener(proxy_handler)
urllib.request.install_opener(opener)

方法4:使用完整证书链文件

重新获取NOAA服务器的完整证书链:

openssl s_client -connect downloads.psl.noaa.gov:443 -showcerts < /dev/null | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{print}' > full-noaa-chain.pem

在代码中指定该完整链文件:

ssl_context = ssl.create_default_context(cafile="/path/to/full-noaa-chain.pem")

内容的提问来源于stack exchange,提问作者Fábio Antunes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:47:07