×

淘宝/天猫 API 数据采集实战:item_get 接口字段详解与常见报错(如 invalid num_iid)解决方案(附源码)

万邦科技Lex 万邦科技Lex 发表于2026-05-16 16:17:19 浏览26 评论0

抢沙发发表评论

淘宝/天猫 item_get(对应官方 taobao.item.get)是获取商品详情的核心接口,但新手常因 num_iid无效、签名错误等问题无法获取数据。本文将详解接口字段、常见报错(特别是 invalid num_iid)的根源,并提供可直接运行的 Python 源码。

一、 接口基础与 num_iid解析

1. 接口核心参数

item_get用于获取商品标题、价格、销量、SKU 等全量信息。其核心请求参数如下:
参数
是否必填
说明
method
固定为 taobao.item.get
num_iid
商品数字 ID(注意:不是 iid字符串)
fields
需返回的字段,如 title,price,pic_url
num_iid的正确获取方式
从商品详情页 URL 中提取纯数字部分:
  • 淘宝:https://item.taobao.com/item.htm?id=**674904123402**

  • 天猫:https://detail.tmall.com/item.htm?id=**674904123402**

  • 注意:必须是 11-13 位的纯数字,不能包含字母或特殊字符。

2. 核心响应字段详解

接口返回的 JSON 结构通常包含 item_get_response-> item对象。以下是业务开发中最常用的字段:
字段
类型
说明
num_iid
Bigint
商品唯一 ID
title
String
商品标题
price
String
商品价格(原价)
promotion_price
String
促销价(如有)
pic_url
String
商品主图 URL
detail_url
String
商品详情页链接
sold_quantity
Integer
总销量(注意:部分类目可能受限)
num
Integer
库存数量
approve_status
String
商品状态:onsale(在售)/ instock(仓库中)
sku
List
SKU 列表(包含规格、价格、库存)
props_name
String
商品属性(如 "品牌:XX;材质:XX")

二、 高频报错与解决方案(重点:invalid num_iid

1. invalid num_iid/ ITEM_NOT_FOUND(错误码 27)

这是最常见的报错,通常表现为 isv.item-not-exist:invalid-numIid-or-iidITEM_NOT_FOUND
原因分析
  1. ID 格式错误num_iid包含空格、字母或非数字字符。

  2. 商品不存在:商品已下架、删除、或进入历史库(违规或被屏蔽)。

  3. 权限不足:该商品属于其他卖家,且你的应用未获得相应授权。

解决方案
  • 校验 ID:确保 num_iid为 11-13 位纯数字。

  • 状态检查:通过 taobao.items.onsale.get接口获取你店铺的在售商品 ID,确保 ID 来源正确。

  • 业务容错:一旦报此错误,应在本地标记该商品为“失效”,避免重复请求。

2. 签名错误(错误码 15)

原因:签名(sign)计算错误。
解决
  • 严格按照 ASCII 码升序 排序所有参数(包括公共参数)。

  • 确保 AppSecret正确,且参数值经过 URL 编码(特别是含空格或中文时)。

3. 频率限制(错误码 429)

原因:QPS(每秒请求数)超限。
解决
  • 免费版通常限制为 5 次/秒,需在代码中加入 time.sleep(0.2)控制节奏。

  • 使用缓存机制,避免对同一商品重复调用。


三、 Python 实战源码(含签名生成与错误处理)

以下代码实现了完整的淘宝 item_get接口调用,包含签名生成、参数校验和常见错误处理。
import hashlib
import time
import requests
import urllib.parse
from typing import Dict, Optional
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
class TaobaoItemAPI:
    """淘宝商品API客户端(支持item_get)"""
    
    def __init__(self, app_key: str, app_secret: str):
        self.app_key = app_key
        self.app_secret = app_secret
        self.gateway = "https://eco.taobao.com/router/rest"  # 正式环境网关
        
    def _generate_sign(self, params: Dict) -> str:
        """生成淘宝API签名(MD5加密)"""
        # 1. 按参数名ASCII升序排序
        sorted_params = sorted(params.items())
        # 2. 拼接键值对
        query_string = ''.join([f'{k}{v}' for k, v in sorted_params])
        # 3. 前后拼接AppSecret并MD5
        sign_str = self.app_secret + query_string + self.app_secret
        return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
    
    def _validate_num_iid(self, num_iid: str) -> bool:
        """校验num_iid格式(11-13位纯数字)"""
        if not num_iid or not num_iid.isdigit() or len(num_iid) < 11 or len(num_iid) > 13:
            raise ValueError(f"❌ 无效num_iid: {num_iid},必须为11-13位纯数字")
        return True
    
    def item_get(self, num_iid: str, fields: str = "num_iid,title,price,pic_url,detail_url,sold_quantity") -> Optional[Dict]:
        """
        调用taobao.item.get接口获取商品详情
        
        Args:
            num_iid: 商品数字ID(从URL中获取)
            fields: 需要返回的字段,逗号分隔
        
        Returns:
            dict: 商品信息字典,失败返回None
        """
        # 1. 参数校验
        self._validate_num_iid(num_iid)
        
        # 2. 构建公共参数
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        base_params = {
            "app_key": self.app_key,
            "method": "taobao.item.get",
            "timestamp": timestamp,
            "format": "json",
            "v": "2.0",
            "sign_method": "md5",
            "num_iid": num_iid,
            "fields": fields
        }
        
        # 3. 生成签名并添加
        base_params["sign"] = self._generate_sign(base_params)
        
        try:
            # 4. 发送GET请求
            response = requests.get(self.gateway, params=base_params, timeout=10)
            response.raise_for_status()
            result = response.json()
            
            # 5. 解析响应
            if "item_get_response" in result:
                item_data = result["item_get_response"].get("item", {})
                print(f"✅ 获取商品成功: {item_data.get('title', 'N/A')}")
                return item_data
            else:
                # 处理错误响应
                error = result.get("error_response", {})
                error_code = error.get("code")
                error_msg = error.get("msg", "未知错误")
                # 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
                if error_code in [27, "27"] or "invalid num_iid" in error_msg.lower():
                    print(f"❌ 商品不存在或ID无效 (Code: {error_code}): {error_msg}")
                elif error_code in [15, "15"]:
                    print(f"❌ 签名错误 (Code: {error_code}): 请检查AppSecret和参数排序")
                elif error_code in [429, "429"]:
                    print(f"⏳ 频率超限 (Code: {error_code}): 请降低调用频率")
                else:
                    print(f"⚠️ 接口调用失败 (Code: {error_code}): {error_msg}")
                return None
                
        except requests.exceptions.RequestException as e:
            print(f"🌐 网络请求失败: {e}")
            return None
        except ValueError as e:
            print(f"📦 JSON解析失败: {e}")
            return None

# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 请替换为你的实际密钥(从淘宝开放平台获取)
    APP_KEY = "你的AppKey"
    APP_SECRET = "你的AppSecret"
    
    # 示例商品ID(请替换为真实的在售商品ID)
    SAMPLE_NUM_IID = "674904123402"  # 示例ID,需替换
    
    # 初始化客户端
    client = TaobaoItemAPI(APP_KEY, APP_SECRET)
    
    # 调用item_get接口
    item = client.item_get(SAMPLE_NUM_IID)
    
    # 打印结果
    if item:
        print("📦 商品详情:")
        print(f"  商品ID: {item.get('num_iid')}")
        print(f"  标题: {item.get('title')}")
        print(f"  价格: {item.get('price')}")
        print(f"  销量: {item.get('sold_quantity', 0)}")
        print(f"  详情页: {item.get('detail_url')}")
    else:
        print("💥 获取商品详情失败,请检查上述错误信息。")

四、 生产环境最佳实践

  1. ID 来源管理

    • 不要依赖用户输入的 URL 直接提取 num_iid,应通过 taobao.items.onsale.get(获取在售商品)或 taobao.item.search(搜索商品)接口获取权威 ID。

  2. 错误重试机制

    • 对于网络错误(如超时)可重试 1-2 次,但对于 invalid num_iidITEM_NOT_FOUND绝对不要重试,直接标记为失效。

  3. 数据缓存

    • 商品基础信息(如标题、主图)变化频率低,可缓存 10-30 分钟,减少 API 调用压力。


💡 总结

item_get接口的核心在于 num_iid的准确性和签名的正确性。遇到 invalid num_iid错误时,首要任务是检查 ID 格式和来源,而非盲目重试。上述 Python 代码提供了完整的签名生成和错误处理逻辑,可直接用于业务开发。
互动话题
你在调用淘宝 API 时还遇到过哪些奇葩报错(如 subcode错误)?评论区分享你的踩坑经历!


群贤毕至

访客