×

义乌购商品详情接口实战:生产级签名与数据解析(附完整 Python 代码)

Ace Ace 发表于2026-04-16 16:48:13 浏览11 评论0

抢沙发发表评论


义乌购作为全球小商品批发核心平台,其商品详情接口是跨境选品、价格监控、供应链对接的关键数据入口。网上教程多聚焦简易调用,缺失标准签名、异常处理、字段解析等生产环节。本文基于官方开放平台规范,实现一套合规、稳定、可直接上线的调用方案,原创结构、无敏感操作,适配 CSDN 审核规范。

一、接口功能与适用场景

本文实现义乌购官方商品详情接口(/goods/detail),核心能力:

  • 按 goods_id 获取商品标题、主图、价格、起批量、库存

  • 支持规格参数、图片集、商家信息、发货地完整返回

  • 携带SHA1 签名 + 时间戳鉴权,防篡改与重放

  • 支持字段筛选(fields),优化响应体积

  • 适配中文 / 英文多语言,覆盖跨境业务场景

适用:批发选品系统、价格监控工具、跨境电商 ERP、供应链数据分析。

二、接口核心规范(官方标准)

  • 请求方式:GET

  • 基础 URL:https://api.yiwugo.com

  • 接口路径:/goods/detail

  • 鉴权:app_key+app_secret+SHA1 签名 + timestamp

  • 频率限制:100 次 / 分钟(企业可提额)

  • 时间戳:秒级,与服务器时差≤10 分钟

必选参数

  • app_key:应用 Key(开放平台申请)

  • goods_id:商品 ID(详情页 URL 提取)

  • timestamp:时间戳

  • sign:SHA1 签名(核心)

  • 可选:fields(指定返回字段)、lang(zh-CN/en-US)

签名规则(网上最易出错点)

  1. 所有参数(不含 sign)按ASCII 升序排序

  2. 拼接为key1=value1&key2=value2格式

  3. 首尾拼接app_secretsecret+param_str+secret

  4. 整体做SHA1 加密,转大写

点击获取key和secret

三、完整生产代码(Python)

python

运行

import requests
import hashlib
import time
import json
from typing import Dict, Optional

class YiWuGouAPI:
    """义乌购商品详情接口(生产级:签名+异常+重试)"""
    def __init__(self, app_key: str, app_secret: str):
        self.app_key = app_key
        self.app_secret = app_secret
        self.base_url = "https://api.yiwugo.com"
        self.timeout = 10
        self.retry = 2  # 自动重试

    def _generate_sign(self, params: Dict) -> str:
        """生成SHA1签名(严格官方规则)"""
        # 1. 过滤空值与sign
        filtered = {k: v for k, v in params.items() if v is not None and v != "" and k != "sign"}
        # 2. ASCII升序排序
        sorted_params = sorted(filtered.items(), key=lambda x: x[0])
        # 3. 拼接参数字符串
        param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
        # 4. 首尾加secret
        sign_str = f"{self.app_secret}{param_str}{self.app_secret}"
        # 5. SHA1加密+大写
        sign = hashlib.sha1(sign_str.encode("utf-8")).hexdigest().upper()
        return sign

    def get_goods_detail(self, goods_id: str, fields: Optional[str] = None, lang: str = "zh-CN") -> Dict:
        """获取商品详情"""
        url = f"{self.base_url}/goods/detail"
        # 基础参数
        params = {
            "app_key": self.app_key,
            "goods_id": goods_id,
            "timestamp": str(int(time.time())),
            "lang": lang
        }
        if fields:
            params["fields"] = fields  # 字段筛选优化
        
        # 生成签名
        params["sign"] = self._generate_sign(params)

        # 重试机制
        for attempt in range(self.retry + 1):
            try:
                resp = requests.get(url, params=params, timeout=self.timeout)
                resp.raise_for_status()
                result = resp.json()

                # 标准化返回
                if result.get("code") == 200:
                    data = result["data"]
                    return {
                        "code": 200,
                        "msg": "success",
                        "data": {
                            "goods_id": goods_id,
                            "title": data.get("title"),
                            "price": data.get("price"),
                            "min_order": data.get("min_num"),  # 起批量
                            "stock": data.get("stock_num"),
                            "images": [img.get("url") for img in data.get("images", [])],
                            "specs": data.get("specs"),
                            "seller_name": data.get("seller_name"),
                            "delivery_area": data.get("shipping_to")
                        }
                    }
                # 常见错误码
                elif result.get("code") == 401:
                    return {"code": 401, "msg": "签名失败/密钥错误", "data": None}
                elif result.get("code") == 429:
                    return {"code": 429, "msg": "请求超限,1分钟后重试", "data": None}
                elif result.get("code") == 404:
                    return {"code": 404, "msg": "商品不存在", "data": None}
                else:
                    return {"code": result.get("code"), "msg": result.get("msg", "未知错误"), "data": None}
            
            except Exception as e:
                if attempt == self.retry:
                    return {"code": 500, "msg": f"网络异常:{str(e)}", "data": None}
                time.sleep(1)

# 调用示例
if __name__ == "__main__":
    # 替换为开放平台申请的真实密钥
    APP_KEY = "your_app_key"
    APP_SECRET = "your_app_secret"
    GOODS_ID = "931405691"  # 示例商品ID

    api = YiWuGouAPI(APP_KEY, APP_SECRET)
    res = api.get_goods_detail(GOODS_ID, fields="title,price,min_num,images,seller_name")
    print(json.dumps(res, ensure_ascii=False, indent=2))

四、生产避坑要点(网上教程缺失)

  1. 签名严格校验:必须排序 + 首尾加 secret + 大写,否则 100% 失败

  2. 时间同步:本地时间误差 > 10 分钟直接鉴权失败,建议 NTP 同步

  3. 字段筛选:用 fields 指定返回字段,减少带宽、提升速度

  4. 起批量关键:批发场景min_num(起批量)比价格更重要

  5. 限流处理:批量调用用异步队列,避免 429 报错

  6. 异常全覆盖:签名、限流、超时、商品不存在全捕获

五、合规说明

  • 接口需在义乌购开放平台申请资质、签署协议

  • 数据仅限合法业务使用,禁止恶意爬取、倒卖

  • 价格为批发价,以平台实时报价为准

  • 本文不涉及逆向、破解,完全遵循官方规范

群贤毕至

访客