×

1688 item_search 接口对接全攻略:从入门到精通

万邦科技Lex 万邦科技Lex 发表于2025-10-07 10:44:02 浏览209 评论0

抢沙发发表评论

       注册账号免费测试1688API数据接口

1688 开放平台的item_search接口(对应官方标准接口portals.open.api.item.search)是按关键字搜索商品的核心工具,专为 B2B 批发场景设计,广泛应用于采购系统、供应链选品、竞品分析等业务。本文将从接口基础、对接流程、代码实现到高级优化,全面讲解如何高效对接该接口,覆盖从入门到精通的全流程。

一、接口基础认知

在开始对接前,需先明确接口的核心能力、环境差异及关键参数,避免后续开发走弯路。

1. 核心功能

item_search接口通过关键字、分类、价格区间、起订量等条件筛选 1688 商品,返回符合条件的商品列表及 B2B 场景特有的数据,例如:
  • 基础信息:商品 ID、标题、主图、详情页链接

  • 批发属性:批发价、价格区间(如 1-10 件 10 元 / 件,100 + 件 8 元 / 件)、起订量、混批支持

  • 供应商信息:店铺名称、公司名称、诚信通等级、交易记录

  • 库存与销量:可售数量、30 天成交件数、评价数

2. 接口环境

1688 开放平台区分「沙箱环境」和「正式环境」,开发阶段需先在沙箱验证逻辑,再切换到正式环境。
环境类型接口地址用途
沙箱环境https://gw.api.alibaba.com/dev/tools/api_test_sdk.htm(通过官方测试工具调用)功能验证、参数调试、签名测试
正式环境https://gw.open.1688.com/openapi/param2/2/portals.open.api.item.search生产环境业务调用

3. 核心参数

接口参数分为「公共参数」(所有 1688 接口通用)和「业务参数」(搜索场景特有),两者均为必填项。

(1)公共参数

参数名类型说明
app_key字符串应用唯一标识,从 1688 开放平台「应用管理」中获取
access_token字符串OAuth2.0 授权令牌,需通过system.oauth2.getToken接口获取,有效期 3600 秒
method字符串接口名称,固定为portals.open.api.item.search
format字符串返回格式,固定为json(推荐)或xml
v字符串API 版本,固定为1.0
timestamp字符串毫秒级时间戳(如1699999999999),需与 1688 服务器时间误差≤5 分钟
sign字符串签名,用于接口安全验证,生成规则见「接口调用流程」

(2)业务参数

参数名类型说明是否必填
keywords字符串搜索关键字(如 “纯棉 T 恤”“办公笔记本”),支持多关键词空格分隔
page整数页码,默认 1,最大支持 50 页(1688 限制单次搜索最多返回 50 页数据)
pageSize整数每页条数,默认 20,最大 50(建议按业务需求选择,50 条 / 页可减少调用次数)
categoryId字符串商品分类 ID(如 “服装” 分类 ID 为 10001),可通过portals.open.api.category.get接口获取分类树
priceStart浮点数最低价格(元),如10表示筛选 10 元以上商品
priceEnd浮点数最高价格(元),如50表示筛选 50 元以下商品
minOrderAmount整数最低起订量,如10表示筛选起订量≥10 件的商品
sort字符串排序方式,可选值:- default(默认排序)- price_asc(价格升序)- price_desc(价格降序)- trade_num_desc(30 天销量降序)- credit_desc(供应商诚信通等级降序)
mixEnabled布尔值是否支持混批(多商品合并下单),true表示仅筛选支持混批的商品

二、对接前置准备

在编写代码前,需完成账号注册、应用创建、权限申请等前置操作,确保接口调用权限合法。

1. 注册开发者账号

  1. 访问1688 开放平台,使用企业支付宝或个人支付宝登录;

  2. 完成「开发者认证」:个人开发者需实名认证,企业开发者需上传营业执照(企业认证可获取更多接口权限);

  3. 进入「控制台」,确认账号状态为「已激活」。

2. 创建应用并获取密钥

  1. 在控制台左侧菜单选择「应用管理 → 创建应用」;

  2. 填写应用名称(如 “XX 采购系统”)、应用描述,选择应用类型(“企业自用” 或 “第三方服务”);

  3. 应用创建后,在「应用详情」页获取app_keyapp_secretapp_secret需妥善保管,不可泄露给第三方,建议存储在环境变量或加密配置文件中)。

3. 申请接口权限

  1. 在应用详情页选择「接口权限 → 申请权限」;

  2. 搜索 “商品搜索”,找到「portals.open.api.item.search」接口,点击「申请」;

  3. 填写申请理由(如 “企业采购选品需求,需按关键字筛选商品”),提交后通常 1-3 个工作日内审核通过;

  4. 审核通过后,在「已开通接口」中确认权限状态为「已生效」。

4. 环境与工具准备

  • 开发语言:支持任何可发起 HTTP POST 请求的语言(Python/Java/PHP/Node.js 等,本文以 Python 为例);

  • 测试工具:Postman(用于快速验证接口参数和签名)、1688 官方 API 测试工具(点击访问);

  • 依赖库:Python 需安装requests库(pip install requests)。

三、接口调用流程

1688 item_search接口调用需遵循「获取令牌 → 组装参数 → 生成签名 → 发送请求 → 解析响应」的流程,其中「签名生成」和「令牌管理」是核心环节。

1. 步骤 1:获取 access_token(OAuth2.0 授权)

1688 接口采用 OAuth2.0 认证,所有业务接口(包括item_search)均需携带access_token。获取方式有两种,企业自用场景推荐「客户端模式」(无需用户授权,直接通过app_keyapp_secret获取令牌)。

客户端模式获取令牌的接口参数:

  • 接口地址:https://gw.open.1688.com/openapi/http/1/system.oauth2/getToken

  • 请求方式:POST

  • 业务参数:

    • grant_type:固定为client_credentials

    • client_id:即app_key

    • client_secret:即app_secret

令牌有效期:

  • 生成的access_token有效期为 3600 秒(1 小时),过期后需重新获取;

  • 建议在代码中实现令牌缓存逻辑,避免每次调用item_search都重新请求令牌(减少无效请求)。

2. 步骤 2:组装参数

将「公共参数」和「业务参数」合并为一个参数字典,注意:
  • 参数名区分大小写(如keywords不可写为Keywords);

  • 可选参数若不使用,无需加入字典(避免冗余);

  • timestamp需为毫秒级时间戳(Python 中可通过int(time.time() * 1000)生成)。

3. 步骤 3:生成签名(关键步骤)

1688 签名用于验证请求合法性,签名错误会直接导致接口返回1001错误码,生成规则如下:
  1. 排序:将所有参数(除sign外)按参数名的 ASCII 码升序排序(如app_keyaccess_token之前,keywordspage之前);

  2. 拼接:按 “key1value1key2value2...” 的格式拼接排序后的参数(无分隔符,无=);

  3. 加密:在拼接字符串的末尾追加app_secret,然后进行 MD5 加密(32 位小写),最后转为大写;

  4. 赋值:将加密结果赋值给sign参数,加入参数字典。

  5. 签名生成示例(伪代码):

params = {
    "app_key": "your_app_key",
    "access_token": "your_token",
    "method": "portals.open.api.item.search",
    "format": "json",
    "v": "1.0",
    "timestamp": "1699999999999",
    "keywords": "纯棉T恤",
    "page": 1,
    "pageSize": 20
}
# 1. 排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接
sign_str = ""
for key, value in sorted_params:
    sign_str += f"{key}{value}"
# 3. 追加app_secret并加密
sign_str += "your_app_secret"
sign = hashlib.md5(sign_str.encode()).hexdigest().upper()
# 4. 加入参数字典
params["sign"] = sign

4. 步骤 4:发送请求

  • 请求方式:POST(1688 接口不支持 GET,仅支持 POST);

  • Content-Type:固定为application/x-www-form-urlencoded

  • 超时时间:建议设置为 10-15 秒(避免网络波动导致请求失败)。

5. 步骤 5:解析响应

接口返回 JSON 格式数据,分为「成功响应」和「错误响应」两种类型:
  • 成功响应:包含item_search_response字段,商品列表在item_search_response → items → item中;

  • 错误响应:包含error_response字段,需根据code(错误码)和msg(错误信息)排查问题。

四、代码实现示例(Python)

以下代码包含「令牌自动刷新」「签名生成」「搜索结果解析」「错误处理」等核心逻辑,可直接复用(需替换app_keyapp_secret)。
python
运行
import requestsimport hashlibimport timeimport jsonclass AlibabaSearchApi:
    def __init__(self, app_key, app_secret):
        """初始化API客户端"""
        self.app_key = app_key
        self.app_secret = app_secret        # 接口地址
        self.token_url = "https://gw.open.1688.com/openapi/http/1/system.oauth2/getToken"  # 令牌接口
        self.search_url = "https://gw.open.1688.com/openapi/param2/2/portals.open.api.item.search"  # 搜索接口
        # 令牌缓存(避免频繁请求令牌)
        self.access_token = None
        self.token_expire_at = 0  # 令牌过期时间(时间戳,秒)

    def generate_sign(self, params):
        """生成签名(核心方法)"""
        # 1. 按参数名ASCII升序排序
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        # 2. 拼接参数(key+value)
        sign_str = ""
        for key, value in sorted_params:
            # 注意:参数值需转为字符串,避免类型问题
            sign_str += f"{key}{str(value)}"
        # 3. 追加app_secret并MD5加密
        sign_str += self.app_secret
        sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().upper()
        return sign    def get_access_token(self):
        """获取/刷新access_token(自动判断有效期)"""
        # 检查令牌是否有效(提前60秒刷新,避免过期)
        current_time = time.time()
        if self.access_token and current_time < self.token_expire_at - 60:
            return self.access_token        # 客户端模式参数
        token_params = {
            "grant_type": "client_credentials",
            "client_id": self.app_key,
            "client_secret": self.app_secret        }

        try:
            response = requests.post(
                url=self.token_url,
                data=token_params,
                timeout=10,
                headers={"Content-Type": "application/x-www-form-urlencoded"}
            )
            response.raise_for_status()  # 触发HTTP错误(如404、500)
            result = response.json()

            # 处理令牌请求错误
            if "error" in result:
                raise Exception(f"令牌请求失败:{result['error_description']}")

            # 缓存令牌和过期时间
            self.access_token = result["access_token"]
            self.token_expire_at = current_time + int(result["expires_in"])
            print(f"令牌获取成功,有效期至:{time.ctime(self.token_expire_at)}")
            return self.access_token        except Exception as e:
            raise Exception(f"获取access_token异常:{str(e)}")

    def item_search(self, keywords, page=1, page_size=20, **kwargs):
        """
        按关键字搜索商品(核心业务方法)
        :param keywords: 搜索关键字(必填)
        :param page: 页码(默认1)
        :param page_size: 每页条数(默认20,最大50)
        :param kwargs: 可选参数(如categoryId、priceStart、sort等)
        :return: 搜索结果(字典)
        """
        # 1. 获取有效令牌
        token = self.get_access_token()

        # 2. 组装公共参数
        common_params = {
            "app_key": self.app_key,
            "access_token": token,
            "method": "portals.open.api.item.search",
            "format": "json",
            "v": "1.0",
            "timestamp": str(int(current_time * 1000)),  # 毫秒级时间戳
            "keywords": keywords,
            "page": page,
            "pageSize": page_size        }

        # 3. 合并可选参数(kwargs)
        all_params = {**common_params, **kwargs}
        # 移除值为None的可选参数(避免无效参数)
        all_params = {k: v for k, v in all_params.items() if v is not None}

        # 4. 生成签名
        all_params["sign"] = self.generate_sign(all_params)

        # 5. 发送搜索请求
        try:
            response = requests.post(
                url=self.search_url,
                data=all_params,
                timeout=15,
                headers={"Content-Type": "application/x-www-form-urlencoded"}
            )
            response.raise_for_status()
            result = response.json()

            # 6. 处理响应
            if "error_response" in result:
                error = result["error_response"]
                return {
                    "success": False,
                    "error_code": error.get("code"),
                    "error_msg": error.get("msg"),
                    "request_id": error.get("requestId")  # 用于1688技术支持排查问题
                }

            # 提取商品数据
            search_data = result["item_search_response"]
            total_items = search_data.get("totalCount", 0)  # 总商品数
            item_list = search_data.get("items", {}).get("item", [])  # 商品列表

            return {
                "success": True,
                "total_count": total_items,
                "page": page,
                "page_size": page_size,
                "total_pages": (total_items + page_size - 1) // page_size,  # 总页数
                "items": item_list            }

        except Exception as e:
            return {
                "success": False,
                "error_msg": f"搜索请求异常:{str(e)}"
            }# ------------------------------# 使用示例# ------------------------------if __name__ == "__main__":
    # 替换为自己的app_key和app_secret
    APP_KEY = "your_app_key"
    APP_SECRET = "your_app_secret"

    # 初始化API客户端
    api = AlibabaSearchApi(APP_KEY, APP_SECRET)

    # 搜索“纯棉T恤”,第1页,20条/页,价格10-50元,按销量降序
    search_result = api.item_search(
        keywords="纯棉T恤",
        page=1,
        page


群贤毕至

访客