×

api开发 电商平台 数据挖掘

Python 调用淘宝 API 实战:高效采集商品详情数据

admin admin 发表于2025-09-02 17:54:54 浏览19 评论0

抢沙发发表评论

在电商数据分析、竞品监控、价格跟踪等场景中,高效采集淘宝商品详情数据是关键环节。相比传统的网页爬虫,通过淘宝 API 获取数据不仅合规性更高,还能避免反爬机制限制,同时数据结构更规范、稳定性更强。本文将以 Python 为例,详细讲解如何调用淘宝 API 实现商品详情数据的采集,包含完整代码示例与实战注意事项。

一、前期准备:淘宝API 接入基础

在编写代码前,需完成账号注册、应用创建与 API 权限申请,这是调用 API 的前提条件。

1.1 注册淘宝API账号

  1. 访问登录;

  2. 完成开发者认证并申请 API 权限。

1.2 创建应用并获取关键参数

API 调用需 3 个核心参数,需在控制台获取:

  • Api Key:应用的唯一标识,用于识别调用方身份;

  • Api Secret:应用密钥,用于接口签名验证,需妥善保管,避免泄露;

  • Access Token:访问令牌,用于授权 API 调用(部分 API 需用户授权,部分可通过应用自身权限获取)。

操作步骤:

  1. 登录后进入「控制台」→「应用管理」→「创建应用」;

  2. 选择应用类型(如 “第三方应用” 或 “自用型应用”,个人开发者建议先创建 “自用型应用”);

  3. 填写应用名称、描述等信息,提交审核(通常 1-3 个工作日审核通过);

  4. 审核通过后,在应用详情页可查看App Key和App Secret;

  5. 申请:若调用 “商品详情查询” 类 API(如taobao.item.get),需在 “接口权限” 中申请对应权限。

1.3 核心 API 选择

本文以获取商品基础详情为例,选用淘宝的 **taobao.item.get** 接口,该接口支持通过商品 ID(num_iid)获取商品标题、价格、库存、类目、卖家信息等核心字段。

接口文档地址:

二、Python 调用淘宝 API 核心代码实现

2.1 环境依赖

淘宝 API 调用需通过 HTTP 请求发送,且需进行签名验证(确保请求未被篡改)。推荐使用requests库发送请求,urllib库处理参数编码,无需额外安装复杂 SDK。

安装依赖库:

pip install requests

2.2 核心代码:获取商品详情数据

代码逻辑分为 3 步:

  1. 构造 API 请求参数(含签名所需的公共参数与业务参数);

  2. 生成淘宝 API 要求的签名(签名算法为 MD5,需按特定规则排序参数);

  3. 发送 HTTP 请求,解析返回的 JSON 数据,并存储到本地文件(CSV 格式,便于后续分析)。

完整代码:

import requests
import hashlib
import time
import urllib.parse
import csv

# -------------------------- 1. 配置API核心参数 --------------------------
APP_KEY = "你的App Key"  # 替换为你的App Key
APP_SECRET = "你的App Secret"  # 替换为你的App Secret
ACCESS_TOKEN = "你的Access Token"  # 替换为你的Access Token
API_URL = "https://eco.taobao.com/router/rest"  # 淘宝API网关地址


# -------------------------- 2. 生成淘宝API签名 --------------------------
def generate_sign(params, app_secret):
    """
    按淘宝API签名规则生成签名:
    1. 参数按key字母升序排序;
    2. 拼接为"key=value"格式,并用&连接;
    3. 拼接app_secret,用MD5加密(大写)。
    """
    # 1. 按key升序排序
    sorted_params = sorted(params.items(), key=lambda x: x[0])
    # 2. 拼接参数字符串
    param_str = "&".join([f"{key}={value}" for key, value in sorted_params])
    # 3. 拼接app_secret并MD5加密
    sign_str = param_str + app_secret
    sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().upper()
    return sign


# -------------------------- 3. 调用taobao.item.get接口获取商品详情 --------------------------
def get_taobao_item_detail(num_iid):
    """
    通过商品ID(num_iid)获取商品详情
    :param num_iid: 商品ID(可从淘宝商品详情页URL中获取,如https://item.taobao.com/item.htm?id=123456789中的123456789)
    :return: 商品详情字典(失败返回None)
    """
    # 公共参数(所有淘宝API均需携带)
    public_params = {
        "app_key": APP_KEY,
        "method": "taobao.item.get",  # 接口名称
        "format": "json",  # 返回格式(支持json/xml)
        "v": "2.0",  # API版本
        "timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),  # 时间戳(格式固定)
        "sign_method": "md5",  # 签名方式
        "session": ACCESS_TOKEN  # Access Token(部分接口需携带)
    }

    # 业务参数(接口特定参数,参考taobao.item.get文档)
    business_params = {
        "num_iid": num_iid,
        "fields": "num_iid,title,price,stock,cid,seller_id,nick,item_desc"  # 需要获取的字段,用逗号分隔
    }

    # 合并所有参数
    all_params = {**public_params, **business_params}
    # 生成签名
    all_params["sign"] = generate_sign(all_params, APP_SECRET)

    # 发送HTTP GET请求
    try:
        response = requests.get(API_URL, params=all_params, timeout=10)
        response.raise_for_status()  # 若状态码非200,抛出异常
        result = response.json()

        # 检查返回结果是否正常(淘宝API错误会放在error_response中)
        if "error_response" in result:
            error = result["error_response"]
            print(f"API调用失败:{error['msg']}(错误码:{error['code']})")
            return None
        else:
            item_detail = result["item_get_response"]["item"]
            print(f"成功获取商品详情:{item_detail['title']}")
            return item_detail

    except Exception as e:
        print(f"请求异常:{str(e)}")
        return None


# -------------------------- 4. 数据存储:将商品详情保存到CSV文件 --------------------------
def save_item_to_csv(item_detail, file_path="taobao_item_detail.csv"):
    """
    将商品详情保存到CSV文件
    :param item_detail: 商品详情字典
    :param file_path: 保存路径
    """
    if not item_detail:
        print("无有效商品数据,无需保存")
        return

    # 定义CSV表头(与获取的fields对应)
    headers = ["num_iid", "title", "price", "stock", "cid", "seller_id", "nick", "item_desc"]
    # 提取数据(确保顺序与表头一致)
    row_data = [
        item_detail.get("num_iid", ""),
        item_detail.get("title", ""),
        item_detail.get("price", ""),
        item_detail.get("stock", ""),
        item_detail.get("cid", ""),
        item_detail.get("seller_id", ""),
        item_detail.get("nick", ""),
        item_detail.get("item_desc", "")  # 商品描述可能是HTML,需后续处理
    ]

    # 写入CSV(若文件不存在则创建,存在则追加)
    with open(file_path, "a", encoding="utf-8-sig", newline="") as f:
        writer = csv.writer(f)
        # 首次写入时添加表头
        import os
        if os.path.getsize(file_path) == 0:
            writer.writerow(headers)
        writer.writerow(row_data)
    print(f"商品数据已保存到:{file_path}")


# -------------------------- 5. 批量采集示例 --------------------------
if __name__ == "__main__":
    # 待采集的商品ID列表(可从Excel/数据库中读取,此处为示例)
    item_id_list = ["123456789", "987654321", "112233445"]  # 替换为实际需要采集的商品ID

    # 循环采集每个商品
    for num_iid in item_id_list:
        item_detail = get_taobao_item_detail(num_iid)
        if item_detail:
            save_item_to_csv(item_detail)
        time.sleep(2)  # 避免请求频率过高被限制(淘宝API有QPS限制,通常个人应用为10次/秒)

三、代码说明与实战注意事项

3.1 关键参数与逻辑说明

  1. 签名生成:淘宝 API 要求所有请求必须携带签名,签名的核心是 “参数排序 + MD5 加密”,若签名错误会直接返回400错误,需确保generate_sign函数中的参数排序与拼接逻辑正确;

  2. 字段选择:fields参数决定返回的商品字段,可根据需求调整(参考taobao.item.get文档的 “返回字段” 说明),避免获取无用数据浪费带宽;

  3. 请求频率控制:淘宝 API 调用有 QPS(每秒请求数)限制,个人应用通常为 10 次 / 秒,企业应用可更高。代码中通过time.sleep(2)控制间隔,避免触发限流(限流会返回429错误)。

3.2 常见问题与解决方案


问题现象

可能原因

解决方案

签名错误(error_code: 40)

1. App Secret 错误;2. 参数排序错误;3. 时间戳与服务器时间偏差过大

1. 核对 App Secret;2. 确保按 key 升序排序;3. 确保本地时间与北京时间一致(偏差不超过 5 分钟)

权限不足(error_code: 11)

未申请taobao.item.get接口权限

进入 “应用管理”→“接口权限”,申请该接口权限

商品不存在(error_code: 27)

1. 商品 ID 错误;2. 商品已下架 / 删除

核对商品 ID,确认商品状态(可在淘宝网页搜索该 ID 验证)


3.3 数据后续处理建议

  1. 商品描述处理:item_desc字段返回的是 HTML 格式的商品描述,可使用BeautifulSoup库提取纯文本:

from bs4 import BeautifulSoup
soup = BeautifulSoup(item_detail["item_desc"], "html.parser")
pure_desc = soup.get_text().strip()

2.批量数据管理:若需采集上千个商品 ID,建议将 ID 存储在 Excel 中,使用pandas库读取:

import pandas as pd
df = pd.read_excel("item_ids.xlsx")
item_id_list = df["num_iid"].tolist()  # 假设Excel中列名为num_iid

四、Java 版本调用思路(补充)

若需用 Java 实现,核心逻辑与 Python 一致,差异在于语言语法与工具类:

  1. HTTP 请求:使用OkHttp或HttpClient库;

  2. 签名生成:通过TreeMap对参数按 key 排序,MessageDigest类实现 MD5 加密;

  3. JSON 解析:使用FastJSON或Jackson库解析返回结果。

示例代码(核心签名部分):

import java.util.*;
import java.security.MessageDigest;

public class TaobaoApiSign {
    public static String generateSign(Map<String, String> params, String appSecret) {
        // 按key升序排序
        Map<String, String> sortedMap = new TreeMap<>(params);
        // 拼接参数
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        // 移除最后一个&,拼接appSecret
        String signStr = sb.substring(0, sb.length() - 1) + appSecret;
        // MD5加密
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(signStr.getBytes("UTF-8"));
            // 转为大写十六进制
            StringBuilder signSb = new StringBuilder();
            for (byte b : bytes) {
                signSb.append(String.format("%02X", b));
            }
            return signSb.toString();
        } catch (Exception e) {
            throw new RuntimeException("生成签名失败", e);
        }
    }
}

总结

通过淘宝 API 采集商品数据,是合规、高效的首选方案。本文通过 Python 完整实现了从 API 配置、签名生成、请求发送到数据存储的全流程,同时提供了常见问题解决方案与 Java 版本思路。实际应用中,需根据业务需求调整接口与字段,严格遵守淘宝 API 的调用规范,避免触发限流或账号风险。


少长咸集

群贤毕至

访客