苏宁多规格商品 API 解析实战:SKU 关联逻辑与属性值提取技巧

苏宁多规格商品 API 解析实战:SKU 关联逻辑与属性值提取技巧

苏宁多规格商品(如手机、家电、服饰等)的 API 返回数据中,SKU 与商品主信息的关联逻辑复杂,属性值格式不统一(如分隔符、命名规则差异),是数据解析的核心难点。本文基于苏宁开放平台suning.custom.product.get API 实战,拆解 SKU 与商品主数据的关联逻辑,提供通用的属性值提取、规格维度拆分技巧,并适配不同品类的格式差异,实现多规格商品数据的标准化解析。

一、核心背景:苏宁多规格商品 API 数据结构

苏宁多规格商品的 API响应中,「商品主信息」与「SKU 子信息」是「1:N」的关联关系,核心结构如下:

json

json 复制代码
{
  "code": "0000",
  "msg": "success",
  "body": {
    "productInfo": {  // 商品主信息(唯一)
      "productCode": "100032189765",  // 商品主ID
      "productName": "小米14 5G手机【多规格】"
    },
    "skuInfo": {  // SKU子信息(多个)
      "skuList": [
        {
          "skuCode": "10003218976512",  // SKU唯一ID
          "skuAttr": "黑色+12GB+256GB", // SKU属性组合
          "salePrice": 3999.0,          // SKU单独售价
          "stockCount": 200             // SKU单独库存
        },
        {
          "skuCode": "10003218976513",
          "skuAttr": "白色+12GB+512GB",
          "salePrice": 4299.0,
          "stockCount": 150
        }
      ]
    },
    "attributeInfo": {  // 商品静态属性(补充规格维度说明)
      "attributeList": [
        {"attrName": "机身颜色", "attrValue": "黑色;白色;蓝色"},
        {"attrName": "存储容量", "attrValue": "256GB;512GB;1TB"}
      ]
    }
  }
}

核心关联逻辑

  1. 主键关联productCode(商品主 ID)是所有 SKU 的父级标识,SKU 编码通常以商品主 ID 为前缀(如100032189765 + 12 = 10003218976512);
  2. 属性关联skuAttr(SKU 属性组合)对应attributeInfo中的静态属性维度(如颜色、存储、尺寸等);
  3. 价格 / 库存关联:SKU 级的价格 / 库存优先级高于商品主信息的价格 / 库存(部分 SKU 有单独定价)。

二、SKU 关联逻辑拆解与验证

1. 主键关联规则(通用)

苏宁 SKU 编码生成遵循「商品主 ID + 规格序号」的规则,不同品类的序号长度不同(1-3 位),验证逻辑如下:

python

运行

python 复制代码
def verify_sku_product_relation(product_code: str, sku_code: str) -> bool:
    """
    验证SKU与商品主ID的关联关系
    :param product_code: 商品主ID
    :param sku_code: SKU编码
    :return: 是否关联
    """
    # 规则1:SKU编码以商品主ID为前缀
    if not sku_code.startswith(product_code):
        # 兼容部分品类SKU编码前缀省略末尾0的情况(如商品主ID=100032189760,SKU=1000321897612)
        if sku_code.startswith(product_code.rstrip("0")):
            return True
        return False
    # 规则2:前缀后至少1位规格序号
    seq_part = sku_code[len(product_code):]
    return len(seq_part) >= 1 and seq_part.isdigit()

# 测试验证
product_code = "100032189765"
sku_code_valid = "10003218976512"
sku_code_invalid = "10003218988812"
print(verify_sku_product_relation(product_code, sku_code_valid))  # True
print(verify_sku_product_relation(product_code, sku_code_invalid))  # False

2. 价格 / 库存关联优先级

SKU 级价格 / 库存是实际可售数据,解析时需优先使用 SKU 维度数据,规则如下:

数据维度 优先级 适用场景
SKU 售价 最高 下单定价、价格监控
商品主售价 次高 无 SKU 单独定价时兜底
SKU 库存 最高 库存预警、可售判断
商品主库存 次高 无 SKU 单独库存时兜底

python

运行

python 复制代码
def get_sku_effective_price(sku_data: dict, product_price: float) -> float:
    """
    获取SKU有效售价(优先SKU售价,无则用商品主售价)
    :param sku_data: SKU单条数据
    :param product_price: 商品主售价
    :return: 有效售价
    """
    sku_price = float(sku_data.get("salePrice", 0.0))
    return sku_price if sku_price > 0 else product_price

def get_sku_effective_stock(sku_data: dict, product_stock: int) -> int:
    """
    获取SKU有效库存(优先SKU库存,无则用商品主库存)
    :param sku_data: SKU单条数据
    :param product_stock: 商品主库存
    :return: 有效库存
    """
    sku_stock = sku_data.get("stockCount", 0)
    # 处理苏宁库存格式(如"200+"→200,"无货"→0)
    if isinstance(sku_stock, str):
        if "+" in sku_stock:
            sku_stock = int(sku_stock.replace("+", ""))
        elif sku_stock in ["无货", "缺货"]:
            sku_stock = 0
        else:
            sku_stock = int(sku_stock) if sku_stock.isdigit() else 0
    return sku_stock if sku_stock >= 0 else product_stock

三、属性值提取核心技巧(适配多格式)

苏宁不同品类的skuAttr格式差异极大,是解析的核心痛点,以下是通用提取技巧:

1. 多分隔符适配(解决格式不统一)

skuAttr常见分隔符包括+/|、空格等,需适配所有分隔符拆分属性:

python

运行

python 复制代码
import re

def split_sku_attr(sku_attr: str) -> list:
    """
    拆分SKU属性字符串(适配多分隔符)
    :param sku_attr: SKU属性字符串(如"黑色+12GB+256GB"、"白色/512GB")
    :return: 拆分后的属性值列表
    """
    if not sku_attr:
        return []
    # 正则匹配所有常见分隔符,统一替换为+后拆分
    attr_str = re.sub(r"[/|;\s]", "+", sku_attr)
    # 去重空值、去重重复属性
    attr_list = [attr.strip() for attr in attr_str.split("+") if attr.strip()]
    return list(set(attr_list))

# 测试多格式拆分
test_attrs = [
    "黑色+12GB+256GB",
    "白色/512GB",
    "蓝色 | 8GB | 128GB",
    "红色;256GB"
]
for attr in test_attrs:
    print(f"原始:{attr} → 拆分:{split_sku_attr(attr)}")
# 输出:
# 原始:黑色+12GB+256GB → 拆分:['黑色', '12GB', '256GB']
# 原始:白色/512GB → 拆分:['白色', '512GB']
# 原始:蓝色 | 8GB | 128GB → 拆分:['蓝色', '8GB', '128GB']
# 原始:红色;256GB → 拆分:['红色', '256GB']

2. 规格维度自动匹配(核心技巧)

拆分后的属性值需匹配到具体维度(如颜色、内存、存储、尺寸等),需结合attributeInfo中的静态属性维度实现自动匹配:

python

运行

python 复制代码
def match_sku_attr_dimension(sku_attr_list: list, product_attr_list: list) -> dict:
    """
    将SKU属性值匹配到具体维度(如颜色、存储)
    :param sku_attr_list: 拆分后的SKU属性值列表
    :param product_attr_list: 商品静态属性列表(来自attributeInfo)
    :return: 维度→属性值的字典
    """
    # 步骤1:提取商品静态属性的维度(如机身颜色、存储容量)
    attr_dimensions = {}
    for attr in product_attr_list:
        attr_name = attr.get("attrName", "").strip()
        attr_value = attr.get("attrValue", "").strip()
        if not attr_name or not attr_value:
            continue
        # 标准化维度名称(统一关键词)
        std_dim = ""
        if "颜色" in attr_name:
            std_dim = "颜色"
        elif "内存" in attr_name or "运行内存" in attr_name:
            std_dim = "内存"
        elif "存储" in attr_name or "容量" in attr_name and "GB" in attr_value:
            std_dim = "存储"
        elif "尺寸" in attr_name or "尺码" in attr_name:
            std_dim = "尺寸"
        elif "功率" in attr_name:
            std_dim = "功率"
        if std_dim:
            # 提取该维度的所有可选值(如黑色;白色;蓝色→["黑色","白色","蓝色"])
            attr_dimensions[std_dim] = [v.strip() for v in attr_value.split(";")]
    
    # 步骤2:将SKU属性值匹配到标准化维度
    sku_attr_dict = {}
    for attr_value in sku_attr_list:
        matched = False
        for dim, dim_values in attr_dimensions.items():
            if attr_value in dim_values:
                sku_attr_dict[dim] = attr_value
                matched = True
                break
        # 未匹配到预设维度时,自动识别(如含GB的是存储/内存,颜色关键词)
        if not matched:
            if "GB" in attr_value:
                if attr_value in ["8GB", "12GB", "16GB"]:
                    sku_attr_dict["内存"] = attr_value
                else:
                    sku_attr_dict["存储"] = attr_value
            elif any(color in attr_value for color in ["黑色", "白色", "红色", "蓝色", "绿色"]):
                sku_attr_dict["颜色"] = attr_value
            else:
                sku_attr_dict["其他规格"] = attr_value
    return sku_attr_dict

# 测试维度匹配
product_attr_list = [
    {"attrName": "机身颜色", "attrValue": "黑色;白色;蓝色"},
    {"attrName": "存储容量", "attrValue": "256GB;512GB;1TB"},
    {"attrName": "运行内存", "attrValue": "8GB;12GB;16GB"}
]
sku_attr_list = ["黑色", "12GB", "256GB"]
print(match_sku_attr_dimension(sku_attr_list, product_attr_list))
# 输出:{'颜色': '黑色', '内存': '12GB', '存储': '256GB'}

3. 特殊品类适配(服饰 / 家电)

3.1 服饰类(尺码 / 颜色为主)

服饰类skuAttr常为「颜色 - 尺码」格式(如 "黑色 - L 码"),需适配尺码维度识别:

python

运行

python 复制代码
def adapt_clothing_sku_attr(sku_attr_list: list) -> dict:
    """适配服饰类SKU属性解析"""
    size_keywords = ["XS", "S", "M", "L", "XL", "XXL", "XXXL", "码", "号"]
    color_keywords = ["黑", "白", "红", "蓝", "绿", "粉", "黄", "紫"]
    
    sku_attr_dict = {}
    for attr in sku_attr_list:
        if any(kw in attr for kw in size_keywords):
            sku_attr_dict["尺码"] = attr
        elif any(kw in attr for kw in color_keywords):
            sku_attr_dict["颜色"] = attr
        else:
            sku_attr_dict["版型"] = attr  # 如宽松、修身
    return sku_attr_dict

# 测试服饰适配
clothing_attr_list = ["黑色", "XL码"]
print(adapt_clothing_sku_attr(clothing_attr_list))  # {'颜色': '黑色', '尺码': 'XL码'}
3.2 家电类(功率 / 尺寸为主)

家电类skuAttr含功率、尺寸等数值型属性,需标准化单位:

python

运行

python 复制代码
def adapt_appliance_sku_attr(sku_attr_list: list) -> dict:
    """适配家电类SKU属性解析"""
    sku_attr_dict = {}
    for attr in sku_attr_list:
        if "W" in attr or "千瓦" in attr:
            # 统一单位为W(如"1.5千瓦"→"1500W")
            if "千瓦" in attr:
                kw = float(attr.replace("千瓦", "").strip())
                attr = f"{int(kw*1000)}W"
            sku_attr_dict["功率"] = attr
        elif "mm" in attr or "cm" in attr:
            # 统一单位为mm(如"60cm"→"600mm")
            if "cm" in attr:
                cm = float(attr.replace("cm", "").strip())
                attr = f"{int(cm*10)}mm"
            sku_attr_dict["尺寸"] = attr
        elif "升" in attr:
            sku_attr_dict["容量"] = attr
    return sku_attr_dict

# 测试家电适配
appliance_attr_list = ["1.5千瓦", "60cm"]
print(adapt_appliance_sku_attr(appliance_attr_list))  # {'功率': '1500W', '尺寸': '600mm'}

四、完整解析实战(多规格商品)

1. 全流程解析函数

python

运行

python 复制代码
import json
from typing import Dict, List

def safe_extract_field(data: Dict, field_path: str, default: any = None) -> any:
    """安全提取嵌套字段"""
    keys = field_path.split(".")
    value = data
    for key in keys:
        if isinstance(value, dict) and key in value:
            value = value[key]
        else:
            return default
    return value

def parse_suning_multi_sku_product(raw_api_data: Dict) -> Dict:
    """
    全流程解析苏宁多规格商品API数据
    :param raw_api_data: API原始响应数据
    :return: 标准化的多规格商品数据
    """
    # 1. 提取基础信息
    product_code = safe_extract_field(raw_api_data, "body.productInfo.productCode", "")
    product_name = safe_extract_field(raw_api_data, "body.productInfo.productName", "")
    product_price = float(safe_extract_field(raw_api_data, "body.priceInfo.salePrice", 0.0))
    product_stock = safe_extract_field(raw_api_data, "body.stockInfo.stockCount", 0)
    # 处理商品主库存格式
    if isinstance(product_stock, str):
        product_stock = int(product_stock.replace("+", "")) if "+" in product_stock else 0

    # 2. 提取商品静态属性列表
    product_attr_list = safe_extract_field(raw_api_data, "body.attributeInfo.attributeList", [])

    # 3. 提取SKU列表并解析
    sku_list = safe_extract_field(raw_api_data, "body.skuInfo.skuList", [])
    parsed_skus = []
    for sku in sku_list:
        sku_code = sku.get("skuCode", "")
        sku_attr_str = sku.get("skuAttr", "")
        
        # 验证SKU与商品主ID的关联
        is_related = verify_sku_product_relation(product_code, sku_code)
        if not is_related:
            print(f"SKU {sku_code} 与商品 {product_code} 无关联,跳过")
            continue
        
        # 拆分SKU属性
        sku_attr_list = split_sku_attr(sku_attr_str)
        
        # 匹配属性维度(优先用商品静态属性,无则自动识别)
        sku_attr_dict = match_sku_attr_dimension(sku_attr_list, product_attr_list)
        # 适配特殊品类(可根据商品类目选择适配函数)
        category_name = safe_extract_field(raw_api_data, "body.productInfo.categoryName", "")
        if "服饰" in category_name:
            sku_attr_dict = adapt_clothing_sku_attr(sku_attr_list)
        elif "家电" in category_name or "电器" in category_name:
            sku_attr_dict = adapt_appliance_sku_attr(sku_attr_list)
        
        # 获取SKU有效价格和库存
        sku_effective_price = get_sku_effective_price(sku, product_price)
        sku_effective_stock = get_sku_effective_stock(sku, product_stock)
        
        # 组装SKU解析结果
        parsed_sku = {
            "SKU编码": sku_code,
            "关联商品主ID": product_code,
            "属性维度": sku_attr_dict,
            "原始属性字符串": sku_attr_str,
            "有效售价(元)": round(sku_effective_price, 2),
            "有效库存数": sku_effective_stock,
            "SKU状态": "可售" if sku.get("skuStatus") == "1" else "不可售"
        }
        parsed_skus.append(parsed_sku)

    # 4. 组装最终结果
    final_result = {
        "商品主信息": {
            "商品主ID": product_code,
            "商品名称": product_name,
            "商品主售价(元)": round(product_price, 2),
            "商品主库存数": product_stock,
            "是否多规格": len(parsed_skus) > 1
        },
        "SKU列表": parsed_skus,
        "静态属性列表": product_attr_list
    }
    return final_result

# 2. 测试实战(模拟苏宁API返回数据)
if __name__ == "__main__":
    # 模拟多规格手机商品API响应
    mock_raw_data = {
        "code": "0000",
        "msg": "success",
        "body": {
            "productInfo": {
                "productCode": "100032189765",
                "productName": "小米14 5G手机【多规格】",
                "categoryName": "数码家电-手机通讯-5G手机"
            },
            "priceInfo": {
                "salePrice": 3999.0
            },
            "stockInfo": {
                "stockCount": "500+"
            },
            "skuInfo": {
                "skuList": [
                    {
                        "skuCode": "10003218976512",
                        "skuAttr": "黑色+12GB+256GB",
                        "salePrice": 3999.0,
                        "stockCount": "200+",
                        "skuStatus": "1"
                    },
                    {
                        "skuCode": "10003218976513",
                        "skuAttr": "白色/12GB/512GB",
                        "salePrice": 4299.0,
                        "stockCount": 150,
                        "skuStatus": "1"
                    },
                    {
                        "skuCode": "10003218988814",  # 无效SKU(无关联)
                        "skuAttr": "蓝色+16GB+1TB",
                        "salePrice": 4999.0,
                        "stockCount": 100,
                        "skuStatus": "1"
                    }
                ]
            },
            "attributeInfo": {
                "attributeList": [
                    {"attrName": "机身颜色", "attrValue": "黑色;白色;蓝色"},
                    {"attrName": "运行内存", "attrValue": "8GB;12GB;16GB"},
                    {"attrName": "存储容量", "attrValue": "256GB;512GB;1TB"}
                ]
            }
        }
    }

    # 全流程解析
    parsed_result = parse_suning_multi_sku_product(mock_raw_data)
    # 格式化输出
    print(json.dumps(parsed_result, ensure_ascii=False, indent=2))

2. 解析结果输出

json

json 复制代码
{
  "商品主信息": {
    "商品主ID": "100032189765",
    "商品名称": "小米14 5G手机【多规格】",
    "商品主售价(元)": 3999.0,
    "商品主库存数": 500,
    "是否多规格": true
  },
  "SKU列表": [
    {
      "SKU编码": "10003218976512",
      "关联商品主ID": "100032189765",
      "属性维度": {
        "颜色": "黑色",
        "内存": "12GB",
        "存储": "256GB"
      },
      "原始属性字符串": "黑色+12GB+256GB",
      "有效售价(元)": 3999.0,
      "有效库存数": 200,
      "SKU状态": "可售"
    },
    {
      "SKU编码": "10003218976513",
      "关联商品主ID": "100032189765",
      "属性维度": {
        "颜色": "白色",
        "内存": "12GB",
        "存储": "512GB"
      },
      "原始属性字符串": "白色/12GB/512GB",
      "有效售价(元)": 4299.0,
      "有效库存数": 150,
      "SKU状态": "可售"
    }
  ],
  "静态属性列表": [
    {"attrName": "机身颜色", "attrValue": "黑色;白色;蓝色"},
    {"attrName": "运行内存", "attrValue": "8GB;12GB;16GB"},
    {"attrName": "存储容量", "attrValue": "256GB;512GB;1TB"}
  ]
}

五、避坑指南与优化建议

1. 常见解析问题及解决方案

问题类型 表现形式 解决方案
SKU 编码无关联 SKU 编码不以商品主 ID 为前缀 过滤无效 SKU,记录异常 SKU 编码用于核查
属性值匹配失败 拆分后的属性值无对应维度 新增「其他规格」维度兜底,避免字段缺失
单位格式混乱 功率有 "W"、"千瓦",尺寸有 "cm"、"mm" 统一单位(如功率→W,尺寸→mm)
部分 SKU 无价格 / 库存 SKU 售价为 0 或库存为空 用商品主价格 / 库存兜底,并标记「数据异常」
特殊字符干扰 SKU 属性含 emoji、特殊符号(如🔥) 正则过滤非中文 / 数字 / 字母字符:re.sub(r'[^\u4e00-\u9fa50-9A-Za-zGBW]+', '', attr)

2. 性能优化建议

  • 缓存维度映射:将商品类目→规格维度的映射关系缓存(如手机→颜色、内存、存储),避免重复解析;
  • 批量解析:批量处理多商品时,先提取所有 SKU 属性格式,统一适配分隔符,提升解析效率;
  • 异步解析 :使用aiohttp异步调用 API,结合多进程解析 SKU 属性,适配万级商品批量解析。

3. 合规与稳定性建议

  • 异常日志:记录解析失败的 SKU 编码、属性字符串,便于后续排查;
  • 版本兼容 :苏宁 API 版本更新时,优先适配skuAttrattributeInfo字段的格式变化;
  • 数据校验:解析后校验 SKU 数量、价格范围(如售价不能为负),过滤无效数据。

六、总结

苏宁多规格商品 API 解析的核心是「关联验证 + 多格式适配 + 维度标准化」:

  1. 关联验证:通过 SKU 编码前缀规则验证 SKU 与商品主 ID 的关联,过滤无效数据;
  2. 多格式适配:兼容不同分隔符、不同品类的属性格式,解决解析碎片化问题;
  3. 维度标准化:将属性值匹配到统一维度(颜色、内存、存储等),并标准化单位,适配下游业务场景。

本文的解析方案可直接应用于商品展示、价格监控、库存管理、SKU 下单等核心业务场景,兼顾通用性与品类适配性,确保多规格商品数据的准确解析。

相关推荐
网安情报局17 小时前
告别排队与高延迟:直连GPT全系列,解锁低门槛、高稳定的AI生产力
人工智能·gpt·api·ai大模型
天空属于哈夫克32 天前
企微 RPA 接口开放:无需官方权限,外部群自由操作
自动化·企业微信·api
ZorChi2 天前
AI API 调用优化实战:统一入口与超时处理指南
人工智能·aigc·接口·api·agent·token·中转站
Resistance丶未来2 天前
管控用量,降本增效,MAI Gateway:助力企业搭建 Tokens 统一管理体系
人工智能·大模型·api·claude·ai安全·魔芋ai·maigateway
星浩AI3 天前
Agnes AI 免费 API 接入指南:文本、生图、生视频,一套接口全免费
llm·api·claude
触底反弹4 天前
大模型时代:5 个 Prompt 替代 BERT 训练,搞定 NLP 五大任务
人工智能·node.js·api
极连AI4 天前
国产大模型譬如DeepSeek接入codex教程分享
人工智能·gpt·chatgpt·api·token·极连ai·zovelox.com
MageGojo4 天前
OCR 火车票识别 API 服务介绍与使用考量
ocr·接口·api·数据提取·火车票识别
147API4 天前
Project Glasswing 扩展后,AI 安全扫描不能只看发现漏洞
人工智能·安全·api·claude
小二·5 天前
OpenAI API 实战指南
ai·openai·api