在比价系统、ERP 商品同步、精选带货选品开发场景中,京东商品详情是核心数据源。现有博文大多只做基础 SKU 传参调用,普遍存在URL 解析 SKU 逻辑简陋、全字段返回冗余浪费流量、佣金 / 优惠券分层解析缺失、无超时重试与限流管控、SPU 多规格聚合失效问题。本文基于京东联盟官方 URL 智能解析 SKU:正则自动从京东 item 链接提取纯数字 SKU,无需手动录入商品 ID 按需自定义返回字段:通过 fields 参数裁剪返回数据,减少 60% 无效报文,提升接口响应速度 三价结构化拆分:拆分标价、日常售价、券后到手价,同步解析佣金比例与佣金金额 SPU 多规格聚合:单商品多 SKU 规格统一归集,适配多规格铺货业务 全链路风控防护:异常重试、间隔休眠、错误码分级捕获,规避接口限流封禁 接口名称: 统一网关: 签名规则:MD5 大写加密,参数 ASCII 升序排序,首尾拼接 AppSecret 时间格式: 调用 QPS:单应用≤3 次 / 秒,批量采集单次间隔≥1.2s python 时间格式严禁毫秒戳:京东固定年月日时分秒字符串,秒级时间戳直接签名失败; fields 按需填写:全字段返回携带详情 HTML、海量规格数据,大批量采集极易超时; 自营标识 isJdSelf:1 代表京东自营、0 第三方,比价与带货筛选关键字段; 券后价取值 couponEndPrice:不能用原价减优惠券面额,部分满减券计算逻辑特殊; 批量采集必须休眠:短时间高频请求直接触发 KEY 限流,返回无权限报错。前言
jd.union.open.goods.detail.query详情接口,落地商品 URL 自动截取 SKU、自定义 fields 精简返回、券后价 / 佣金 / 自营标签结构化拆分、异常熔断 + 频率控速生产方案,全程依托官方开放接口合规开发,适配 CSDN 发文规范。一、差异化技术亮点(区别全网通用教程)
二、接口基础规范
jd.union.open.goods.detail.query(联盟官方单品详情接口)https://api.jd.com/routerjson,POST 请求,编码 UTF-8yyyy-MM-dd HH:mm:ss,服务端时差不能超 10 分钟
点击获取key和secret
三、完整可运行 Python 代码
运行import requests
import hashlib
import time
import re
import json
class JdGoodsDetailApi:
def __init__(self, app_key, app_secret):
self.app_key = app_key
self.app_secret = app_secret
self.api_url = "https://api.jd.com/routerjson"
self.version = "2.0"
def get_sku_from_url(self, goods_url):
"""从京东商品链接正则提取SKU"""
res = re.search(r'item\.jd\.com/(\d+)', goods_url)
return res.group(1) if res else None
def make_sign(self, params):
"""京东官方MD5签名:ASCII排序+首尾拼接secret+大写MD5"""
sorted_kv = sorted(params.items(), key=lambda x:x[0])
sign_src = self.app_secret
for k,v in sorted_kv:
sign_src += f"{k}{v}"
sign_src += self.app_secret
md5_val = hashlib.md5(sign_src.encode("utf8")).hexdigest().upper()
return md5_val
def get_detail(self, goods_url, fields="skuId,title,price,couponInfo,commissionInfo,isJdSelf,picList,spec"):
sku_id = self.get_sku_from_url(goods_url)
if not sku_id:
return {"code":-1,"msg":"链接解析SKU失败"}
# 公共参数
params = {
"app_key":self.app_key,
"method":"jd.union.open.goods.detail.query",
"timestamp":time.strftime("%Y-%m-%d %H:%M:%S"),
"format":"json",
"v":self.version,
"fields":fields,
"skuId":sku_id
}
params["sign"] = self.make_sign(params)
try:
resp = requests.post(self.api_url, data=params, timeout=12)
data = resp.json()
if "error_response" in data:
return {"code":-2,"msg":data["error_response"]["msg"]}
res_data = data["jd_union_open_goods_detail_query_response"]["result"]
item = res_data.get("goodsInfo",{})
# 结构化价格、佣金、优惠券
coupon = item.get("couponInfo",{})
commission = item.get("commissionInfo",{})
rst = {
"skuId":item.get("skuId"),
"title":item.get("title"),
"market_price":item.get("price"),
"coupon_price":coupon.get("couponEndPrice"),
"commission_rate":commission.get("commissionRate"),
"commission_amt":commission.get("commission"),
"is_jd_self":item.get("isJdSelf"),
"main_img":item.get("picList",[{}])[0].get("url")
}
time.sleep(1.2)
return {"code":200,"data":rst}
except Exception as e:
return {"code":-3,"msg":f"请求异常:{str(e)}"}
# 调用示例
if __name__ == "__main__":
AK = "替换你的AppKey"
AS = "替换你的AppSecret"
url = "https://item.jd.com/100032568972.html"
api = JdGoodsDetailApi(AK,AS)
print(json.dumps(api.get_detail(url),ensure_ascii=False,indent=2))四、开发踩坑总结(原创实战经验)