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

class AliexpressAPI:
    def __init__(self, app_key: str, app_secret: str, access_token: Optional[str] = None):
        """
        初始化速卖通API客户端
        
        参数:
            app_key: 应用的AppKey
            app_secret: 应用的AppSecret
            access_token: 访问令牌(可选)
        """
        self.app_key = app_key
        self.app_secret = app_secret
        self.access_token = access_token
        self.base_url = "https://gw.api.alibaba.com/openapi/param2/1/system.oauth2/"
    
    def generate_signature(self, params: Dict[str, Any]) -> str:
        """
        生成API请求签名
        
        参数:
            params: 请求参数
            
        返回:
            签名结果
        """
        # 按参数名排序
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        
        # 拼接参数名和参数值
        sign_text = self.app_secret
        for key, value in sorted_params:
            sign_text += f"{key}{value}"
        sign_text += self.app_secret
        
        # 计算MD5哈希
        signature = hashlib.md5(sign_text.encode('utf-8')).hexdigest().upper()
        return signature
    
    def get_access_token(self, authorization_code: str, redirect_uri: str) -> Dict[str, Any]:
        """
        获取访问令牌
        
        参数:
            authorization_code: 授权码
            redirect_uri: 重定向URI
            
        返回:
            包含访问令牌的响应
        """
        endpoint = "getToken/{}/{}".format(self.app_key, self.app_secret)
        url = self.base_url + endpoint
        
        params = {
            "grant_type": "authorization_code",
            "need_refresh_token": "true",
            "client_id": self.app_key,
            "client_secret": self.app_secret,
            "code": authorization_code,
            "redirect_uri": redirect_uri
        }
        
        response = requests.post(url, data=params)
        return response.json()
    
    def refresh_access_token(self, refresh_token: str) -> Dict[str, Any]:
        """
        刷新访问令牌
        
        参数:
            refresh_token: 刷新令牌
            
        返回:
            包含新访问令牌的响应
        """
        endpoint = "getToken/{}/{}".format(self.app_key, self.app_secret)
        url = self.base_url + endpoint
        
        params = {
            "grant_type": "refresh_token",
            "need_refresh_token": "true",
            "client_id": self.app_key,
            "client_secret": self.app_secret,
            "refresh_token": refresh_token
        }
        
        response = requests.post(url, data=params)
        return response.json()
    
    def execute(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        执行API请求
        
        参数:
            method: API方法名
            params: 请求参数
            
        返回:
            API响应
        """
        if not self.access_token:
            raise ValueError("访问令牌为空,请先获取访问令牌")
        
        # 公共参数
        common_params = {
            "method": method,
            "appKey": self.app_key,
            "session": self.access_token,
            "timestamp": str(int(time.time() * 1000)),
            "format": "json",
            "v": "2.0",
            "sign_method": "md5"
        }
        
        # 合并公共参数和业务参数
        all_params = {**common_params, **params}
        
        # 生成签名
        signature = self.generate_signature(all_params)
        all_params["sign"] = signature
        
        # 构建URL
        service_url = f"https://gw.api.alibaba.com/openapi/param2/2/aliexpress.open/{method}/{self.app_key}"
        
        # 发送请求
        response = requests.post(service_url, data=all_params)
        return response.json()
    
    def get_product_detail(self, product_id: str) -> Dict[str, Any]:
        """
        获取商品详情
        
        参数:
            product_id: 商品ID
            
        返回:
            商品详情数据
        """
        method = "aliexpress.product.redefining.findproductdetail"
        params = {
            "product_id": product_id
        }
        return self.execute(method, params)

# 使用示例
if __name__ == "__main__":
    # 替换为你的应用信息
    APP_KEY = "your_app_key"
    APP_SECRET = "your_app_secret"
    ACCESS_TOKEN = "your_access_token"
    
    # 初始化API客户端
    api = AliexpressAPI(APP_KEY, APP_SECRET, ACCESS_TOKEN)
    
    # 获取商品详情
    product_id = "1005001234567890"  # 替换为实际商品ID
    try:
        result = api.get_product_detail(product_id)
        print(json.dumps(result, indent=2, ensure_ascii=False))
    except Exception as e:
        print(f"请求出错: {e}")    

以上代码实现了一个完整的速卖通 API 接入方案,包含三个主要模块:

  1. AliexpressAPI类:负责与速卖通 API 进行通信,包括获取访问令牌、生成签名和执行 API 请求。
  2. ProductDataProcessor类:处理 API 返回的商品数据,并支持将数据保存为 JSON 或 CSV 格式。
  3. BatchProductCrawler类:实现批量商品数据采集功能,包含错误重试和请求间隔控制。

要使用这些代码,你需要先注册获取 ApiKey 和 ApiSecret,然后通过授权流程获取访问权限。代码中已经包含了详细的使用示例和注释,方便你理解和修改。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐