×

api开发 电商平台 数据挖掘

Python 实战:快速接入淘宝 API 批量获取商品详情

admin admin 发表于2025-10-28 17:27:18 浏览35 评论0

抢沙发发表评论

在电商数据分析、竞品监控、价格跟踪等场景中,批量获取淘宝商品详情是一项常见需求。本文将通过 Python 实战演示如何快速接入淘宝开放平台 API,实现商品详情的批量获取,并提供可直接运行的代码示例。

一、前期准备

1. 淘宝平台账号注册

首先需要注册账号,创建应用并获取以下关键信息:

  • Api Key:应用标识

  • Api Secret:应用密钥

  • Access Token:访问令牌(需通过授权流程获取)

2. 了解核心 API

获取商品详情主要使用taobao.item.get接口,支持通过商品 ID(num_iid)获取单个商品的详细信息,可指定返回字段包括:

  • 基本信息:标题、价格、库存、销量

  • 类目信息:商品分类 ID、名称

  • 商家信息:卖家昵称、店铺名称

  • 图片信息:主图、详情图 URL

  • 规格信息:SKU、规格参数

二、开发环境配置

安装必要的 Python 依赖库:

pip install requests python-dotenv urllib3

三、核心代码实现

1. 配置文件管理

创建.env文件存储敏感信息(避免硬编码):

# .env文件内容
APP_KEY=你的AppKey
APP_SECRET=你的AppSecret
ACCESS_TOKEN=你的AccessToken
API_URL=http://gw.api.taobao.com/router/rest

2. API 调用工具类

实现淘宝 API 调用的核心工具类,处理签名生成、参数组装和请求发送:

import os
import time
import hmac
import hashlib
import base64
import requests
from urllib.parse import urlencode
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

class TaobaoAPIClient:
    def __init__(self):
        self.app_key = os.getenv('APP_KEY')
        self.app_secret = os.getenv('APP_SECRET')
        self.access_token = os.getenv('ACCESS_TOKEN')
        self.api_url = os.getenv('API_URL')
        
    def _generate_sign(self, params):
        """生成API签名"""
        # 按参数名ASCII排序
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        # 拼接参数
        query_string = urlencode(sorted_params)
        # 生成签名字符串
        sign_str = self.app_secret + query_string + self.app_secret
        # HMAC-SHA1加密
        sign = hmac.new(
            sign_str.encode('utf-8'),
            digestmod=hashlib.sha1
        ).digest()
        # Base64编码
        return base64.b64encode(sign).decode('utf-8')
        
    def call(self, method, params=None):
        """调用淘宝API"""
        if params is None:
            params = {}
            
        # 公共参数
        public_params = {
            'app_key': self.app_key,
            'format': 'json',
            'method': method,
            'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
            'v': '2.0',
            'sign_method': 'hmac-sha1',
            'session': self.access_token
        }
        
        # 合并参数
        all_params = {**public_params,** params}
        # 生成签名
        all_params['sign'] = self._generate_sign(all_params)
        
        try:
            # 发送请求
            response = requests.get(
                self.api_url,
                params=all_params,
                timeout=10
            )
            response.raise_for_status()
            result = response.json()
            
            # 处理错误响应
            if 'error_response' in result:
                error = result['error_response']
                raise Exception(f"API错误: {error['msg']} (错误码: {error['code']})")
                
            return result
        except Exception as e:
            print(f"调用失败: {str(e)}")
            return None

3. 商品详情批量获取工具

实现批量获取商品详情的功能,支持并发控制和失败重试:

import time
import json
from typing import List, Dict
from taobao_api_client import TaobaoAPIClient

class ProductDetailFetcher:
    def __init__(self, max_retries=3, interval=2):
        self.client = TaobaoAPIClient()
        self.max_retries = max_retries  # 最大重试次数
        self.interval = interval  # API调用间隔(秒)
        
    def fetch_single_product(self, num_iid: str) -> Dict:
        """获取单个商品详情"""
        # 需要返回的字段列表
        fields = (
            "num_iid,title,price,stock,sale_count,shop_name,nick,"
            "cid,category_name,pic_url,detail_url,skus,params"
        )
        
        for retry in range(self.max_retries):
            try:
                result = self.client.call(
                    "taobao.item.get",
                    {
                        "num_iid": num_iid,
                        "fields": fields
                    }
                )
                
                if result and "item_get_response" in result:
                    return result["item_get_response"]["item"]
                    
            except Exception as e:
                print(f"获取商品 {num_iid} 失败(第{retry+1}次重试): {str(e)}")
                time.sleep(self.interval)
                
        print(f"商品 {num_iid} 达到最大重试次数,获取失败")
        return None
        
    def fetch_batch_products(self, num_iids: List[str]) -> List[Dict]:
        """批量获取商品详情"""
        results = []
        total = len(num_iids)
        
        for index, num_iid in enumerate(num_iids, 1):
            print(f"正在获取商品 {index}/{total}: {num_iid}")
            product = self.fetch_single_product(num_iid)
            
            if product:
                results.append(product)
                # 保存中间结果
                self._save_temp_result(product)
                
            # 控制调用频率,避免触发限流
            if index < total:
                time.sleep(self.interval)
                
        return results
        
    def _save_temp_result(self, product: Dict, filename="temp_products.json"):
        """保存临时结果到文件"""
        try:
            with open(filename, 'a', encoding='utf-8') as f:
                json.dump(product, f, ensure_ascii=False)
                f.write('\n')
        except Exception as e:
            print(f"保存临时结果失败: {str(e)}")

    @staticmethod
    def save_results(products: List[Dict], filename="products_detail.json"):
        """保存最终结果到JSON文件"""
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(products, f, ensure_ascii=False, indent=2)
            print(f"成功保存 {len(products)} 个商品详情到 {filename}")
        except Exception as e:
            print(f"保存结果失败: {str(e)}")

4. 主程序调用

def main():
    # 要查询的商品ID列表(示例)
    product_ids = [
        "654879215632",
        "648752136547",
        "632547896521",
        "612547896325",
        "687542136589"
        # 可添加更多商品ID
    ]
    
    # 创建获取器实例
    fetcher = ProductDetailFetcher(
        max_retries=3,  # 失败重试3次
        interval=2      # 每2秒调用一次API
    )
    
    # 批量获取商品详情
    print(f"开始批量获取 {len(product_ids)} 个商品详情...")
    products = fetcher.fetch_batch_products(product_ids)
    
    # 保存结果
    if products:
        fetcher.save_results(products)
        
        # 打印统计信息
        print("\n获取统计:")
        print(f"总商品数: {len(product_ids)}")
        print(f"成功获取: {len(products)}")
        print(f"失败数量: {len(product_ids) - len(products)}")

if __name__ == "__main__":
    main()

四、代码使用说明

  1. 替换配置信息:将.env文件中的APP_KEYAPP_SECRETACCESS_TOKEN替换为实际值

  2. 准备商品 ID 列表:在main函数的product_ids列表中填入需要查询的商品 ID

  3. 调整参数:可根据需要调整max_retries(重试次数)和interval(调用间隔)

  4. 运行程序:执行主程序后,结果将保存到products_detail.json文件中

五、优化建议

  1. 并发处理:对于大量商品 ID,可使用concurrent.futures实现多线程并发获取(注意控制并发数,避免触发限流)

  2. 增量更新:记录已获取的商品 ID 和更新时间,实现增量更新

  3. 字段定制:根据实际需求修改fields参数,只获取需要的字段,减少数据传输量

  4. 异常监控:添加更完善的日志记录和异常告警机制

  5. 代理池:如果需要大量调用,可配置代理池避免 IP 被限制

六、注意事项

  1. 淘宝 API 有调用频率限制,不同级别的应用有不同的配额,需合理控制调用频率

  2. 部分字段需要特定的 API 权限,使用前请确保已获取相应权限

  3. 商业使用需遵守淘宝平台的相关协议和规定

  4. Access Token 有有效期,需定期更新

通过以上代码,你可以快速实现淘宝商品详情的批量获取功能,为电商数据分析、竞品监控等业务场景提供数据支持。根据实际需求,还可以进一步扩展功能,如数据清洗、入库存储、可视化展示等。


少长咸集

群贤毕至

访客