返回教程列表
教程2026年11月8日5 分钟阅读

1688 API 接入教程:用 Python 搜索商品并获取详情

使用 Just One API 完成1688关键词商品搜索、商品详情查询与JSON保存,了解价格筛选、分页、英文输出和错误处理。

从一个选品关键词开始

1688商品数据接入可以分成两步:先按关键词找到候选商品,再查询某个具体商品的详情。本教程使用 Just One API 搜索“保温杯”,由你选择一个商品,再获取英文详情并保存为 JSON,作为后续货源对比或商品目录整理的起点。

Just One API 是第三方数据 API 服务。这里演示读取平台数据,不涉及下单或访问商家的私有账户。搜索“1688采集API”或“1688 scraper API”时,建议先确认返回字段能否满足自己的业务需求,再扩大调用范围。

“保温杯”仅是接入示例。搜索结果是一份可获得的商品样本,不能当作全市场库存清单,也不能直接证明供应商的质量。

按手上的输入选择接口

只有关键词时,使用商品搜索 V2。已有商品 ID 时,使用商品详情 V2。如果手上是商品链接,可以改用商品详情(URL)V1,不要把整条链接填到 itemId 中。

示例脚本使用两个 GET 接口:

  • /api/1688/search-item-list/v2:必填 token 和 keyword。
  • /api/1688/get-item-detail/v2:必填 token 和 itemId。

先注册 Just One API 账户、获取 Token,并在账户中确认接口权限和当前价格。可用试用额度也以账户显示为准,本教程不假设固定免费次数。

先取一页,确认搜索结果是否有用

商品搜索 V2 的 page 从 1 开始。pageSize 是期望获取的数量,实际返回数量可能不同。示例只请求第一页的10条结果,并用 sort=price_up 按价格升序排列;其他已文档化的排序值包括 default、sales 和 price_down。

如需价格区间,可在参数中增加字符串 priceStart 和 priceEnd,例如 "20" 和 "80",单位为人民币。继续翻页时保持关键词、筛选和排序一致。本例只读取第1页,不自动遍历后续页面。

文档还提供 moq、supportDropshipping 等选品条件。使用前应核对实际结果是否符合要求;筛选条件本身不等于对供应商或可用物流服务的独立认证。

选择商品 ID,再读取英文详情

查看保存的搜索数据,选择一个有效的商品 ID,再提交详情查询。编写自动提取逻辑前,先在文档中核对实际响应示例,不同接口或版本的字段层级可能不同。因此示例显式接收 --item-id,不猜测固定的 ID 字段路径。

商品详情 V2 支持 language=en 返回英文内容,默认值为 zh。这属于详情接口的参数,不能直接套用到商品搜索 V2。详情接口还支持可选的 scene=drop_shipping 代发价格场景;本例不填写。需要比较代发报价时,应使用相同场景核对结果。

当返回结果包含商品价、SKU价或数量阶梯价时,应分别保留。记录采集时间,以及适用规格、数量和报价场景。字段缺失应标记为未知,不应写成零库存或零销量;页面报价也不是已经确认的到手采购成本。

Python 示例:每条命令只请求一次

在 macOS 或 Linux 终端安装 requests 并设置 Token。your_token 是占位符,不要把真实 Token 提交到仓库或放进共享截图、请求日志。

bash
python3 -m pip install requests
export JUSTONEAPI_TOKEN='your_token'

将以下代码保存为 1688_sample.py。每次运行只发出1次请求,不自动重试、跟随重定向或翻页。脚本同时检查 HTTP 状态与业务 code=0,仅保存 data、采集时间和接口路径,不保存完整响应信封或其中可能回显的请求参数。

python
import argparse
import json
import os
from datetime import datetime, timezone
from pathlib import Path

import requests


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("mode", choices=("search", "detail"))
    parser.add_argument("--keyword")
    parser.add_argument("--item-id")
    parser.add_argument("--output", required=True)
    args = parser.parse_args()
    if args.mode == "search" and not (args.keyword or "").strip():
        parser.error("search requires --keyword")
    if args.mode == "detail" and not (args.item_id or "").strip():
        parser.error("detail requires --item-id")
    output = Path(args.output)
    if output.exists() or not output.parent.is_dir():
        raise SystemExit("Use a new output filename in an existing folder.")
    token = os.environ.get("JUSTONEAPI_TOKEN", "").strip()
    if not token or token == "your_token":
        raise SystemExit("Set JUSTONEAPI_TOKEN to your own API token.")
    if args.mode == "search":
        path = "/api/1688/search-item-list/v2"
        params = {"keyword": args.keyword, "page": 1,
                  "pageSize": 10, "sort": "price_up"}
    else:
        path = "/api/1688/get-item-detail/v2"
        params = {"itemId": args.item_id, "language": "en"}
    try:
        response = requests.get("https://api.justoneapi.com" + path,
                                params={**params, "token": token},
                                timeout=120, allow_redirects=False)
    except requests.RequestException:
        raise SystemExit("No confirmed result. No automatic retry was made; "
                         "check request records before repeating.") from None
    try:
        payload = response.json()
    except ValueError:
        raise SystemExit("Expected a JSON response; no result file was saved.") from None
    if response.status_code != 200:
        raise SystemExit(f"HTTP {response.status_code}; no result file was saved.")
    if not isinstance(payload, dict):
        raise SystemExit("Unexpected response structure; inspect the documentation.")
    code = payload.get("code")
    if type(code) is not int or code != 0:
        label = str(code) if type(code) is int else "missing/invalid"
        raise SystemExit(f"Business code {label}; no result file was saved.")
    if "data" not in payload:
        raise SystemExit("Success envelope has no data field; inspect the documentation.")
    result = {"collected_at_utc": datetime.now(timezone.utc).isoformat(),
              "endpoint": path, "data": payload["data"]}
    with output.open("x", encoding="utf-8") as file:
        json.dump(result, file, ensure_ascii=False, indent=2)
    print(f"Saved {output.name}")


if __name__ == "__main__":
    main()

先请求一页商品搜索结果:

bash
python3 1688_sample.py search --keyword '保温杯' --output search.json

检查 search.json,选取真实商品 ID 替换下方的 YOUR_ITEM_ID。每次使用新的文件名,避免后续请求静默覆盖已有样本。

bash
python3 1688_sample.py detail --item-id YOUR_ITEM_ID --output detail.json

以上两条命令各执行一次,共产生2次 API 请求。脚本不会自动选品、联系供应商或下单。保存的 data 保留接口实际结构;如需导出 CSV,应在核对自己拿到的字段后再设置列映射。

先处理错误,再扩大调用量

HTTP 请求成功不代表业务取数成功。使用指南说明了常见业务码:100 为 Token 无效或未启用,301 为采集失败,302 为频率限制,303 为日配额限制,600 为无权限,601 为余额不足,602 为当前 Token 预算已达上限。

根据错误检查账户或请求参数后,再决定是否重发。超时并不能证明服务端没有处理请求,本示例会停止而不重试;再次提交可能计费的请求前,先查看请求记录。由于鉴权参数放在查询串中,不要打印完整请求 URL。

常见问题

缺失字段能否直接填零?

不能。保留未知值,并在相同规格、数量、币种和报价场景下比较不同采集时间的结果。本教程不保证每个商品都提供库存或销量字段。

是否直接选择版本号最高的接口?

先查看1688接口目录,按照输入参数和所需返回字段选择版本。用自己的样本验证后,再考虑替换已有接入。

这个流程能否直接采购或验证供应商?

这里读取商品数据,不创建订单、不认证供应商,也不保证商品始终可售。采购和供应商评估还需要示例之外的核实。

下一步:用自己的关键词核对一条商品

从商品搜索 V2 文档开始,再用选定商品核对商品详情 V2。确认字段覆盖和账户权限后再扩大流程。如果现有文档没有覆盖所需数据,可以说明你的采集需求,由 Just One API 评估定制化采集的可行性。

继续使用 Just One API

登录 Dashboard 获取 Token,查看完整 API 文档,或打开 MCP GitHub 项目了解最新配置。