1688 / 京东 / 淘宝 item_get 返回字段逐个拆:三个平台的真实报文差在哪

跨平台做数据的人,八成的调试时间花在同一件事上:这个字段到底叫什么、是什么意思、单位是啥。这篇不讲架构,只把三个平台 item_get 的请求参数和返回报文摊开逐个字段过一遍,附一份可直接用的字段映射表。

一、请求侧:一个网关跑三个平台

三个平台的调用形式完全统一,差异只在路径里的平台名:

arduino 复制代码
https://api-gw.onebound.cn/{平台名}/{接口名}/

平台名取 1688 / jd / taobao,接口名就是 item_get。公共参数三平台一致:

参数 必填 说明 取值
key 是 应用 key 控制台分配
secret 是 应用密钥 控制台分配
api_name 否 接口名,部分调用方式需显式指定 item_get
cache 否 是否走缓存 yes(默认)/ no
result_type 否 返回格式 json / xml / serialize
lang 否 文案语言 cn / en

业务参数只有一个:num_iid(商品 ID)。所以最小的调用就是:

bash 复制代码
curl "https://api-gw.onebound.cn/1688/item_get/?key=你的key&secret=你的secret&num_iid=623415409661&cache=yes&result_type=json&lang=cn"

返回的外层结构三平台也是同一套,先认这几个字段再谈业务字段:

json 复制代码
{
  "item":   { "...商品字段..." },
  "error":  "",
  "error_code": "0000",
  "reason": "",
  "execution_time": 0.318,
  "request_id": "b2f1c9d8..."
}

判成败只看 error_code:0000 是成功,2000 是搜索类接口的"无结果",4000 / 4001 / 4002 / 4017 是请求侧问题。这里有个和花费直接相关的细节值得记住:0000 和 2000 都计费,那四个 4 开头的错误码不计费 。所以拿 2000 去轮询搜索等于持续花钱买空结果,而参数写错反倒不花钱------调试阶段真正该防的是前者。

二、1688:item 里最需要看清的字段

1688 的 item 返回字段多且杂,做成本核算和铺货真正高频用到的就这些:

字段 含义 实测注意点
num_iid 报价 ID 唯一,建议加平台前缀后再当主键
title 标题 常带供应商自造的促销前缀
price 价格 区间字符串 ,如 "3.20-5.80",不是数字
orginal_price 原价 官方字段名就是拼错的,别"顺手改对"
min_num 起订量 一件代发场景必须看,2 件起订的款不能按 1 件卖
quantity 库存 单位随类目变,可能是件/打/箱
sold_quantity 成交量 选品排序的主要依据
seller_nick / company_name 店铺 同一供应商可能有多个店铺
pic_url / item_imgs 主图/图集 图集是数组,铺货时按需截取
skus.sku[] 规格数组 真正的价格与库存都在这里

skus 要单独讲,因为它是唯一能拿到规格级价格的地方:

json 复制代码
"skus": {
  "sku": [
    {
      "sku_id": "4902881234567",
      "properties": "1627207:28320;20509:28314",
      "properties_name": "颜色:黑色;尺码:L",
      "quantity": 812,
      "price": "3.20",
      "orginal_price": "4.50"
    }
  ]
}

properties 是平台的属性 ID 组合,properties_name 才是人看的文案。做规格库存判断必须用 sku[].quantity,不能用外层的 quantity------外层那个是全部规格的合计,拿它算可售量会把某个已断货的规格也放出去卖。

上面这些字段名和那个拼错的 orginal_price,我都核过好几遍。最快的核对方式不是翻文档,是在调试工具里打一份真实响应回来逐行对照,入口在 开放平台控制台,需要的自取。

三、京东:字段名相似,能力边界差很多

京东的 item_get 返回结构跟 1688 高度相似(price、title、pic_url、skus 都在),但有两个实操层面的差别。

一是 ID 前缀问题。 京东同一款商品在不同入口下可能返回纯数字 skuId,也可能带 J_ 前缀。落库前统一清洗,否则同一个款会存成两条记录。

二是不少字段要走别的接口。 京东 item_get 后台统计只有 78% ,item_get_pro 也是 78%,item_history_price 75%------这条链路稳定性明显低于 1688。但它的 item_get_desc 有 98% ,所以描述类字段从详情描述接口取,别指望主接口:

python 复制代码
def jd_desc(num_iid, key, secret):
    r = call("jd", "item_get_desc", num_iid=num_iid, key=key, secret=secret)
    return r["item"]["description"] if r.get("error_code") == "0000" else None

再补一条:京东的销量字段缺失很常见。想拿"卖得怎么样"这个信号,实际可用的替代是 item_review(评价接口,99% ),用评价数近似。至于 item_search------后台统计只有 28% ,别把主链路押在京东搜索上,它只适合做人工触发的补采。

四、淘宝:字段最全,但 item_get 的成功率是硬伤

淘宝返回的字段是三家里最完整的,问题出在成功率:item_get 和 item_get_pro 都只有 40% ------每 5 次调用只有 2 次能拿到 item,另外 3 次落空。

对比之下淘宝其他接口反而很稳 :item_link 100% 、item_search_shop_pro 96% 、item_password 95% 、item_search_img 92% 、item_search 85%。

这个分布直接决定了策略:别用 item_get 硬扛,改成"列表接口铺量 + 详情接口补点"。

python 复制代码
def tb_items(shop_id, page, key, secret):
    """用店铺商品接口取列表,96% 成功率,一次拿到一批商品的字段"""
    return call("taobao", "item_search_shop_pro",
                seller_id_or_nick=shop_id, page=page,
                key=key, secret=secret)

def tb_detail(num_iid, key, secret, retry=2):
    """详情接口只对重点商品调用,拿不到就明示为空,不硬等"""
    for i in range(retry):
        r = call("taobao", "item_get", num_iid=num_iid, key=key, secret=secret)
        if r.get("error_code") == "0000" and r.get("item"):
            return r["item"]
    return None      # 40% 的接口,拿不到是常态,别让它阻塞任务

五、字段映射表:让三个报文落进同一张表

差异认清了,落地就简单。写成声明式映射,新增平台只加一段配置:

python 复制代码
FIELD_MAP = {
    "1688": {"id": "num_iid", "price": "price", "origin": "orginal_price",
             "min_num": "min_num", "stock": "quantity", "sold": "sold_quantity",
             "seller": "seller_nick", "pic": "pic_url"},
    "jd":   {"id": "num_iid", "price": "price", "origin": "orginal_price",
             "min_num": "min_num", "stock": "quantity", "sold": "sold_quantity",
             "seller": "shop_name",  "pic": "pic_url"},
    "taobao": {"id": "num_iid", "price": "price", "origin": "orginal_price",
               "min_num": "min_num", "stock": "quantity", "sold": "sold_quantity",
               "seller": "nick",     "pic": "pic_url"},
}

def parse_price(raw):
    """'3.20-5.80' / '3.50' / '面议' 都要接得住"""
    if raw is None:
        return None, None
    nums = re.findall(r"\d+(?:\.\d+)?", str(raw))
    if not nums:
        return None, None            # 面议不能当 0,否则定价直接崩
    vals = [Decimal(n) for n in nums]
    return min(vals), max(vals)      # 一价时 min == max

parse_price 那两行是我改得最多的地方:早期版本直接 float(item["price"]),碰上区间价抛异常、碰上"面议"返回 0,定价模块跟着一起错。归一化函数的原则是"不确定就给 None,不要给默认值",让空值在后续校验里暴露出来,比默默按 0 元算安全得多。

六、收尾

字段这东西,看文档不如看报文。另外一个建议:把原始 item JSON 整段存进 raw_json 列------归一化一定会漏字段,能回捞历史报文比重新调接口便宜得多,毕竟成功和"无结果"都是要计费的。

相关推荐
行百里er1 小时前
Redis 核心数据结构(二)——List 与消息队列
redis·后端
知守观1 小时前
AI 代码审查实战:2022年Java老项目挑出20个坑,老炮只认15个
后端
创新技术阁1 小时前
FastapiAdmin插件介绍
前端·后端·fastapi
行百里er1 小时前
Redis 核心数据结构(三)——Hash,把一堆字段塞进一个 Key
redis·后端
isfox1 小时前
MapReduce 数据压缩:用 CPU 换 IO,这笔账怎么算?
后端
能掘金的小能手1 小时前
「数据库连不上」——一次误判,和它暴露出的排查盲区
后端
用户EasyAdminBlazor1 小时前
Blazor Admin 关联表怎么处理?EasyAdminBlazor Navigate、Include、Join 实战
后端
一粒麦仔1 小时前
llama.cpp / Ollama / LM Studio:本地 LLM 推理栈的硬核拆解
人工智能·后端·架构
一勺思维1 小时前
做完半年 AI Agent 应用,我踩过的 5 个坑,全是"看起来解决了"的那种
后端