×

苏宁商品详情接口开发实践:参数组结构化解析与异常码拦截方案

Ace Ace 发表于2026-10-15 13:44:56 浏览3 评论0

抢沙发发表评论

前言

苏宁开放平台商品详情接口和多数电商接口有明显区别:返回数据嵌套层级多,商品参数为多组循环数组,同时接口采用独立异常码体系。常规直接取 JSON 字段的写法,很容易出现规格参数入库困难、活动价与日常价混淆、接口异常漏判问题。本文不只是简单演示接口调用,重点封装一套参数结构化解析、异常码拦截、自动重试的工具类,适合商品数据同步、比价业务场景。

前置准备

Python3 环境,依赖 requests 库。调用苏宁云台 API 需要提前申请 AppKey、AppSecret,请求报文需要按平台规则生成签名。接口有调用频次限制,高频请求会触发权限拦截,批量拉取需要控制请求间隔。

点击获取key和secret

完整代码示例

python
import requests
import time
import hashlib

class SuningDetailClient:
    def __init__(self, app_key, app_secret):
        self.app_key = app_key
        self.app_secret = app_secret
        self.session = requests.Session()
        self.retry_times = 2
        self.delay = 1.4

    def build_sign(self, params):
        """苏宁接口签名生成"""
        sort_str = "".join([k+params[k] for k in sorted(params.keys())])
        sign_raw = sort_str + self.app_secret
        return hashlib.md5(sign_raw.encode("utf-8")).hexdigest().upper()

    def get_item_detail(self, sku_id, supplier_code):
        """根据SKU编码获取苏宁商品详情,结构化解析参数"""
        api_url = "https://open.suning.com/api/http/sopRequest"
        req_params = {
            "appKey": self.app_key,
            "skuId": sku_id,
            "supplierCode": supplier_code
        }
        req_params["sign"] = self.build_sign(req_params)
        for i in range(self.retry_times):
            try:
                resp = self.session.post(api_url, json=req_params, timeout=12)
                time.sleep(self.delay)
                if resp.status_code != 200:
                    return {"code": resp.status_code, "data": None, "msg": "http请求失败"}
                res_json = resp.json()
                sn_body = res_json.get("sn_body", {})
                if res_json.get("sn_error"):
                    err_info = res_json["sn_error"]
                    return {"code":-1, "data":None, "msg":f"{err_info['error_code']}:{err_info['error_msg']}"}
                raw_detail = sn_body.get("queryItemdetail", {})
                # 商品参数数组转为键值对,方便入库
                param_map = {}
                for p in raw_detail.get("itemParameters", []):
                    param_map[p.get("parName")] = p.get("parValue")
                detail_result = {
                    "sku_id": raw_detail.get("skuId"),
                    "title": raw_detail.get("itemName", "").strip(),
                    "brand": raw_detail.get("brandName", ""),
                    "sale_price": raw_detail.get("price"),
                    "stock": raw_detail.get("invQty",0),
                    "images": [raw_detail.get(f"supplierImg{i}Url") for i in range(1,6) if raw_detail.get(f"supplierImg{i}Url")],
                    "params": param_map,
                    "is_on_sale": raw_detail.get("status") == 1
                }
                return {"code":0, "data":detail_result, "msg":"success"}
            except Exception as e:
                if i < self.retry_times -1:
                    time.sleep(2)
                    continue
                return {"code":-1, "data":None, "msg":str(e)}

if __name__ == "__main__":
    client = SuningDetailClient(app_key="your_key", app_secret="your_secret")
    ret = client.get_item_detail(sku_id="123456789", supplier_code="000000000")
    if ret["code"] ==0:
        item = ret["data"]
        print("商品名称:", item["title"])
        print("商品参数:", item["params"])
    else:
        print("查询失败:", ret["msg"])

核心逻辑解析


  1. 签名封装:实现平台 MD5 签名算法,自动排序参数生成签名,适配苏宁接口鉴权规则。

  2. 参数结构化转换:将循环的商品参数数组转为键值字典,避免嵌套数组入库麻烦,便于检索。

  3. 独立异常拦截:单独捕获 sn_error 节点,识别业务异常码,区分网络错误和业务权限错误。

  4. 失败重试:网络抖动时自动重试,减少单次调用失败造成的数据缺失。


线上踩坑要点


  1. 入参双必填:查询详情时 skuId 和 supplierCode 两个参数必须同时传入,缺少供应商编码直接返回无结果。

  2. 图片字段分散:商品图分 5 个独立字段,代码统一收集过滤空链接,避免无效图片地址入库。

  3. 状态校验:下架商品依然返回基础标题,需要 status 字段校验在售状态。

  4. 限流控制:单账号 QPS 有限制,批量同步需要做队列限速,短时间高频调用会返回权限异常码。


群贤毕至

访客