全国城市空气质量查询:5 分钟接入,拿到第一条空气质量数据
# 全国城市空气质量查询:5 分钟接入,拿到第一条空气质量数据
> 接口/接入点:全国城市空气质量查询(apiCode=104)· 104-42 单城市查询 · 免费 · 请求方式 POST/GET · 返回 JSON · 适用人群:新注册用户、初级开发者 · 阅读时间:约 5 分钟
## 核心要点
- 注册 ShowAPI 账号 → 控制台获取 AppKey → 一次 POST 调用即可拿到某城市的 AQI、PM2.5、质量等级。
- 单城市查询(104-42)必填参数只有 `area`(城市名),小地区会自动回退到上级主要城市。
- 返回包在 `showapi_res_body` 内,判断 `ret_code == 0` 即成功;空气质量等级为「优质/良好/轻度污染…」6 类。
## Why:这跟我有什么关系
做天气类 App、出行/旅游工具、智能音箱播报、空气净化器联动、健康提醒小程序,几乎都需要「某城市现在空气好不好」。与其自己采集环保站点数据,不如直接调一个免费接口把 AQI、PM2.5、首要污染物拿到手。本篇目标是让你**复制代码、替换 AppKey,5 分钟内看到第一条真实数据**。
## What:前置条件与接口速览
| 项 | 内容 |
|----|------|
| 接口地址(单城查询) | `https://route.showapi.com/104-42?appKey={your_appKey}` |
| 请求方式 | POST 或 GET |
| 必填参数 | `area`(城市名,如「北京」「承德」「双桥镇」) |
| 鉴权 | URL 上的 `appKey` |
| 计费 | 免费服务(注册即可调用,受免费档位限制;每次调用仍计 1 次额度) |
| 返回格式 | JSON,业务数据在 `showapi_res_body` |
| 集成能力 | 接口级 MCP、OpenAPI 3.0(YAML/JSON) |
> 想直接拿「全国城市排名」而不是单城?用接入点 **104-41 排行榜**(见系列第 4 篇)。
## How:第一次调用
### Python(requests)
```python
import requests
url = "https://route.showapi.com/104-42"
params = {"appKey": "YOUR_APPKEY"} # 替换为你的真实 AppKey
data = {"area": "北京"} # 城市名,必填
try:
resp = requests.post(url, params=params, data=data, timeout=10)
resp.raise_for_status()
body = resp.json()["showapi_res_body"]
except Exception as e:
print("请求失败:", e)
raise
if body.get("ret_code") != 0:
print("业务失败:", body.get("remark") or body)
else:
print(f"城市={body['area']} AQI={body['aqi']} "
f"PM2.5={body['pm2_5']} 质量等级={body['quality']}")
print(f"首要污染物={body['primary_pollutant'] or '无'} 发布时间={body['ct']}")
```
### cURL
```bash
curl -X POST "https://route.showapi.com/104-42?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" \
-d "area=%E5%8C%97%E4%BA%AC"
```
### Node.js(fetch)
```js
const url = "https://route.showapi.com/104-42?appKey=YOUR_APPKEY";
const res = await fetch(url, {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ area: "北京" }),
});
const json = await res.json();
const b = json.showapi_res_body;
if (b.ret_code !== 0) {
console.error("业务失败:", b.remark || b);
} else {
console.log(`${b.area} AQI=${b.aqi} PM2.5=${b.pm2_5} 质量=${b.quality}`);
}
```
## 返回示例与解析
实测「北京」返回(节选):
```json
{
"showapi_res_code": 0,
"showapi_res_body": {
"remark": "查询成功!",
"primary_pollutant": "",
"aqi": "18",
"pm2_5": "3",
"pm10": "11",
"co": "0.3",
"no2": "11",
"so2": "3",
"o3": "57",
"o3_8h": "_",
"quality": "优质",
"area": "北京",
"area_code": "beijing",
"num": "41",
"ct": "2026-08-31 11:10:00.012",
"ret_code": 0
}
}
```
字段速读:`aqi` 为空气质量指数;`pm2_5`/`pm10` 为颗粒物浓度(μg/m³);`quality` 是等级文字;`primary_pollutant` 在空气优/良时为空字符串;`o3_8h` 无数据时返回 `"_"`(占位,非数字);`ct` 为数据发布时间。
## 进阶 / 边界
- **小地区回退**:当查询「双桥镇」这类非主要城市时,接口返回其上级主要城市(如「承德」)的空气质量,这是正常行为。
- **免费额度**:接口虽免费,但每次调用计 1 次免费额度(`showapi_fee_num:1`),请勿无节制轮询;生产环境务必加缓存(见系列第 7 篇)。
- **AppKey 安全**:示例用 `YOUR_APPKEY` 占位,真实项目请从环境变量读取,切勿硬编码进前端代码。
## FAQ
**Q1:返回提示不是 JSON 或请求失败?**
先确认 `appKey` 已替换为真实值,且账号已完成注册并拥有该接口的免费调用权限;网络超时默认 10 秒,弱网可适当加大。
**Q2:传了城市名却返回别的城市?**
多为「小地区自动回退」:国家仅公布主要城市的监测数据,查小地名会返回其上级主要城市,属预期行为。
**Q3:quality 出现「优质」还是「优」?**
线上实际返回为「优质」(共 6 类:优质/良好/轻度污染/中度污染/重度污染/严重污染),以线上返回为准。
**Q4:免费接口每天能调多少次?**
以官方免费档位说明为准(https://www.showapi.com/free-api),文档未给固定数字;建议结合缓存控制频次。
## 相关能力 / 下一步阅读
- [全国城市空气质量查询:返回字段全解(AQI/PM2.5/质量等级一文读懂)](https://www.showapi.com/guides/air-quality-response-fields-104)
- [全国城市空气质量查询:单城市实时查询集成指南(从请求到 UI 展示)](https://www.showapi.com/guides/air-quality-query-integration-104)
- **本系列共 11 篇**:查看[全国城市空气质量查询 · 指南总目录](https://www.showapi.com/guides/air-quality-guides-104)