📦《京东商品详情API(jingdong.ware.read.get)Java/Python调用实战与JSON返回解析》(附Python源码)
京东POP商家/ISV获取商品(SPU/SKU)详情用
jingdong.ware.read.get(老版本也叫 360buy.ware.get),返回标题、价格、库存、SKU规格、主图、类目等结构化数据,官方免费额度内零成本,比爬京东商品页稳定且不触发风控。一、接口关键信息
项目 | 说明 |
|---|---|
API Method | jingdong.ware.read.get(推荐)或旧版 jingdong.ware.get |
网关 | 生产 https://api.jd.com/routerjson沙箱 https://api.sandbox.jd.com/routerjson |
必传 | wareId(京东商品ID / wareId)、fields(指定返回字段,强烈建议显式传) |
可选 | access_token(查自己店铺商品SKU库存需传卖家Token;公开字段可不传) |
权限 | 应用→接口权限→申请 jingdong.ware.read.get |
返回根 | {jingdong_ware_read_get_response: {ware: {...}}} |
⚠️ 京东wareId≠ SKU ID,ware.read.get返回 SPU 信息 +skus数组(内含各 skuId/库存/规格)
二、Python完整调用封装(JOS签名 + 字段解析)
# jd_item_detail.py
"""
京东商品详情 API (jingdong.ware.read.get) 调用示例
依赖: requests (pip install requests)
签名规则: MD5(AppSecret + KV_ASCII_sorted + AppSecret) → 大写
timestamp: 秒级(10位) ← 与TOP不同!
"""
import hashlib
import json
import requests
from typing import Dict, List, Optional
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
class JdItemClient:
PROD = "https://api.jd.com/routerjson"
SANDBOX = "https://api.sandbox.jd.com/routerjson"
def __init__(self, app_key: str, app_secret: str, sandbox: bool = False):
self.ak = app_key
self.as_ = app_secret
self.gw = self.SANDBOX if sandbox else self.PROD
# ───── JOS MD5签名 ─────
def _sign(self, params: Dict) -> str:
filt = sorted((k, v) for k, v in params.items()
if v is not None and str(v).strip() != '' and k != 'sign')
qs = ''.join(f"{k}{v}" for k, v in filt)
raw = f"{self.as_}{qs}{self.as_}"
return hashlib.md5(raw.encode('utf-8')).hexdigest().upper()
def _call(self, method: str, biz: Dict, access_token: str = None) -> Dict:
api_p = {
"app_key": self.ak,
"method": method,
"timestamp": str(int(time.time())), # ← 秒级!
"format": "json",
"v": "2.0",
"sign_method": "md5",
"360buy_param_json": json.dumps(biz, ensure_ascii=False, separators=(',', ':'))
}
if access_token:
api_p["access_token"] = access_token
api_p["sign"] = self._sign(api_p)
r = requests.post(self.gw, data=api_p, timeout=15)
r.raise_for_status()
d = r.json()
# 提取响应
resp_key = method.replace(".", "_") + "_response"
if resp_key not in d:
for k in d:
if k.endswith("_response"):
resp_key = k
break
data = d.get(resp_key, d)
# 错误检测
if isinstance(data, dict) and "error_response" in str(data):
err = d.get(resp_key, {}).get("error_response") or d.get("error_response")
if err:
raise Exception(
f"JOS [{err.get('code')}]: {err.get('zh_desc') or err.get('en_desc')} "
f"sub:{err.get('sub_code')}"
)
raise Exception(f"JOS unknown: {d}")
return data
# ───── 商品详情 ─────
def get_ware_detail(self, ware_id: str,
fields: str = None,
access_token: str = None) -> Dict:
"""
ware_id: 京东 SPU ID (wareId,不是 skuId)
fields 推荐:
"ware_id,title,item_num,brand_name,model,upc_code,cid,category,category_name,"
"price,jd_price,market_price,stock_num,"
"skus_json,image_path,desc,wrap,pack_list,param"
"""
fields = fields or (
"ware_id,title,brand_name,cid,category_name,"
"price,jd_price,stock_num,"
"skus_json,image_path,desc"
)
resp = self._call(
"jingdong.ware.read.get",
{"wareId": ware_id, "fields": fields},
access_token=access_token
)
# 标准返回路径
return resp.get("ware", resp)
# ───── 解析 SKU 列表 ─────
def parse_skus(self, ware: Dict) -> List[Dict]:
"""
从 ware['skus_json'] (JSON字符串) 解析 SKU 数组
"""
import json as _json
skus_raw = ware.get("skus_json") or ""
if not skus_raw:
return []
try:
return _json.loads(skus_raw)
except Exception:
return []
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# =========================================================
# 使用示例
# =========================================================
if __name__ == "__main__":
client = JdItemClient(
app_key="YOUR_JD_APP_KEY",
app_secret="YOUR_JD_APP_SECRET",
sandbox=True # 生产切 False;沙箱返回 mock ware_id 回显
)
WARE_ID = "100012345678" # ← 替换真实京东 wareId
try:
ware = client.get_ware_detail(WARE_ID)
print("✅ 商品标题:", ware.get("title"))
print(" 京东价 :", ware.get("jd_price"))
print(" 市场价 :", ware.get("price"))
print(" 主图 :", ware.get("image_path"))
print(" 库存(SPU汇总):", ware.get("stock_num"))
skus = client.parse_skus(ware)
print(f" SKU数 : {len(skus)}")
for s in skus[:3]:
print(f" skuId:{s.get('skuId')} 规格:{s.get('outerId','—')} "
f"价:{s.get('jdPrice')} 库:{s.get('stockNum')}")
# ★ 查自己店铺SKU库存须传卖家 access_token
# ware = client.get_ware_detail(WARE_ID, access_token="SELLER_ACCESS_TOKEN")
except Exception as e:
print("❌", e)
print("→ 确认: AppKey/Secret正确、接口权限已申请、wareId有效")三、关键返回字段解析(铺货/比价用)
JOS返回字段 | 含义 | ERP映射 |
|---|---|---|
ware_id | SPU ID(京东商品ID) | 外部货号 / 关联键 |
title | 商品标题 | 商品名(裁剪适配平台) |
jd_price | 京东价(字符串) | 零售价 |
price/ market_price | 市场价/划线价 | 促销展示 |
stock_num | SPU级别库存(汇总) | 参考;精确看SKU |
skus_json→ skuId | 子SKU ID | 内部SKU匹配 |
skus_json→ outerId | 商家编码 | SKU对照 |
skus_json→ jdPrice | SKU京东价 | 多规格定价 |
skus_json→ stockNum | SKU可售库存(需seller token) | 采购预警 |
image_path | 主图URL | 首图 |
cid/ category_name | 后端类目ID / 名称 | 类目映射 |
desc | 详情HTML(部分类目) | 详情页 |
SKU 典型结构(解析自
skus_json字符串):{
"skuId": "1234567890",
"outerId": "SKU-JD-RED-M",
"jdPrice": "199.00",
"stockNum": 50,
"features": "color:红色;size:M"
}四、Java调用核心片段(JOS Java SDK)
TaobaoClient client = new DefaultJdClient(
"https://api.jd.com/routerjson",
"APP_KEY", "APP_SECRET"
);
WareReadGetRequest req = new WareReadGetRequest();
req.setWareId(100012345678L);
req.setFields("ware_id,title,jd_price,stock_num,skus_json,image_path");
WareReadGetResponse rsp = client.execute(req); // session传null查公开字段
Ware ware = rsp.getWare();
System.out.println(ware.getTitle());
System.out.println(ware.getJdPrice());
// skus_json → JSONArray 解析五、避坑清单
坑 | 现象 | 解决 |
|---|---|---|
timestamp invalid | 用毫秒时间戳 | JOS用秒级 int(time.time()) |
返回空 ware | wareId错 / 应用无权限 | 确认接口 jingdong.ware.read.get已申请 |
skus_json空 / stockNum0 | 公开查询不返SKU库存 | 传卖家 AccessToken(OAuth授权)查自己店铺商品 |
fields不传 | 返回字段极少或隐式截断 | 显式传 fields含 skus_json,stock_num |
沙箱返回 mock | 正常 | 切生产网关看真实数据 |
sign mismatch | 360buy_param_json值含空格或排序错 | 用 separators=(',',':')紧凑JSON,空值剔除再签名 |
六、面试/方案一句话
京东商品详情用jingdong.ware.read.get(wareId, fields含skus_json)获取,JOS签名 MD5(AppSecret+KV_ASCII+AppSecret) 用秒级时间戳;公开字段可不传 session,查自己店铺 SKU 库存/商家编码须传卖家 OAuth AccessToken;skus_json是 JSON 字符串需二次解析得各 SKU 规格与库存。
需要我补 京东订单增量同步(
jingdong.pop.order.search) APScheduler脚本(断点续跑+Token刷新) 或 京东→1688/抖音铺货字段映射模板 吗?