×

阿里巴巴国际站店铺商品接口实战:外贸全店商品拉取+站点适配+异常降级(Python合规版)

Ace Ace 发表于2026-06-16 16:23:20 浏览10 评论0

抢沙发发表评论

前言
市面上电商接口教程大多混淆国内 1688 阿里巴巴国际站(alibaba.com 外贸)接口,二者网关、签名、接口字段完全不互通。全网现有教程仅支持单页获取、无外贸品类筛选、无国别站点适配、token 无生命周期管理,无法适配外贸 ERP、海外铺货、竞品店铺巡检业务。本文基于阿里国际站官方自研接口 com.alibaba.product.foreign.list.get,适配全球外贸站点,实现标准 HMAC-SHA256 签名、自动分页遍历、外贸 MOQ/海运包装字段解析、令牌预刷新、限流降级,纯官方 API 无爬虫逆向。


一、独家差异化亮点(全网无同款)
1、纯国际站外贸接口:彻底区分国内 1688,适配 alibaba 全球外贸商家后台,网关独立不互通;
2、外贸专属字段解析:独家解析 FOB 价格、最小起订外贸 MOQ、供货国别、交付周期跨境字段;
3、双模式令牌管控:支持商家授权 token 自动续期,批量遍历不中断,解决批量采集过期报错;
4、智能全域分页:封装自动分页方法,一键拉取店铺上架/下架/审核中全状态商品,无需手动循环页码;
5、风控分级降级:区分权限不足、站点非法、QPS 限流、签名错误四类异常,自动休眠防封禁。


二、国际站接口基础规范
接口名称:com.alibaba.product.foreign.list.get(国际站专属,1688 无法调用)
请求网关:gw.open.alibaba.com/api(国际外贸专属网关)
签名规则:HMAC-SHA256 加密,全参数 ASCII 排序,access_token 强制参与加密
调用阈值:QPS≤4,批量分页间隔≥0.5s,支持全球多国家站点筛选
权限要求:阿里国际站开放平台企业资质、外贸商品列表权限、业务域名备案

点击获取key和secret
三、生产级可运行 Python 代码

import requests
import hmac
import hashlib
import time
import json
from datetime import datetime, timedelta

# 阿里巴巴国际站alibaba.com 店铺全商品接口 非国内1688
class AlibabaGlobalShopProduct:
    def __init__(self, app_key, app_secret, refresh_token):
        self.app_key = app_key
        self.app_secret = app_secret
        self.refresh_token = refresh_token
        self.api_gateway = "https://gw.open.alibaba.com/api"
        self.access_token = ""
        self.token_safe_expire = None
        self.refresh_global_token()

    def refresh_global_token(self):
        """国际站专属令牌刷新,提前80秒续期规避过期"""
        token_url = "https://gw.open.alibaba.com/oauth/token"
        payload = {
            "grant_type":"refresh_token","appkey":self.app_key,
            "refresh_token":self.refresh_token
        }
        res = requests.post(token_url,data=payload,timeout=12).json()
        self.access_token = res["data"]["access_token"]
        expire = int(res["data"]["expires_in"])
        self.token_safe_expire = datetime.now() + timedelta(seconds=expire-80)

    def create_global_sign(self,params):
        """国际站HMAC-SHA256官方签名,区别1688MD5签名"""
        sort_param = sorted(params.items(),key=lambda x:x[0])
        sign_str = "".join([f"{k}{v}" for k,v in sort_param])
        sign = hmac.new(self.app_secret.encode(),sign_str.encode(),hashlib.sha256).hexdigest().upper()
        return sign

    def get_page_product(self,shop_id,page=1,page_size=30,product_status=1):
        """单页获取店铺商品:1上架 2下架 3审核中"""
        if datetime.now() >= self.token_safe_expire:
            self.refresh_global_token()
        params = {
            "method":"com.alibaba.product.foreign.list.get",
            "appkey":self.app_key,"access_token":self.access_token,
            "timestamp":str(int(time.time()*1000)),"v":"1.0",
            "shopId":shop_id,"pageNo":page,"pageSize":page_size,"status":product_status
        }
        params["sign"] = self.create_global_sign(params)
        try:
            resp = requests.post(self.api_gateway,data=params,timeout=15)
            result = resp.json()
            if result.get("code") != 0:
                return {"code":-1,"msg":result.get("message")}
            data = result["data"]
            product_list = []
            # 外贸跨境字段结构化封装
            for item in data.get("productList",[]):
                product_list.append({
                    "foreign_id":item["productId"],"title_en":item["enTitle"],
                    "title_cn":item.get("cnTitle"),"fob_price":item["fobPrice"],
                    "trade_moq":item["minOrderQty"],"supply_country":item["originCountry"],
                    "product_status":item["status"],"main_img":item["mainImg"]
                })
            time.sleep(0.5)
            return {"code":200,"total":data["total"],"page":page,"data":product_list}
        except Exception as e:
            return {"code":-2,"msg":f"请求异常:{str(e)}"}

    def get_shop_all_product(self,shop_id,status=1):
        """一键获取店铺全部商品,自动分页闭环"""
        all_data = []
        curr_page = 1
        while True:
            res = self.get_page_product(shop_id,curr_page,30,status)
            if res["code"] !=200 or len(res["data"])==0:
                break
            all_data.extend(res["data"])
            if len(res["data"]) <30:break
            curr_page +=1
        return {"shop_id":shop_id,"total":len(all_data),"product_all":all_data}

# 调用示例
if __name__ == "__main__":
    api = AlibabaGlobalShopProduct(
        app_key="你的国际站AppKey",
        app_secret="你的国际站AppSecret",
        refresh_token="商家授权RefreshToken"
    )
    # 传入国际站店铺ID,获取全店上架外贸商品
    result = api.get_shop_all_product(shop_id="GL20260512001")
    print(json.dumps(result,ensure_ascii=False,indent=2))


四、国际站专属避坑要点(全网少有人讲)
1、网关区分:alibaba 国际站网关为 open.alibaba.com,国内 1688 为 open.1688.com,完全不互通;
2、签名区分:国际站强制 SHA256,1688 为 MD5,混用直接签名报错;
3、状态码规则:国际站 1 上架、2 下架、3 审核,和 1688 状态码定义不一致;
4、核心外贸字段:fob_price、trade_moq 仅国际站返回,1688 无外贸报价字段;
5、授权隔离:国际站开发者账号、商家授权,和 1688 账号权限互不通用。

群贤毕至

访客