苏宁多规格商品 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"}
]
}
}
}
核心关联逻辑
- 主键关联 :
productCode(商品主 ID)是所有 SKU 的父级标识,SKU 编码通常以商品主 ID 为前缀(如100032189765+12=10003218976512); - 属性关联 :
skuAttr(SKU 属性组合)对应attributeInfo中的静态属性维度(如颜色、存储、尺寸等); - 价格 / 库存关联: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 版本更新时,优先适配
skuAttr和attributeInfo字段的格式变化; - 数据校验:解析后校验 SKU 数量、价格范围(如售价不能为负),过滤无效数据。
六、总结
苏宁多规格商品 API 解析的核心是「关联验证 + 多格式适配 + 维度标准化」:
- 关联验证:通过 SKU 编码前缀规则验证 SKU 与商品主 ID 的关联,过滤无效数据;
- 多格式适配:兼容不同分隔符、不同品类的属性格式,解决解析碎片化问题;
- 维度标准化:将属性值匹配到统一维度(颜色、内存、存储等),并标准化单位,适配下游业务场景。
本文的解析方案可直接应用于商品展示、价格监控、库存管理、SKU 下单等核心业务场景,兼顾通用性与品类适配性,确保多规格商品数据的准确解析。