CircuitPython环境下树莓派Pico调用天气API证书验证失败求助
解决CircuitPython树莓派Pico调用天气API证书验证失败问题
在CircuitPython环境的树莓派Pico上,调用worldtimeapi正常,但调用weatherapi.com的天气API时出现证书验证错误,报错核心信息如下:
x509-crt-bundle:Failed to verify certificate
OSError: (-12288, 'MBEDTLS_ERR_X509_FATAL_ERROR')
RuntimeError: Sending request failed
以下是三种可行的解决方案:
方案1:手动添加目标API的根证书(推荐)
CircuitPython默认的证书 bundle可能未包含weatherapi.com使用的根证书,手动加载对应根证书即可解决:
- 获取weatherapi.com的根证书:通过浏览器访问该API地址,查看证书详情,导出PEM格式的根证书(通常是Let's Encrypt系列根证书)
- 在代码中加载该证书,替换默认SSL上下文:
import ssl import socketpool import wifi import adafruit_requests import json # 替换为你导出的PEM格式根证书内容 ROOT_CERT = """-----BEGIN CERTIFICATE----- # 此处粘贴根证书完整内容 -----END CERTIFICATE-----""" pool = socketpool.SocketPool(wifi.radio) # 创建带自定义根证书的SSL上下文 ssl_context = ssl.create_default_context() ssl_context.load_verify_locations(cadata=ROOT_CERT) requests = adafruit_requests.Session(pool, ssl_context) # 天气API请求代码 url = "https://api.weatherapi.com/v1/current.json?key=你的API密钥&q=Berlin" response = requests.get(url) data = json.loads(response.text) print(data["temp_c"])
方案2:临时禁用证书验证(仅测试用)
如果只是临时测试功能,可以禁用SSL证书验证,但生产环境绝对不要使用,会带来明文传输、中间人攻击等安全风险:
import ssl import socketpool import wifi import adafruit_requests import json pool = socketpool.SocketPool(wifi.radio) # 禁用证书验证 ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE requests = adafruit_requests.Session(pool, ssl_context) # 后续请求代码不变 url = "https://api.weatherapi.com/v1/current.json?key=你的API密钥&q=Berlin" response = requests.get(url) data = json.loads(response.text) print(data["temp_c"])
方案3:更新CircuitPython及相关库
部分旧版CircuitPython的证书bundle可能过时,尝试更新到最新版本:
- 下载最新版CircuitPython固件刷入树莓派Pico
- 从Adafruit官方库bundle中获取最新的
adafruit_requests.mpy及相关SSL依赖库,替换Pico上lib文件夹内的对应文件
内容的提问来源于stack exchange,提问作者L L
相关产品推荐
相关产品推荐

