本文基于公开接口文档整理,未对接口发起真实请求实测,文中返回示例均为结构示意(标注「示例返回」),字段名与类型以官方文档为准;集成前请自行验证。
一、技术简介
天气预报查询接口是一类 HTTP + JSON 的数据服务:调用方传入地区标识(地名、地区 code、经纬度、IP、区号邮编或景点名称),接口返回该地区的气象要素——实况温度、湿度、风向风力、天气现象、空气质量,以及未来一段时间(7 天、15 天等)的逐日预报与历史天气记录。
它解决的问题很具体:业务系统本身不生产气象数据,而天气又是很多场景里必须参与决策的外部变量。与其自建气象采集链路,不如把「区域 → 气象要素」的映射关系交给接口,在自己的系统里只保留取数、缓存、降级三段逻辑。
本文以一个典型的逐日预报端点为例,说明请求参数设计、返回结构解读、日期语义、错误码排查与生产接入中的边界处理。核心端点:
| 项目 | 内容 |
|---|---|
| 调用路径 | /area-to-weather-date |
| 请求方式 | GET |
| 返回格式 | JSON |
| 鉴权方式 | Authorization: APPCODE <appcode>(简单身份认证),亦支持 AppKey/AppSecret 签名认证 |
| 核心入参 | areaCode / area / date / need3HourForcast |
| 核心返回 | 指定日期逐日预报(白天/夜间天气、气温、风向风力、生活指数),可叠加 3/6/8 小时间隔的分时段预报 |
二、能力概览
同一套数据能力通常按「查询维度」拆成多个端点,常见的维度与返回侧重如下:
| 查询维度 | 主要入参 | 返回侧重 | 典型用途 |
|---|---|---|---|
| 地名查实时+预报 | area / areaCode |
实况 now + 逐日 f1~f7 |
城市天气页、App 首页卡片 |
| 指定日期预报 | areaCode / area / date |
目标日期逐日对象 | 履约日天气核对、活动排期 |
| 未来 24 小时 | area / areaCode |
小时级 hourList |
出行提示、外卖运力调度 |
| 经纬度查询 | lng / lat |
反查区域 + 实况与预报 | 移动端 GPS 定位、车机 |
| IP 查询 | ip |
按 IP 归属地取天气 | 无定位权限的 Web 端 |
| 区号/邮编查询 | phone_code / post_code |
区域资料 + 实况 | 电话呼叫中心、传统业务系统 |
| 历史天气 | area / areaCode / month |
逐日历史记录 list |
数据回补、同比分析、报表 |
| 地名查 code | area |
匹配地区列表 | 重名消歧、一次解析多次复用 |
逐日预报对象是这套接口里信息密度最高的结构,一天一个对象,主要字段含义:
| 字段 | 含义 | 使用提示 | |
|---|---|---|---|
day_weather / night_weather |
白天 / 夜间天气现象文本 | 用于展示文案,不要用于逻辑判断 | |
day_weather_code / night_weather_code |
天气现象编码(如 00 晴、01 多云、07 小雨、13 阵雪) |
图标映射与规则判断请用编码,文本会因供应商措辞不同而变化 | |
day_air_temperature / night_air_temperature |
白天 / 夜间气温(摄氏度,字符串) | 字符串需自行 float() 转换,勿直接做数值比较 |
|
day_wind_direction / day_wind_power |
白天风向 / 风力编号 | 编号到「东南风 3-5 级」的映射由业务侧维护 | |
sun_begin_end |
日出与日落时间,用 `\ | ` 分隔 | 做光照相关业务时注意解析分隔符 |
index |
生活指数集合(穿衣、紫外线、洗车、运动等) | 字段较多,按需取用,避免整包透传给前端 | |
air_press / jiangshui |
大气压 / 降水概率 | 降水概率为文本,展示前做归一化 |
实况对象 now 则包含 temperature、sd(湿度)、wind_direction、wind_power、weather、weather_pic、aqi、feels_like(体感温度)、rain(降水量)等字段;空气质量明细在 aqiDetail 中给出 pm2_5、pm10、so2、no2、co、o3、quality、primary_pollutant 等分项。

三、适用场景
| 场景 | 关键取数 | 工程要点 |
|---|---|---|
| 生活服务类应用天气卡片 | 实况 now + f1~f3 |
卡片只展示 3 天,减少单次返回体积 |
| 电商与本地生活履约 | 目标日期逐日对象 | 用 date 精确取履约日,而非按偏移量猜 |
| 能源、电力、光伏 | 逐日预报 + 气温极值 | 按区域批量拉取,结果做小时级缓存 |
| 农业与种植 | 逐日天气编码、降水概率、气温 | 编码稳定优先于文本;降水为概率,不做确定性承诺 |
| 出行与物流调度 | 24 小时预报 + 预警 | 预警字段独立处理,不能混在展示层 |
| 智能硬件 / 车机 | 经纬度查询 + 实况 | 端侧缓存有效期短,注意弱网重试 |
| 航旅、旅游 | 景点名称、目的地城市 | 景点名命中率低于城市名,做好兜底 |
| 数据报表与复盘 | 历史天气 list |
按月拉取,落库后再做统计,避免重复调用 |
判断是否需要接口,可以先问三个问题:气象要素是否会影响业务决策?是否已有稳定的内部数据源?能否接受「区域级」而非「点位级」的精度?三个都是「是」时,接口通常比自己采集更省事。

四、接入流程
整体是四步:准备凭据 → 选定区域标识 → 组装日期与可选参数 → 取数并落缓存。
第 1 步,准备鉴权凭据。 在云市场开通该 API 后获得 AppCode,请求头统一携带 Authorization: APPCODE <appcode>。凭据放在服务端配置中心或密钥管理里,不要写进前端代码,也不要提交到代码仓库。
第 2 步,选定地区标识。 有三种做法:
- 地名直查(
area)——上手快,但地名可能重名,命中结果为库内排序第一条; - 地区 code(
areaCode)——最稳定,建议先用地名查 code 端点解析一次、落库复用; - 经纬度 / IP——适合端侧无输入的场景,接口内部完成「坐标 → 区域」的反查。
当 areaCode 与 area 同时传入时,以 areaCode 为准——这一点在批量任务里很重要,可避免两个字段口径不一致。
第 3 步,组装日期与可选参数。 date 使用 yyyyMMdd 形式(示例值 20200319);need3HourForcast=1 时额外返回当天每 3/6/8 小时的分时段预报。注意 f1 是 3 小时间隔,f2 到 f7 的间隔可能是 6 或 8 小时,做时间轴对齐时不要假设等间隔。
第 4 步,取数并落缓存。 建议按「区域 code + 日期」做缓存键,缓存时间与数据刷新频率对齐;写入时记录 ret_code 与抓取时间,便于排查脏数据。

五、调用示例与返回结构
5.1 curl 示例
curl -X GET \
'https://<网关域名>/area-to-weather-date?areaCode=530700&area=%E9%BB%8E%E6%B1%9F&date=20200319&need3HourForcast=1' \
-H 'Authorization: APPCODE <你的 appcode>' \
-H 'Content-Type: application/json; charset=UTF-8'
5.2 Python 示例
import json
import os
import requests
BASE = "https://<网关域名>/area-to-weather-date"
APPCODE = os.environ["WEATHER_APPCODE"] # 从环境变量读取,不要硬编码
def fetch_weather(area_code=None, area=None, date=None, need_3hour=False, timeout=5):
if not area_code and not area:
raise ValueError("areaCode 与 area 至少传入一个")
params = {
}
if area_code:
params["areaCode"] = area_code
if area and not area_code:
params["area"] = area
if date:
params["date"] = date
if need_3hour:
params["need3HourForcast"] = 1
resp = requests.get(
BASE,
params=params,
headers={
"Authorization": f"APPCODE {APPCODE}"},
timeout=(3, timeout),
)
resp.raise_for_status()
payload = resp.json()
if payload.get("showapi_res_code") != 0:
raise RuntimeError(f"网关层失败: {payload.get('showapi_res_error')}")
body = payload.get("showapi_res_body") or {
}
if body.get("ret_code") != 0:
raise RuntimeError(f"业务层失败: ret_code={body.get('ret_code')}")
return body
if __name__ == "__main__":
data = fetch_weather(area_code="530700", date="20200319", need_3hour=True)
print(json.dumps(data, ensure_ascii=False, indent=2)[:800])
5.3 返回结构(示例返回,字段与类型以官方文档为准)
{
"showapi_res_code": 0,
"showapi_res_error": "",
"showapi_res_id": "示例请求标识",
"showapi_res_body": {
"ret_code": 0,
"area": "丽江",
"areaid": "示例区域 ID",
"areaCode": "530700",
"time": "2020-03-19 08:00:00",
"f1": {
"day": "20200319",
"weekday": 4,
"day_weather": "多云",
"night_weather": "晴",
"day_weather_code": "01",
"night_weather_code": "00",
"day_air_temperature": "18",
"night_air_temperature": "6",
"day_wind_direction": "西南风",
"day_wind_power": "3-5级",
"sun_begin_end": "07:12|19:20",
"jiangshui": "10%",
"air_press": "1012hPa",
"index": {
"clothes": "较冷,建议外套",
"uv": "中等",
"wash_car": "较适宜"
},
"3hourForcast": [
{
"time": "08:00", "weather": "多云", "temperature": "12"}
]
},
"now": {
"temperature": "11",
"sd": "48%",
"weather": "多云",
"wind_direction": "西南风",
"wind_power": "3级",
"feels_like": "10",
"rain": "0",
"aqi": "32",
"temperature_time": "2020-03-19 08:00:00"
}
}
}
读返回的三层结构:最外层 showapi_res_code 表示网关层是否受理(0 为成功);showapi_res_body.ret_code 表示业务层是否查到数据(0 为成功);真正的气象数据在 showapi_res_body 下的 f1(逐日)与 now(实况)里。三层必须逐层判空,只判 JSON 能否解析会把业务失败当成空数据。

5.4 返回字段速查
| 路径 | 类型 | 说明 | 易错点 |
|---|---|---|---|
showapi_res_code |
number | 网关状态码 | 非 0 时 showapi_res_body 可能为空 |
showapi_res_error |
string | 网关错误信息 | 仅用于日志,不要直接展示给终端 |
showapi_res_body.ret_code |
number | 业务状态码,0 成功 | 缺失时按失败处理 |
showapi_res_body.area / areaCode |
string | 实际命中的区域 | 与请求值比对,可发现重名误命中 |
showapi_res_body.f1 |
object | 目标日期的逐日预报 | 字段若为字符串,注意数值转换 |
f1.index |
object | 生活指数集合 | 子字段随日期与区域变化,需容错 |
f1.3hourForcast |
array | 分时段预报 | f2~f7 间隔可能为 6/8 小时 |
showapi_res_body.now |
object | 实况 | 实况更新频率高于逐日预报 |
六、调试方法与示例返回
调试的目标不是「跑通一次」,而是确认参数语义、字段类型、异常分支三件事。
参数怎么填。 先在调试面板里固定一个已知区域(如 areaCode=530700),只调 date 一个变量,观察 f1 是否随日期变化;再把 need3HourForcast 从 0 切到 1,确认 3hourForcast 数组出现且时间节点递增。date 留空时通常返回以当天为起点的预报,这一点要在自己的代码里显式判断,而不是依赖接口默认行为。
返回怎么读。 依次看三处:showapi_res_code 是否为 0、ret_code 是否为 0、f1 是否存在且 day 与请求日期一致。第三步的日期比对最容易被跳过,但它是发现「接口静默回退到默认日期」的关键。
异常分支怎么造。 用非法区域值(如不存在的 code)触发业务失败,确认 ret_code 非 0 且 f1 为空;用错误凭据触发网关失败,确认 showapi_res_code 非 0。两类失败的响应体形状不同,客户端要分别处理,不能共用一套「返回空对象」兜底逻辑。
断言怎么写。 单测里对固定区域、固定日期做结构断言而非数值断言:断言 f1 的键集合包含 day_weather、day_air_temperature、index,断言温度可被 float() 解析。气象数值本身会随时间变化,写死数值的测试用例第二天就会失败。

七、调用限制与规范
频控与配额。 按 HTTP 状态码判定是否计入调用次数:200 才计次,非 200 不计次(业务失败会以 450 + ret_code 返回,属「调用成功、业务失败」的语义,需按官方口径确认计次规则)。因此客户端不应把「非 200」当成可无限重试的信号,重试必须带上退避与上限。
参数前置校验。 areaCode 与 area 至少一个非空;date 必须是 8 位数字且落在接口支持的时间范围内;need3HourForcast 只接受 0/1。把这三条校验放在 SDK 入口,能挡掉大部分无效请求。
幂等与缓存。 同一「区域 + 日期 + 分时段开关」的请求在短时间内结果一致,适合做结果缓存。缓存键建议为 weather:{areaCode}:{date}:{need3Hour},值里带上 fetched_at;跨天任务要按 date 分片,不要用「今天 + n 天」在运行期计算。
失败重试。 区分三类:网络超时(可退避重试 1~2 次)、网关 5xx(可重试,注意退避)、业务失败(ret_code 非 0,不要重试,直接降级)。降级策略建议为「返回上一次缓存 + 标注数据时间」,而不是返回空对象让前端显示「暂无数据」。
熔断与监控。 对单区域的连续失败做计数,超过阈值短时间内直接走缓存;监控上报 ret_code 分布、P95 耗时与缓存命中率,而不是只报总量。
合规与数据安全。 只取业务必需字段(最小必要),日志中不落完整响应体;IP、经纬度属于位置信息,传输使用 HTTPS,长期存储需脱敏并明确用途;生活指数等文本内容仅供展示,不作为医疗、健康建议输出。
八、能力边界与免责
- 区域级而非点位级。 返回的气象要素对应的是「区域」的观测与预报,同一区县内不同地点的实际天气可能存在差异,不适合做精细化到米级的判断。
- 文本字段不稳定。 天气现象文本、生活指数文案可能随数据更新调整措辞,做逻辑判断请使用编码字段(如
day_weather_code)。 - 分时段间隔不齐。
f1为 3 小时间隔,f2~f7可能为 6 或 8 小时;画曲线或做插值前先按实际时间戳排序。 - 历史数据有起点。 历史天气通常支持按月查询且可回溯到较早年份,但最早的可用月份以官方说明为准,不要按年份无限回溯。
- 重名与命中顺序。 纯地名查询在重名时按库内排序取第一条,跨城市业务务必先用「地名查 code」解析并落库。
- 极端天气不作为安全依据。 预警与预报信息仅作参考,涉及人身安全、航空、航海、电力调度等场景,须以官方气象机构发布的信息为准。
- 数值可能缺测。 个别区域或时段存在缺测,返回中可能出现
undefined或空串,客户端需容错而非直接抛异常。
九、错误码排查
9.1 网关层常见错误码
| 错误码 | HTTP 状态 | 语义 | 排查方向 |
|---|---|---|---|
A400AC |
400 | Invalid AppCode ${Reason},AppCode 模式未找到 AppCode |
检查请求头是否携带 Authorization: APPCODE <appcode>,注意前缀与空格 |
A400IK |
400 | Invalid AppKey,Key/Secret 签名模式未找到 AppKey |
签名模式下检查 AppKey 是否传入 |
Invalid AppKey |
400 | AppKey 无效或不存在 | 核对 AppKey 值,注意首尾空格与复制带入的换行 |
Invalid AppSecret |
400 | AppSecret 错误 | 核对密钥,Secret 与 Key 必须配对 |
B403MQ |
403 | Api Market Subscription quota exhausted,订购配额已耗尽 |
检查余量,补充额度后重试 |
B403ME |
403 | Api Market Subscription expired,订购关系已过期 |
检查订购有效期 |
Quota Exhausted |
403 | 调用次数已用完 | 与上一条区分:次数用尽 vs 关系过期 |
Quota Expired |
403 | 购买的次数已过期 | 检查次数有效期 |
User Arrears |
403 | 用户已欠费 | 结清欠费后恢复 |
Unauthorized |
403 | APP 未被授权调用该 API | 检查应用与 API 的授权绑定关系 |
| 无 | 450 | 接口调用成功但业务失败,有返回信息 | 读 showapi_res_body.ret_code,不要重试 |
9.2 业务层排查顺序
- 看
showapi_res_code:非 0 时先解决鉴权与配额,此时业务字段无意义; - 看
ret_code:非 0 说明区域无法解析或日期超出范围,回查areaCode与date的格式; - 看
area与请求值是否一致:不一致说明命中了重名区域,改用areaCode; - 看
f1.day是否等于请求日期:不等说明接口回退到了默认日期; - 看字段类型:气温、湿度等为字符串,直接做数值运算会抛异常。
9.3 一次典型的「查不到数据」排查链
请求 area=丽江、返回值正常但日期不对 → 说明地名命中成功、日期参数被忽略 → 检查 date 是否为 8 位数字且未被 URL 编码破坏 → 修正后复测。排查时始终一次只改一个变量,否则无法定位是哪一层出了问题。

十、技术 FAQ
Q1:areaCode 和 area 到底该用哪个?
A:代码里统一用 areaCode。地名只作为「首次解析」的输入,解析到 code 后落库;两者同时传入时接口以 areaCode 为准。
Q2:为什么返回的天气和手机自带的天气不一致?
A:区域粒度、数据更新频率、观测点位置都可能不同。接口给的是区域级要素,展示时应标注数据时间,避免用户误以为是实时点位观测。
Q3:date 支持多远的未来?
A:以官方文档说明的时间范围为准,超出范围通常返回业务失败。做排期类业务时,对超出范围的日期直接走「无预报」分支,不要循环重试。
Q4:f1 和 f2~f7 是什么关系?
A:f1 是当前日(或目标日)预报,f2~f7 依次为后续日期。注意 f1 为 3 小时间隔,f2~f7 的间隔可能为 6 或 8 小时。
Q5:need3HourForcast=1 会不会让响应变大很多?
A:会多出一个分时段数组。仅在需要画时间轴或做运力调度时开启,普通展示保持 0。
Q6:天气现象用文本还是编码?
A:展示用文本,判断用编码。00 晴、01 多云、02 阴、03 阵雨、07 小雨、13 阵雪等编码相对稳定,文本措辞可能调整。
Q7:气温字段为什么是字符串?
A:接口返回保持原始文本,便于保留小数与缺测标记。使用前统一 float() 并处理空值与 undefined。
Q8:如何应对重名地区?
A:先调「地名查 code」端点拿到候选列表,按 prov、distric 等字段确认后再用 areaCode 查询天气,把 code 缓存到业务侧。
Q9:批量查多个城市怎么做才不浪费调用?
A:按区域 code 做并发(控制在合理并发度内),结果按「code + 日期」缓存;同一城市的多页面展示复用同一份缓存。
Q10:接口失败时前端该显示什么?
A:显示「上次更新于 xx:xx」并保留缓存数据,而不是空白或「暂无数据」。业务失败与网络失败要区分文案。
Q11:历史天气能用来做同比分析吗?
A:可以,但需按月度拉取后落库,再在本地做统计;直接用接口做聚合查询会放大调用量与耗时。
Q12:接入前需要做哪些准备?
A:服务端托管凭据、确定区域标识口径(优先 code)、明确缓存与降级策略、准备好错误码到用户文案的映射表。
十一、内容小结
- 这是一个 GET + JSON 的区域级气象数据接口,鉴权用
Authorization: APPCODE <appcode>,核心入参是区域标识与日期。 - 返回分三层:
showapi_res_code(网关)、ret_code(业务)、showapi_res_body(数据),三层都要判。 - 区域标识统一用
areaCode,地名只做首次解析;两者同传以 code 为准。 - 逐日对象的文本用于展示、编码用于判断;气温等字段是字符串,需转换后使用。
date是yyyyMMdd语义,且f2~f7的分时段间隔不固定,时间轴对齐要按实际时间戳。- 生产接入的重点在缓存键设计、失败分类与降级策略,而不在首次跑通。
- 极端天气、人身安全相关场景,须以官方气象机构发布信息为准。
再次说明:本文基于公开接口文档整理,未做真实请求实测,示例返回仅表示结构,具体字段、取值范围与时间范围请以官方文档为准。