调用CWB开放气象API获取XML数据连接报错及大文件解析问题求助
问题解决指南
一、连接报错(WinError 10061)解决方法
- 修正API协议:台湾气象局开放数据API现已全面停用HTTP协议,统一使用HTTPS,将
api_link前缀修改为https://opendata.cwb.gov.tw/opendataapi即可解决大部分连接拒绝问题。 - 校验授权参数:确认
authorized_key已正确赋值,无多余空格、特殊字符,可在平台个人中心确认密钥未过期、接口权限正常。 - 网络环境排查:
- 关闭本地代理、VPN软件后重试,部分代理规则会拦截跨区域API请求
- 执行cmd命令
ping opendata.cwb.gov.tw确认本地网络到目标域名的连通性 - 若处于公司/校园网络环境,确认防火墙未拦截该域名请求,可切换个人网络重试
- 请求配置优化:添加超时、重试机制,避免偶发网络波动导致请求失败,参考配置:
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 配置重试策略 session = requests.Session() retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504] ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("https://", adapter) session.mount("http://", adapter) # 发起请求 try: # 大文件建议开启stream流式传输,配合后续XML流式解析更省内存 response = session.get(api_link, timeout=10, stream=True) response.encoding = 'utf-8' except Exception as e: print(f"请求失败: {e}")
二、大体积XML文件高效读取方法
不要使用et.fromstring()直接加载整个XML到内存,推荐使用iterparse流式解析,边读取边处理,仅提取目标节点,内存占用可控制在MB级,示例代码如下:
from xml.etree.ElementTree import iterparse # 示例为提取台北市的气象数据,可根据实际需求修改目标字段 target_location = "台北市" result = [] # 直接传入流式响应对象,边下载边解析 context = iterparse(response.raw, events=("start", "end")) _, root = next(context) for event, elem in context: if event == "end" and elem.tag == "location": loc_name = elem.findtext("locationName") if loc_name == target_location: # 按实际XML结构调整节点路径,提取需要的字段 weather = elem.findtext(".//parameter[parameterName='天氣現象']/parameterValue") max_temp = elem.findtext(".//parameter[parameterName='最高溫度']/parameterValue") result.append({ "location": loc_name, "weather": weather, "max_temp": max_temp }) # 处理完当前节点立即清空,释放内存 root.clear() print(result)
补充说明:解析前先确认返回XML的节点层级结构,调整标签名、查找路径匹配实际格式即可。
内容的提问来源于stack exchange,提问作者Dominic Sham
相关产品推荐
相关产品推荐

