今日油价返回字段对照:p89/p92/p0 与 ct 的含义与空值处理
约 13 分钟 进阶今日油价返回字段返回结构空值处理
# 今日油价返回字段对照:p89/p92/p0 与 ct 的含义与空值处理
接口/接入点:今日油价(apiCode=138)· 查询油价(138-46)/ 查询行情(138-49) · 免费 · POST/GET · JSON · 适用人群:初级与中级开发者 · 阅读时间:约 6 分钟 · 最后实测核对:2026-09-18
今日油价(apiCode=138)两个接入点的返回结构不一样,同一个字段名在两处的类型也不同。写解析代码前先看这张对照表,能省下不少调试时间。
## 核心要点
- 查询油价(138-46)返回 `showapi_res_body.list[]`,每项是一个省的油价,价格字段都是字符串。
- 查询行情(138-49)返回的是单个对象,`p0`/`p89`/`p92` 等字段都是含 `price`、`change`、`change_percent` 的对象,不是字符串。
- `p90`/`p93`/`p97` 在 2026-09-18 实测的 31 条记录里全部是空字符串;`p89` 有 7 个省份返回 `"0.00"`。
## 两个接入点的返回骨架
查询油价(138-46):
```json
{
"showapi_res_code": 0,
"showapi_fee_num": 1,
"showapi_res_body": {
"ret_code": 0,
"list": [
{ "prov": "北京", "p0": "8.02", "p89": "7.76", "p90": "", "p92": "8.29",
"p93": "", "p95": "8.83", "p97": "", "p98": "10.33", "ct": "2026-09-18 12:00:05.916" }
]
}
}
```
查询行情(138-49):
```json
{
"showapi_res_code": 0,
"showapi_fee_num": 1,
"showapi_res_body": {
"ret_code": 0,
"prov": "北京",
"p0": { "change_before_price": "7.81", "price": "8.02", "change": "0.21", "change_percent": "2.689%" },
"p92": { "change_before_price": "8.09", "price": "8.29", "change": "0.2", "change_percent": "2.472%" },
"p90": { "change_before_price": "", "price": "", "change": "", "change_percent": "" },
"before_change_time": "20260912",
"next_change_time": "20260925"
}
}
```
上面两段都是 2026-09-18 的实测返回(北京),为了便于阅读省略了部分标号。
## 查询油价(138-46)字段表
`list[]` 中每项的字段:
| 字段 | 类型 | 含义 |
|---|---|---|
| `prov` | String | 省份名称,如「北京」 |
| `p89` | String | 89 号汽油价格 |
| `p90` | String | 90 号汽油价格 |
| `p92` | String | 92 号汽油价格 |
| `p93` | String | 93 号汽油价格 |
| `p95` | String | 95 号汽油价格 |
| `p97` | String | 97 号汽油价格 |
| `p98` | String | 98 号汽油价格 |
| `p0` | String | 0 号柴油价格 |
| `ct` | String | 该批数据的生成时间,形如 `2026-09-18 12:00:05.916` |
这份结构里没有 `p91`、`p94`、`p96`,不要在代码里预留这三个键。
## 查询行情(138-49)字段表
| 字段 | 类型 | 含义 |
|---|---|---|
| `prov` | String | 省份名称 |
| `ret_code` | Number | 业务层状态码,0 成功 |
| `p0` `p89` `p90` `p92` `p93` `p95` `p97` `p98` | Object | 对应标号的涨跌信息 |
| `before_change_time` | String | 最近一次调价日,`yyyyMMdd` 格式 |
| `next_change_time` | String | 下一次调价日,`yyyyMMdd` 格式 |
标号对象里的四个子字段:
| 子字段 | 类型 | 含义 |
|---|---|---|
| `price` | String | 当前价格 |
| `change_before_price` | String | 上一次价格 |
| `change` | String | 涨跌值,不带单位 |
| `change_percent` | String | 涨跌率,带 `%` 后缀 |
同一个 `p0` 字段在两个接入点里类型不同,共用解析函数时需要按接入点分开处理。
## 空值分布(2026-09-18 实测)
用查询油价(138-46)不传 `prov` 取回 31 条记录,逐字段统计空字符串:
| 字段 | 空值条数 | 说明 |
|---|---|---|
| `p90` | 31 / 31 | 该批数据里全部为空 |
| `p93` | 31 / 31 | 该批数据里全部为空 |
| `p97` | 31 / 31 | 该批数据里全部为空 |
| `p89` | 0 / 31 | 但其中 7 个省份的值是 `"0.00"` |
| `p92` `p95` `p98` `p0` `prov` `ct` | 0 / 31 | 全部有值 |
`p89` 返回 `"0.00"` 的 7 个省份是:吉林、河南、湖北、黑龙江、内蒙古、辽宁、新疆。`"0.00"` 不是空字符串,判空逻辑拦不住它,会一路传到页面上显示成「0.00 元/升」。处理方式是按数值判断:
Python:
```python
import requests
resp = requests.post(
"https://route.showapi.com/138-46",
data={"appKey": "YOUR_APPKEY", "prov": "北京"},
timeout=5,
).json()
item = resp["showapi_res_body"]["list"][0]
GAS_LABELS = {"p89": "89号", "p90": "90号", "p92": "92号",
"p93": "93号", "p95": "95号", "p97": "97号", "p98": "98号"}
def display(raw):
"""空字符串和 0 都不展示,返回占位符。"""
if not raw:
return "—"
value = float(raw)
return f"{value:.2f}" if value > 0 else "—"
for code, label in GAS_LABELS.items():
print(f"{label}汽油: {display(item.get(code))}")
print(f"0号柴油: {display(item.get('p0'))}")
print(f"数据生成时间: {item['ct']}")
```
cURL:
```bash
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
const resp = await fetch("https://route.showapi.com/138-46", {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ appKey: "YOUR_APPKEY", prov: "北京" }),
signal: AbortSignal.timeout(5000),
});
const item = (await resp.json()).showapi_res_body.list[0];
const labels = { p89: "89号", p90: "90号", p92: "92号", p93: "93号",
p95: "95号", p97: "97号", p98: "98号" };
const display = (raw) => {
const value = Number(raw);
return raw && value > 0 ? value.toFixed(2) : "—";
};
for (const [code, label] of Object.entries(labels)) {
console.log(`${label}汽油: ${display(item[code])}`);
}
console.log(`0号柴油: ${display(item.p0)}`);
```
## 适用条件与注意事项
- 所有价格字段都是字符串,排序、求和、比大小之前先转数值。
- `p90`/`p93`/`p97` 在当前数据里没有价格,返回空字符串,按空值处理。
- `p89` 存在 `"0.00"` 这样的值,判空时同时判断数值是否为 0。
- `ct` 是这批数据的生成时间,不是调价公告时间。
- 标号含义、现行与历史标号的区分见《今日油价标号对照:89/92/95/98 汽油与 0 号柴油的字段映射》。
## FAQ
**Q1:为什么有的标号是空字符串?**
表示该批数据里没有这个标号的价格。2026-09-18 实测中 `p90`、`p93`、`p97` 在 31 条记录里全部为空,前端显示为「—」即可。
**Q2:`p0` 在两篇文章里看到的类型不一样?**
两个接入点确实不同。查询油价(138-46)的 `p0` 是价格字符串,查询行情(138-49)的 `p0` 是含 `price`、`change`、`change_percent` 的对象。
**Q3:`p89` 返回 `"0.00"` 是接口异常吗?**
不是异常,接口按数据原样返回。2026-09-18 实测有 7 个省份的 `p89` 为 `"0.00"`,展示前按数值判断即可。
**Q4:`change_percent` 可以直接参与计算吗?**
它是带 `%` 后缀的字符串,如 `"2.689%"`,计算前先去掉后缀再转数值。`change` 不带单位,形如 `"0.21"`。
**Q5:有没有 `p91`、`p94`、`p96`?**
没有。返回结构里只有 `p89`、`p90`、`p92`、`p93`、`p95`、`p97`、`p98` 和 `p0`。
## 相关能力 / 下一步阅读
- [今日油价标号对照:89/92/95/98 汽油与 0 号柴油的字段映射](https://www.showapi.com/guides/oilprice-grade-meaning-138)
- [今日油价:用 Python 查北京 92 号汽油价格的完整调用流程](https://www.showapi.com/guides/oilprice-quickstart-138)
- [今日油价涨跌幅怎么查?查询行情接入点的调价日与涨跌率用法](https://www.showapi.com/guides/oilprice-trend-138)
- [今日油价数据什么时候刷新?用 ct 字段判断缓存是否过期](https://www.showapi.com/guides/oilprice-schedule-138)
- **本系列共 13 篇**:查看[今日油价指南总目录](https://www.showapi.com/guides/oilprice-guides-138)





