从 curl 到封装:腾讯天气 API 的工程化接入指南

发布时间:2026/7/26 15:50:00

从 curl 到封装:腾讯天气 API 的工程化接入指南 为什么需要从 curl 走向工程封装在调试阶段一条简单的curl命令就能验证接口是否通畅、返回数据是否合理。但一旦要将天气预报、生活指数等功能集成到生产系统里curl就远远不够了——你需要处理网络抖动时的重试、接口限流、参数校验、日志记录、响应解析异常等。本文以腾讯天气 API 为例展示如何从原型级的curl一步一步过渡到一个可维护、可扩展的工程封装。接口能力与适用场景腾讯天气 API 提供了基于中文省市名的天气数据查询无需经纬度坐标。主要能力包括实时天气温度、湿度、风向风力、天气现象、更新时间空气质量AQI、PM2.5、PM10、质量等级未来 7 天预报每日最高/最低温度24 小时逐时预报每个整点的温度和天气23 项生活指数穿衣、紫外线、洗车、运动等日出日落时间每日的具体时刻机动车限行根据城市及区县返回限行尾号典型使用场景智能家居控制面板显示室外天气旅游 App 提供目的地未来一周天气概览物流调度系统结合天气与限行规划路线个人助手自动推送当日穿衣建议和限行提醒请求参数与鉴权接口基本信息项目内容请求方法POST请求地址https://v1.apizero.cn/api/tencent-weather数据格式JSONQPS 上限10 次/秒Header 参数参数名必填类型说明Authorization否stringBearer 你的 API Key不传时使用默认匿名额度较低注意官方文档中也可使用X-API-Key头部传递密钥两种方式等价选择其一即可。Body 参数JSON字段名必填类型描述示例值province是string省 / 直辖市中文名广东city是string市中文名深圳county否string区 / 县中文名提升定位精度及限行准确度南山{ province: 广东, city: 深圳, county: 南山 }curl 快速验证curl -sS \ -X POST \ -H X-API-Key: $APIZERO_API_KEY \ -H Content-Type: application/json \ -d {province: 广东, city: 深圳, county: 南山} \ https://v1.apizero.cn/api/tencent-weather如果返回的 JSON 中code为 0则表示请求成功。若未传入 API Key匿名额度为每日 500 次通常也足够调试。响应字段解读成功响应示例已精简{ code: 0, msg: 成功, request_id: abc123, data: { observe: { temperature: 30, weather: 多云, humidity: 77, wind_direction: 北风, wind_power: 3-4, update_time: 2026-07-01 10:15 }, air: { aqi: 13, level: 1, quality: 优, pm25: 4, pm10: 12 }, daily_forecast: [ { date: 2026-07-01, temperature: { max: 33, min: 26 } } ], hourly_forecast: [ { time: 07-01 10:00, temperature: 30, weather: 多云 } ], life_index: [ { key: clothes, name: 穿衣, level: 炎热, detail: 建议穿着轻薄衣物 } ], sunrise_sunset: [ { date: 2026-07-01, sunrise: 05:43, sunset: 19:12 } ], limit: { date: 2026-07-01, tail_number: 3和8 }, location: { province: 广东, city: 深圳, county: 南山 }, alarm: [] } }关键字段说明顶层字段说明code状态码0 表示成功非 0 表示异常msg状态描述request_id请求唯一标识可用于排查问题data.observe实时观测数据data.air空气质量data.daily_forecast未来 7 天预报数组data.hourly_forecast未来 24 小时逐时预报数组data.life_index生活指数数组data.sunrise_sunset日出日落时间数组data.limit限行信息若无限制可能返回空对象data.alarm预警信息数组通常为空异常与错误处理常见 HTTP 状态码状态码含义排查方向200正常但需检查业务 code 是否非 0解析 JSON 的业务码401未授权或密钥错误检查 API Key 是否正确、是否过期429请求频率超过 QPS 限制增加请求间隔或实现本地排队与重试5xx服务端异常适当等待后重试若持续则联系服务商业务错误码code 字段codemsg原因处理方式1001参数缺失缺少必填字段 province/city校验请求参数完整性1002地区不存在省市名无法匹配数据库提示用户检查名称或提供候选1003密钥不可用API Key 无效或已超出额度检查密钥或等待额度重置工程化封装Python 示例现以一个WeatherClient类为例将 curl 的调用思想转化为具备健壮性的代码封装。import requests import logging from time import sleep from typing import Optional, Dict, Any logger logging.getLogger(WeatherClient) class WeatherClient: 腾讯天气客户端封装 BASE_URL https://v1.apizero.cn/api/tencent-weather DEFAULT_TIMEOUT 10 # 秒 MAX_RETRIES 3 RETRY_BACKOFF 1.5 # 重试间隔倍数 def __init__(self, api_key: Optional[str] None): self.api_key api_key self.session requests.Session() # 每次请求都带上 Content-Type self.session.headers.update({Content-Type: application/json}) if api_key: # 两种鉴权方式任选其一这里使用 Authorization Headers self.session.headers[Authorization] fBearer {api_key} def _do_request(self, payload: Dict[str, str]) - requests.Response: 执行 POST 请求包含重试逻辑 for attempt in range(self.MAX_RETRIES): try: resp self.session.post( self.BASE_URL, jsonpayload, timeoutself.DEFAULT_TIMEOUT, ) resp.raise_for_status() # 触发 HTTP 层面的错误 return resp except requests.exceptions.Timeout: logger.warning(f请求超时剩余重试次数 {self.MAX_RETRIES - attempt - 1}) except requests.exceptions.ConnectionError as e: logger.error(f连接错误: {e}) except requests.exceptions.HTTPError as e: status e.response.status_code # 4xx 错误除了 429 通常不应重试 if 400 status 500 and status ! 429: raise logger.warning(fHTTP {status}剩余重试次数 {self.MAX_RETRIES - attempt - 1}) if attempt self.MAX_RETRIES - 1: sleep(self.RETRY_BACKOFF ** attempt) raise RuntimeError(f请求失败已重试 {self.MAX_RETRIES} 次) def get_weather(self, province: str, city: str, county: Optional[str] None) - Dict[str, Any]: 查询天气 :param province: 省/直辖市 :param city: 市 :param county: 区县可选 :return: 解析后的 JSON data 字段 payload {province: province, city: city} if county: payload[county] county response self._do_request(payload) result response.json() if result.get(code) ! 0: logger.error(f业务错误: code{result.get(code)}, msg{result.get(msg)}, request_id{result.get(request_id)}) raise ValueError(f天气查询失败: {result.get(msg)}) return result[data] # 使用示例 if __name__ __main__: logging.basicConfig(levellogging.INFO) client WeatherClient(api_keyyour-api-key-here) try: data client.get_weather(广东, 深圳, 南山) print(f当前温度: {data[observe][temperature]}°C) print(f空气质量: {data[air][quality]}) print(f建议衣着: {[i[detail] for i in data[life_index] if i[key] clothes][0]}) except Exception as e: print(f异常: {e})封装要点说明连接复用使用requests.Session()保持连接池避免每次请求都新建 TCP 连接。超时控制timeout10防止接口异常时进程卡死。日志记录记录每次失败和成功的关键信息request_id 用于排查。业务错误码校验不仅检查 HTTP 状态码还解析 JSON 中的code字段确保业务逻辑正确。类型提示使用 Python 类型注解提升代码可维护性。工程化注意事项生产环境补充频率控制QPS 上限为 10若多个微服务共享同一个 API Key需在客户端做本地限流如令牌桶避免触发 429。缓存策略天气数据变化不算频繁实时温度除外可按需对 hourly/daily 预报缓存 10-30 分钟减少 API 调用次数。参数标准化用户输入的省市名可能存在空格、简繁混用建议先进行标准化映射如“深圳”-“深圳市”或参考行政区划码。限行解析limit.tail_number字段格式为“3和8”可根据本地规则解析出具体数字注意多城市限行规则差异。监控与告警对code非 0 的响应、频繁的超时或 5xx 设置监控指标及时发现接口或密钥问题。多语言封装除 Python 外也可用 JavaOkHttp/WebClient、Gonet/http等实现类似的封装核心思想一致。参考文档腾讯天气 API 官方文档https://apizero.cn/aidocs/tencent-weather原始接口规范Markdownhttps://apizero.cn/aidocs/tencent-weather/raw.md

相关新闻