今日油价:一次调用取回全国 31 省油价的做法
约 10 分钟 进阶今日油价全国油价省份枚举批量取数
# 今日油价:一次调用取回全国 31 省油价的做法
接口/接入点:今日油价(apiCode=138)· 查询油价(138-46) · 免费 · 适用人群:需要做全国比价、油价地图的开发者 · 阅读时间:约 5 分钟 · 最后实测核对:2026-09-18
要全国油价,不必循环 31 次。查询油价(138-46)的 `prov` 不传时,接口一次返回 31 个省级行政区的完整数据,计费次数仍是 1。
## 核心要点
- 不传 `prov`(或传空字符串)时,`showapi_res_body.list` 返回 31 条记录,覆盖全部 31 个省级行政区。
- 这次调用的 `showapi_fee_num` 是 1,与查单个省份相同(2026-09-18 实测)。
- 传 `prov` 时 `list` 只有 1 条,且精确匹配该省;两种用法可以按场景分开选择。
## 两种取数方式的实际差别
2026-09-18 实测对照:
| 调用方式 | `list` 长度 | `showapi_fee_num` |
|---|---|---|
| 不传 `prov` | 31 | 1 |
| 传 `prov=北京` | 1 | 1 |
| 传 `prov=广西` | 1 | 1 |
| 传 `prov=`(空字符串) | 31 | 1 |
做全国榜单、油价地图、跨省比价这类需求,不传 `prov` 一次取全量,调用次数从 31 次降到 1 次。
## 实测返回的 31 个省级行政区
2026-09-18 一次全量调用返回的名称列表,可直接作为枚举值使用:
```
北京、天津、河北、山西、内蒙古、辽宁、吉林、黑龙江、上海、江苏、浙江、安徽、
福建、江西、山东、河南、湖北、湖南、广东、广西、海南、重庆、四川、贵州、
云南、西藏、陕西、甘肃、青海、宁夏、新疆
```
名称与查询时的 `prov` 入参一致,不需要做额外的映射表。
## 全量取数代码
Python(requests):
```python
import requests
def fetch_all():
"""一次调用取回全国油价,返回 {省名: 记录} 的字典。"""
resp = requests.post(
"https://route.showapi.com/138-46",
data={"appKey": "YOUR_APPKEY"}, # 不传 prov 即返回全量
timeout=5,
).json()
if resp.get("showapi_res_code") != 0:
raise RuntimeError(resp.get("showapi_res_error"))
body = resp["showapi_res_body"]
if body.get("ret_code") != 0:
raise RuntimeError(body.get("remark"))
return {item["prov"]: item for item in body["list"]}
prices = fetch_all()
print(f"共 {len(prices)} 个省级行政区")
# 按 92 号汽油价格排序,值为空的排到最后
ranked = sorted(
prices.items(),
key=lambda kv: (not kv[1]["p92"], float(kv[1]["p92"] or 0)),
)
for prov, item in ranked[:5]:
print(f"{prov} 92号 {item['p92']} 元/升")
# 数据生成时间在每条记录里都是一致的,取第一条即可
print("数据生成时间:", next(iter(prices.values()))["ct"])
```
cURL:
```bash
# 不传 prov,一次取回 31 个省份
curl -X POST "https://route.showapi.com/138-46?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded"
# 查单省做对照
curl -X POST "https://route.showapi.com/138-46?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" -d "prov=%E5%8C%97%E4%BA%AC"
```
Node.js(fetch):
```javascript
async function fetchAll() {
const resp = await fetch("https://route.showapi.com/138-46", {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
// 不传 prov 即返回全量
body: new URLSearchParams({ appKey: "YOUR_APPKEY" }),
signal: AbortSignal.timeout(5000),
});
const data = await resp.json();
if (data.showapi_res_code !== 0) throw new Error(data.showapi_res_error);
const body = data.showapi_res_body;
if (body.ret_code !== 0) throw new Error(body.remark);
const map = Object.fromEntries(body.list.map((x) => [x.prov, x]));
console.log(`共 ${body.list.length} 个省级行政区,数据时间 ${body.list[0].ct}`);
return map;
}
const prices = await fetchAll();
console.log("广西 92号:", prices["广西"].p92);
```
## 缓存的粒度怎么定
两种粒度都可用,取决于页面一次要展示几个省。
**按省份缓存**:以 `prov` 为 key。2026-09-18 对照实测确认对应关系是一对一的,`prov=北京` 只返回北京,`prov=广西` 只返回广西,不会串数据。适合用户选一个省查一次的场景。
**按全量快照缓存**:把一次全量调用的 31 条结果整体存成一个 JSON,页面按需从快照里取省。适合地图、排行榜这类要同时展示多省的场景,也能让回源次数稳定在每天一次。
要避免的是「每个省一个缓存、但每个都单独回源」:既然一次调用就能取全量,分开回源只会让调用次数线性增长。
缓存 TTL 的确定方式见《今日油价数据什么时候刷新?用 ct 字段判断缓存是否过期》,调用量与档位的对应关系见《今日油价调用量规划:缓存粒度与 TTL 的确定方式》。
## 适用条件与注意事项
- 全量返回的 31 条记录里 `ct` 值一致,代表同一批次生成。
- `p90`/`p93`/`p97` 在 31 条里全部为空字符串,排序前先过滤。
- `p89` 有 7 个省份返回 `"0.00"`,按数值判断有效性。
- 单省查询按精确匹配,不做前缀或模糊处理,省名写法见《今日油价 prov 参数怎么传?查询油价与查询行情的必填差异》。
- 计费次数为 1 是全量返回的实测结果,档位消耗仍按调用次数累计。
## FAQ
**Q1:不传 `prov` 真的会返回全部省份吗?**
会。2026-09-18 实测 `list` 返回 31 条,覆盖 31 个省级行政区,`showapi_fee_num=1`。
**Q2:全量返回比单省查询贵吗?**
不贵。实测两种调用的 `showapi_fee_num` 都是 1。全量取数把 31 次调用压缩成 1 次。
**Q3:批量拉全国要不要加限速?**
一次全量调用已经是单次请求,不需要限速。若确实要逐省调用,按平台档位的并发限制安排节奏即可。
**Q4:省名列表从哪里取?**
直接取全量返回里的 `prov` 值,与查询入参完全一致,不必自己维护映射表。
**Q5:全国比价时 `p89` 的 `"0.00"` 怎么处理?**
按无数据处理。2026-09-18 实测有 7 个省份的 `p89` 为 `"0.00"`,参与排序时会排到最前面,需要先过滤。
## 相关能力 / 下一步阅读
- [今日油价调用量规划:缓存粒度与 TTL 的确定方式](https://www.showapi.com/guides/oilprice-cache-138)
- [今日油价 prov 参数怎么传?查询油价与查询行情的必填差异](https://www.showapi.com/guides/oilprice-prov-param-138)
- [今日油价返回字段对照:p89/p92/p0 与 ct 的含义与空值处理](https://www.showapi.com/guides/oilprice-fields-138)
- **本系列共 13 篇**:查看[今日油价指南总目录](https://www.showapi.com/guides/oilprice-guides-138)





