×

🚀 别再爬虫了!1688官方API合法获取商品数据(附完整Python源码)

万邦科技Lex 万邦科技Lex 发表于2026-06-12 16:12:52 浏览17 评论0

抢沙发发表评论

结论先行:1688 有开放的官方商品查询接口(alibaba.item.get/ alibaba.offer.search),完全免费、合法、稳定,只需企业实名应用 + AppKey。比爬虫稳定10倍,不怕封IP、不改版、不违规。

一、为什么放弃爬虫选官方API?

维度
爬虫(Selenium/Requests)
1688官方API
合法性
⚠️ 违反ToS,有法律风险
✅ 签约开放平台,合规
稳定性
页面改版即挂
接口版本化管理
数据质量
需自己解析HTML,易缺字段
结构化JSON,含SKU/价格/图片
限流
IP被封
明确QPS(免费10~20/s),可买包扩容
维护成本
高(选择器/JS逆向)
几乎零(签名+调用)

二、前置准备(10分钟搞定)

  1. 注册 1688开放平台创建「自用型应用」

  2. 企业支付宝认证(个人账号无法调订单/部分字段)

  3. 申请接口权限:

    • alibaba.offer.search(商品搜索)

    • alibaba.item.get(商品详情)

  4. 记录 App Key+ App Secret

  5. (订单类需Access Token,商品查询可不传)


三、完整Python源码 —— 搜索 + 获取详情

# ali1688_official_api.py
import hashlib
import time
import requests
import urllib.parse
from typing import Dict, List, Optional
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex

class Ali1688OfficialClient:
    """
    1688 官方商品API客户端(合法替代爬虫)
    网关 + MD5签名 标准实现
    """
    GATEWAY_SEARCH = "https://gw.open.1688.com/openapi/param2/2/alibaba.offer.search/2.0"
    GATEWAY_COMMON = "https://gw.open.1688.com/openapi/http/2/1"

    def __init__(self, app_key: str, app_secret: str, access_token: str = None):
        self.app_key = app_key
        self.app_secret = app_secret
        self.access_token = access_token

    # ────────────────────────────────────────
    # 1688 标准 MD5 签名
    # ────────────────────────────────────────
    def _sign(self, params: Dict) -> str:
        filtered = sorted((k, v) for k, v in params.items() if v is not None)
        qs = ''.join(f"{k}{v}" for k, v in filtered)
        raw = f"{self.app_secret}{qs}{self.app_secret}"
        return hashlib.md5(raw.encode('utf-8')).hexdigest().upper()

    def _call(self, url: str, method: str, biz: Dict) -> Dict:
        api_params = {
            "method": method,
            "app_key": self.app_key,
            "timestamp": str(int(time.time() * 1000)),   # 毫秒!
            "format": "json",
            "v": "2.0",
            "sign_method": "md5",
        }
        if self.access_token:
            api_params["session"] = self.access_token

        # param2 = URL编码后的业务参数字符串
        api_params["param2" if "param2" in url or method == "alibaba.offer.search" else "param"] = \
            urllib.parse.quote_plus(str(biz).replace("'", '"'))
        api_params["sign"] = self._sign(api_params)

        resp = requests.get(url, params=api_params, timeout=15)
        resp.raise_for_status()
        data = resp.json()

        if "error_response" in data:
            err = data["error_response"]
            raise Exception(f"1688 API Error [{err.get('code')}]: {err.get('msg')}")

        result_key = [k for k in data if k != "error_response"][0]
        return data[result_key]

    # ────────────────────────────────────────
    # 1️⃣ 关键词搜索商品列表
    # ────────────────────────────────────────
    def search_products(self,
                         keyword: str,
                         page_no: int = 1,
                         page_size: int = 40,
                         price_min: Optional[float] = None,
                         price_max: Optional[float] = None) -> Dict:
        """
        返回: { offers: [...], totalResult: int, pageNo, pageSize }
        ⚠️ price单位 分!beginPrice=1500 表示 ≥15元
        """
        biz = {
            "keywords": keyword,
            "pageNo": page_no,
            "pageSize": min(page_size, 50),
            "sortType": "booked"     # 按成交量降序(选品推荐)
        }
        if price_min is not None:
            biz["beginPrice"] = str(int(price_min * 100))
        if price_max is not None:
            biz["endPrice"] = str(int(price_max * 100))

        return self._call(self.GATEWAY_SEARCH, "alibaba.offer.search", biz)

    # ────────────────────────────────────────
    # 2️⃣ 获取商品详情(含SKU/图片/批发价)
    # ────────────────────────────────────────
    def get_product_detail(self, offer_id: str, fields: str = None) -> Dict:
        """
        fields示例: "item_id,title,price,sku_list,pics,spec_info,min_order_quantity"
        """
        biz = {"item_id": offer_id}
        if fields:
            biz["fields"] = fields
        result = self._call(
            self.GATEWAY_COMMON, "alibaba.item.get", biz
        )
        return result.get("alibaba_item_get_response", {}).get("item", {})

# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# =========================================================
# 使用示例
# =========================================================
if __name__ == "__main__":
    client = Ali1688OfficialClient(
        app_key="YOUR_APP_KEY",
        app_secret="YOUR_APP_SECRET",
        access_token=None   # 商品搜索/详情可不传
    )

    try:
        # —— ① 搜索 ——
        result = client.search_products(
            keyword="不锈钢保温杯 定制",
            price_min=15,
            price_max=60,
            page_no=1,
            page_size=10
        )

        offers = result.get("offers", [])
        total = result.get("totalResult", 0)
        print(f"✅ 找到 {total} 个商品,本页 {len(offers)} 条")

        if not offers:
            exit()

        # —— ② 取第一个商品查详情 ——
        offer_id = str(offers[0].get("offerId"))
        detail = client.get_product_detail(
            offer_id,
            fields="item_id,title,price,sku_list,pics,min_order_quantity"
        )

        print(f"\n📦 商品标题: {detail.get('title')}")
        print(f"   起批价: ¥{detail.get('price')}")
        print(f"   最小起订量: {detail.get('min_order_quantity')}")
        print(f"   主图: {detail.get('pics', [''])[0]}")

        skus = detail.get("sku_list", [])
        if skus:
            print(f"   SKU数量: {len(skus)}")
            for sku in skus[:2]:
                print(f"     - {sku.get('spec_attributes')} 价:{sku.get('price')} 库存:{sku.get('amount_on_sale')}")

    except Exception as e:
        print(f"❌ {e}")

四、返回关键字段映射(B2B重点)

1688返回字段
含义
ERP用途
offerId/ item_id
商品唯一ID
外部单号关联
title
商品标题
显示名
price
起批参考价(字符串)
比价基准
sku_list[].price
SKU阶梯价
采购成本核算
sku_list[].spec_attributes
规格(颜色/尺寸)
SKU映射
min_order_quantity
MOQ
采购校验
pics[]
主图URL
商品图片
supplierName
供应商店铺
溯源

五、生产级建议

  1. 字段过滤:传 fields参数只取需要的字段 → 响应体积小、不易触发限流

  2. 限速:免费应用 QPS≈10,封装里加 time.sleep(0.15)或用令牌桶

  3. 翻页终止条件pageNo * pageSize >= totalResult停止翻页

  4. 增量更新:加 gmtModified筛选(部分接口支持),每天只拉变更商品

  5. 密钥安全AppSecret放环境变量 / 配置中心,严禁硬编码


六、一句话总结(面试版)

1688商品数据用官方开放平台API(alibaba.offer.search+ alibaba.item.get)合法获取,MD5签名按参数名ASCII升序拼 AppSecret+KV+AppSecret再大写,免费额度足够中小企业做选品/比价/主数据同步,不要用爬虫
需要我补充 OAuth2获取AccessToken代码每日增量同步APScheduler脚本SKU与内部ERP编码映射表设计 吗?


群贤毕至

访客