☰
全量发改委油价查询 API 实战:一次拉回全国省市区六种油品价格
2026/9/27 4:55:14 网站建设 项目流程

全量发改委油价查询 API 实战:一次拉回全国省市区六种油品价格

要在本地建一份成品油价格库,最笨的办法是逐个省去查:30 多个省 × 6 种油品,几十上百次请求,还得自己处理「这个省是统一价还是按市定价」。本文介绍一个全量拉取接口:一次 GET 请求、零业务参数,把系统中当前生效的整批价格(省 / 市 / 区县 + 0#柴油、-10#柴油、-35#柴油、92#、95#、98# 汽油)一次性返回,适合做本地缓存、离线对账与批量核算。

  • api.xujian.tech
  • xujian_cq

一、为什么需要「全量」而不是「逐个查」

场景逐个查的问题全量接口的做法
建本地价格库30+ 省 × 6 油品 = 上百次请求,初始化慢且容易漏一次请求拿全批
批量成本核算每单查一次,调用量与延迟都放大拉一次进内存,本地匹配
数据对账难以确认「我本地那份是不是最新版」用返回的effectiveDate做版本比对
地区粒度不确定不知道哪些省按市定价、哪些区县单独定价结果里直接体现(city/district是否为null)

代价也很直接:这是一次返回全部数据的高单价接口,不适合放在用户请求的链路上高频调用。正确的用法是「低频拉取 + 本地缓存」。

二、接口能力概览

2.1 接口基础信息

项目说明
接口地址https://api.xujian.tech/openapi/oilprice/all
接口编码oilprice.all
请求方式GET
鉴权方式请求头X-API-Key,不做签名、时间戳或加密
返回格式JSON,Content-Type: application/json;charset=UTF-8
单次费用5 元/次(按次计费)
是否需要业务入参否,无任何查询参数
返回条数当前生效批次的全部记录,条数取决于库内维护粒度
数据来源国家发改委公布的成品油最高零售价,由平台运营在调价当日维护入库
更新频率国家发改委约每 10 个工作日调价一次(实际以返回体dataUpdateTime为准)
在线文档https://api.xujian.tech/api/oilprice-all

价格说明:5 元/次取自本项目的接口初始化配置(后台「接口管理」可随时调价),实际单价请以开发者控制台与在线文档页的显示为准。

2.2 请求参数

请求头:

参数名必填说明
X-API-Key是开发者 API Key,缺失或无效直接返回失败

查询参数:无。

接口故意不做分页与筛选:全量数据的定位就是「一次拉全、本地处理」,加分页反而容易漏数据。如果你只想查单个地区单油品,请用
oilprice.realtime(0.01 元/次),不要浪费一次全量调用。

2.3 计费上需要提前知道的一点(重要)

这个接口是**「先鉴权扣费、再查数据」**的模式:

  • API Key 有效、账号正常、接口启用、余额充足 →鉴权通过即扣一次 5 元;
  • 由于没有业务参数,鉴权之后基本不会失败,即使系统当前没有维护任何价格(total = 0),本次也已经扣费。

不扣费的场景只有:请求头缺失X-API-Key、API Key 无效或已停用、客户不存在或已停用、接口不存在或已停用、余额不足。

5 元/次不便宜,接入前建议先确认:

  1. 你的账户余额是否够(余额不足会直接返回失败,不扣费,不会半途扣一部分);
  2. 是否真的需要全量 —— 只查一个省的话,oilprice.realtime便宜几个数量级;
  3. 拉取频率是否有必要 —— 价格通常约 10 个工作日才变一次,每天拉一次已经很充裕。

2.4 数据量大概有多少

返回条数取决于平台当前的维护粒度,不是固定值:

维护粒度大致条数
全省统一价(一个省一条)30+ 条
按地市维护300+ 条量级
细化到区县更多

这是量级估计,不是承诺值。请按total字段做动态处理,别在代码里写死条数;入库时也别假设「一个省只有一条记录」。

三、返回字段详解

3.1 顶层字段

字段类型说明
codeint0成功,非 0 失败(本接口失败为500)
msgString结果描述,成功为success,失败为具体原因
dataObject业务数据,失败时为null

3.2 data 字段

字段类型示例说明
effectiveDateString2026-09-24本批次价格生效日期yyyy-MM-dd;系统暂无数据时为null
totalint312本次返回的价格条数
listArray[…]价格明细列表,按province_code→city_code→district_code升序
apiCode/apiNameStringoilprice.all / 全量发改委价格查询接口编码与接口名称
chargeTypeStringPER_CALL本次计费方式
balanceBigDecimal94.9900本次扣费后的账户余额(元)
costMslong12服务端处理耗时(毫秒,不含公网传输时间)

3.3 list[] 明细字段

字段类型示例说明
effectiveDateString2026-09-24该行价格的生效日期
province/provinceCodeString浙江省 / 330000省名称与 6 位 adcode
city/cityCodeString杭州市 / 330100地市名称与代码;null表示全省统一价
district/districtCodeStringnull区县名称与代码;null表示全市统一价
priceDiesel0BigDecimal7.250#柴油价格(元)
priceDiesel10BigDecimal7.69-10#柴油价格(元)
priceDiesel35BigDecimalnull-35#柴油价格(元),未维护时为null
priceGas92BigDecimal7.8392#汽油价格(元)
priceGas95BigDecimal8.2895#汽油价格(元)
priceGas98BigDecimal9.3298#汽油价格(元)
dataUpdateTimeString2026-09-24 09:00:00数据更新时间yyyy-MM-dd HH:mm:ss

与单油品接口的重要差别:全量接口的油品价格可能是null(该地区未维护该油品,例如南方很多地区不供应 -35#柴油)。处理时请按「无价」处理,不要当成 0。而oilprice.realtime遇到这种情况会直接报错,不会返回null价格。

四、调用示例

4.1 curl

curl-s"https://api.xujian.tech/openapi/oilprice/all"\-H"X-API-Key: 你的APIKey"

建议先这样手工跑一次,把返回的total和effectiveDate看一眼,确认数据粒度符合预期,再写进定时任务。

4.2 Java(Hutool)

importcn.hutool.http.HttpRequest;importcn.hutool.json.JSONArray;importcn.hutool.json.JSONObject;importcn.hutool.json.JSONUtil;publicclassOilPriceAllClient{privatestaticfinalStringAPI_URL="https://api.xujian.tech/openapi/oilprice/all";/** * 拉取当前生效批次的全部发改委价格 * * @param apiKey 开发者 API Key * @return [生效日期, 明细数组];失败返回 null */publicstaticObject[]fetchAll(StringapiKey){JSONObjectjson=JSONUtil.parseObj(HttpRequest.get(API_URL).header("X-API-Key",apiKey).timeout(30000)// 全量数据建议放宽超时.execute().body());if(json.getInt("code")==null||json.getInt("code")!=0){System.out.println("拉取失败:"+json.getStr("msg"));returnnull;}JSONObjectdata=json.getJSONObject("data");JSONArraylist=data.getJSONArray("list");System.out.println("生效日期:"+data.getStr("effectiveDate")+",条数:"+data.getInt("total"));returnnewObject[]{data.getStr("effectiveDate"),list};}publicstaticvoidmain(String[]args){Object[]r=fetchAll("你的APIKey");if(r==null){return;}JSONArraylist=(JSONArray)r[1];for(inti=0;i<list.size();i++){JSONObjectrow=list.getJSONObject(i);// 注意:priceDiesel35 等字段可能为 null,取值前判空System.out.printf("%s %s 92#=%s 0#柴油=%s%n",row.getStr("province"),row.getStr("city"),row.getStr("priceGas92"),row.getStr("priceDiesel0"));}}}

4.3 Python

importrequestsdeffetch_all(api_key:str)->dict:""" 拉取当前生效批次的全部发改委价格 Returns: dict: {"effectiveDate": str|None, "total": int, "list": [...]}; 失败返回 None """result=requests.get("https://api.xujian.tech/openapi/oilprice/all",headers={"X-API-Key":api_key},timeout=30,).json()ifresult.get("code")!=0:print("拉取失败:",result.get("msg"))returnNonedata=result["data"]print("生效日期:",data["effectiveDate"],"条数:",data["total"])returndatadefto_price_index(data:dict)->dict:"""把全量结果整理成 {(省, 市, 区): {油品: 价格}} 的本地索引"""FIELD={"0#柴油":"priceDiesel0","-10#柴油":"priceDiesel10","-35#柴油":"priceDiesel35","92#汽油":"priceGas92","95#汽油":"priceGas95","98#汽油":"priceGas98",}index={}forrowindata["list"]:# city / district 为 None 表示上一级统一价,用空串占位便于匹配key=(row["provinceCode"],row.get("cityCode")or"",row.get("districtCode")or"")prices={}forname,fieldinFIELD.items():value=row.get(field)ifvalueisnotNone:# 未维护的油品不写进索引prices[name]=float(value)index[key]={"effectiveDate":row["effectiveDate"],"prices":prices}returnindexif__name__=="__main__":data=fetch_all("你的APIKey")ifdata:idx=to_price_index(data)print("索引条数:",len(idx))

4.4 JavaScript(Node 18+)

asyncfunctionfetchAll(apiKey){constres=awaitfetch("https://api.xujian.tech/openapi/oilprice/all",{headers:{"X-API-Key":apiKey},});const{code,msg,data}=awaitres.json();if(code!==0){console.warn("拉取失败:",msg);returnnull;}returndata;}// 按省分组,方便落库或渲染functiongroupByProvince(list){returnlist.reduce((acc,row)=>{(acc[row.province]||=[]).push(row);returnacc;},{});}

五、返回示例

5.1 成功(code = 0)

{"code":0,"msg":"success","data":{"effectiveDate":"2026-09-24","total":2,"list":[{"effectiveDate":"2026-09-24","provinceCode":"500000","province":"重庆市","cityCode":null,"city":null,"districtCode":null,"district":null,"priceDiesel0":7.28,"priceDiesel10":7.72,"priceDiesel35":8.05,"priceGas92":7.86,"priceGas95":8.31,"priceGas98":9.36,"dataUpdateTime":"2026-09-24 09:00:00"},{"effectiveDate":"2026-09-24","provinceCode":"330000","province":"浙江省","cityCode":"330100","city":"杭州市","districtCode":null,"district":null,"priceDiesel0":7.25,"priceDiesel10":7.69,"priceDiesel35":null,"priceGas92":7.83,"priceGas95":8.28,"priceGas98":9.32,"dataUpdateTime":"2026-09-24 09:00:00"}],"apiCode":"oilprice.all","apiName":"全量发改委价格查询","chargeType":"PER_CALL","balance":94.9900,"costMs":12}}

5.2 成功但系统暂无数据(仍然计费)

{"code":0,"msg":"success","data":{"effectiveDate":null,"total":0,"list":[],"apiCode":"oilprice.all","apiName":"全量发改委价格查询","chargeType":"PER_CALL","balance":94.9900,"costMs":5}}

code = 0但total = 0表示系统当前没有维护任何已生效的价格。此时不要把它当成「上次的价格仍然有效」,应保留本地缓存并稍后重试。

5.3 失败(余额不足,不扣费)

{"code":500,"msg":"余额不足,请先充值。","data":null}

六、典型应用场景

6.1 建本地价格库(含版本控制)

用effectiveDate做版本号,避免重复入库与重复付费:

classPriceStore:"""本地价格库:只在生效批次变化时覆盖写入"""def__init__(self):self.version=Noneself.rows=[]defrefresh(self,api_key:str)->bool:data=fetch_all(api_key)ifnotdataordata["total"]==0:returnFalse# 保留旧数据,不覆盖ifdata["effectiveDate"]==self.version:returnFalse# 同一批次,无需写入self.version=data["effectiveDate"]self.rows=data["list"]returnTrue

6.2 本地匹配查询(替代高频调用实时接口)

拉一次全量后,在内存里按「区县 → 市 → 省」回落匹配,命中不了再打实时接口:

deflookup(index:dict,province:str,city:str="",district:str="")->dict:"""按 区县 → 市 → 省 逐级回落查找本地价格"""forkeyin[(province,city,district),(province,city,""),(province,"","")]:ifkeyinindex:returnindex[key]returnNone

这个回落顺序与实时接口内部的匹配规则一致,本地复现后行为可预期。

6.3 调价日排程(配合免费的调价周期接口)

免费的oilprice.cycle返回当年已登记的调价生效日期列表,用它决定何时拉全量:

fromdatetimeimportdatedefneed_refresh(cycle_dates:list[str],cached_version:str)->bool:today=date.today().isoformat()past=[dfordincycle_datesifd<=today]latest=max(past)ifpastelseNonereturnlatestisnotNoneandlatest!=cached_version

这样一年只需要在调价日附近调用约 24 次,而不是每天一次。

6.4 批量对账:确认「我算的和基准价一致」

把一批历史单据的价格与本地库按effectiveDate对齐重算,可快速找出「用了旧价」的异常单据。这也是全量数据相比单条查询最有价值的用法。

七、提升可用性的几条实践建议

  1. 一定要缓存。价格通常约 10 个工作日才变一次,每天最多拉一次;配合免费的oilprice.cycle能做到只在调价日拉。
  2. 别写死条数。返回条数取决于维护粒度,按total动态处理。
  3. 油品价格可能是null。按「无价」处理,不要当 0,否则成本会算成 0。
  4. city/district为null是统一价标记,不是数据缺失。
  5. 超时放宽到 20~30 秒。全量响应体比单条查询大,别用 5 秒超时。
  6. 失败时保留旧数据。拉取失败或total = 0时不要清空本地库。
  7. 不要放在用户请求链路上。这是 5 元/次的重接口,应走后台定时任务,并对任务做幂等(同effectiveDate不重复写)。
  8. 不要把它当「实时行情」。这是发改委公布的批次最高零售价,不是加油站挂牌价或成交价。

八、错误码与排查

codemsg(示例)处理建议
0success调用成功;total为 0 表示系统暂未维护当前批次价格(仍计费)
500缺少请求头 X-API-Key在请求头补充X-API-Key(不扣费)
500API Key 无效 / API Key 已停用检查 Key 是否正确,或在控制台重新启用(不扣费)
500客户不存在或已停用联系平台确认账号状态(不扣费)
500接口不存在或已停用确认oilprice.all当前是否维护中(不扣费)
500余额不足,请先充值。可xujian_cq充值后重试;余额不足时不扣费。本接口单价较高,建议先确认余额

九、计费与接入

项目说明
单价5 元/次(取自接口初始化配置,后台可调,以控制台显示为准)
计费方式按次计费,调用前校验余额;行锁 + 条件式原子扣减,不会把余额扣成负数
计费时机鉴权通过即扣费;total = 0的空结果也计费
不计费场景Key 缺失/无效、客户停用、接口停用、余额不足
建议频率调价日拉取一次,其余时间用本地缓存

接入流程:注册开发者账号 → 控制台创建 API Key → 请求头带上X-API-Key即可调用,无需签名或加密。控制台可查看调用量、扣费流水与余额。

控制台与在线文档:https://api.xujian.tech;接口接入、数据与充值相关问题可Vxujian_cq。

同系列接口:

  • oilprice.realtime(实时发改委价格查询):0.01 元/次,单地区单油品,适合高频小查询;
  • oilprice.advance(提前查询发改委价格):按年付费,提前 2 小时拿即将生效的新价;
  • oilprice.cycle(发改委调价周期查询):免费,用于决定何时拉全量。

十、总结

全量接口解决的是「一次性把基准价搬回本地」这件事:没有参数、没有分页、一次拿全批,配合effectiveDate做版本控制,就能搭出一份可离线使用的价格库。

几个关键取舍值得留意:

  • 5 元/次,鉴权通过即扣费:只适合低频批量拉取,不适合高频调用,更不要放在用户请求链路上;
  • 空结果也计费:系统暂无数据时返回code = 0+total = 0,费用照扣,所以定时任务要判断total;
  • 油品价格可能是null:与单油品接口的「查不到就报错」不同,全量接口用null表示未维护,解析时必须判空;
  • 条数不固定:取决于平台维护粒度,total才是唯一可信的数字。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询