1688的拍立淘图片搜索(官方多称为图片找货/以图搜货接口,如 alibaba.offer.searchByImage或 ISV 图片搜索能力)允许上传商品图片返回相似1688供应商品。它和普通关键词搜索不同——必须先申请白名单权限,默认应用无法直接调用。
下面给你完整的申请流程 + 签名注意事项 + Python 图片上传调用 Demo。
一、 接口申请流程(关键!)
Step 1:创建「自用型应用」
- 登录 1688开放平台控制台
- 应用类型必须选「自用型应用」(ISV/第三方应用图片搜索需额外资质)
- 记录
AppKey/AppSecret
Step 2:申请图片搜索权限
- 进入 应用详情 → 接口权限 → 申请新接口
- 搜索关键词:
图片搜索/searchByImage/以图搜货 - 勾选并提交使用说明(写明:"ERP系统上传商品图片搜索1688相似货源,辅助采购选品")
- ⚠️ 此接口通常需人工审核,1~3个工作日邮件通知结果
Step 3:确认沙箱测试
- 审核通过后,在「沙箱环境」先用测试图片验证
- 生产调用与沙箱共用同一个 AppKey
💡 避坑:未申请或审核未通过直接调会返回error_code: 403 / no permission
二、 图片搜索接口核心参数
参数 | 说明 | 注意 |
|---|---|---|
imageData | 图片二进制 Base64编码 | 建议压缩至 ≤ 500KB,格式 JPG/PNG |
pageNo | 页码,从1开始 | — |
pageSize | 每页条数,最大50 | 推荐20 |
categoryId | 可选,限制类目提高准确度 | 先调类目接口获取 |
sortType | booked(销量) / price_asc | — |
⚠️ 1688图片搜索走 multipart/form-data 或 Base64 参数,不同于普通 param2 GET,签名时需把 imageData(base64串) 参与签名但要控制长度,部分版本要求
imageData不参与签名仅参与传输——以你拿到的最新文档为准,下面代码按参与签名写法(最通用)。三、 Python调用Demo(图片→Base64→签名→搜索)
# ali1688_image_search.py
import hashlib
import time
import requests
import base64
import os
from typing import Dict, List
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
class Ali1688ImageSearchClient:
"""
1688 拍立淘/图片搜索(以图搜货) API Client
网关示例: https://gw.open.1688.com/openapi/param2/2/alibaba.offer.searchByImage/2.0
(具体 method 名以开放平台批准文档为准)
"""
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
self.gateway = "https://gw.open.1688.com/openapi/param2/2/alibaba.offer.searchByImage/2.0"
# ────────────────────────────────────────
# 1688 标准 MD5 签名(参与签名的参数值过长时截断说明见下方)
# ────────────────────────────────────────
def _sign(self, params: Dict) -> str:
# 注意:部分1688图片接口要求 imageData(Base64) 参与签名
# 但签名时可用原串(不要截断),只要和请求发送的一致即可
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 search_by_image(self,
image_path: str,
page_no: int = 1,
page_size: int = 20,
category_id: int = None) -> Dict:
"""
上传本地图片搜索相似1688商品
Args:
image_path: 本地图片路径 (jpg/png, 建议 ≤ 500KB)
page_no: 页码
page_size: 每页条数 ≤ 50
category_id: 可选类目ID限定
Returns:
{offers: [...], totalResult: int}
"""
if not os.path.exists(image_path):
raise FileNotFoundError(f"图片文件不存在: {image_path}")
# 1. 读取并 Base64 编码
with open(image_path, 'rb') as f:
img_bytes = f.read()
# 可选:简单压缩提示
if len(img_bytes) > 1024 * 1024:
print("⚠️ 图片 > 1MB,建议压缩以避免超时或签名异常")
img_b64 = base64.b64encode(img_bytes).decode('utf-8')
# 2. 组装业务参数
biz = {
"pageNo": page_no,
"pageSize": min(page_size, 50),
"imageData": img_b64, # Base64 字符串
"sortType": "booked"
}
if category_id:
biz["categoryId"] = category_id
# 3. 组装 API 参数
api_params = {
"method": "alibaba.offer.searchByImage",
"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
# 图片搜索接口一般用 POST(form 或 param 内嵌)
# 这里按 param2 传 JSON 字符串(1688 部分版本要求)
import json, urllib.parse
api_params["param2"] = urllib.parse.quote_plus(
json.dumps(biz, ensure_ascii=False)
)
api_params["sign"] = self._sign(api_params)
# 4. 发送请求(推荐 POST)
resp = requests.post(self.gateway, data=api_params, timeout=30)
resp.raise_for_status()
data = resp.json()
if "error_response" in data:
err = data["error_response"]
raise Exception(
f"1688 ImageSearch Err [{err.get('code')}]: {err.get('msg')}"
)
return data.get("alibaba_offer_searchbyimage_response", {})
# ────────────────────────────────────────
# 便捷:提取商品摘要
# ────────────────────────────────────────
def extract_offers(self, search_result: Dict) -> List[Dict]:
return search_result.get("offers", []) or []
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# ===================================================
# 使用示例
# ===================================================
if __name__ == "__main__":
client = Ali1688ImageSearchClient(
app_key="YOUR_APP_KEY",
app_secret="YOUR_APP_SECRET",
access_token=None # 图片搜索公开商品可不传;私有结果传session key
)
try:
result = client.search_by_image(
image_path="./test_cup.jpg", # ← 放一张商品实拍图
page_no=1,
page_size=10
)
offers = client.extract_offers(result)
total = result.get("totalResult", 0)
print(f"✅ 图片搜到 {total} 个相似商品,本页 {len(offers)} 条")
for o in offers[:3]:
print(f" • {o.get('subject')} ¥{o.get('priceRange')} offerId:{o.get('offerId')}")
except Exception as e:
print(f"❌ 图片搜索失败: {e}")
print(" → 请确认:1)接口权限已审批 2)图片≤1MB 3)AppKey正确")四、 关键避坑清单
坑 | 现象 | 解决 |
|---|---|---|
未申请权限直接调 | 403 no permission/ invalid method | 控制台提交申请并等审核邮件 |
图片过大 | 超时 / IllegalParam imageData | 压缩至 ≤ 500KB,JPG 优先 |
Base64 带换行/前缀 | 签名不匹配或解析失败 | 用 base64.b64encode(...).decode()不带 data:image/...前缀 |
QPS 更低 | 图片搜索默认 QPS 往往 ≤ 5/s | TokenBucket 限速设 qps=3~4,失败后指数退避 |
沙箱/生产混用 | 沙箱返回空 | 审核通过后切生产网关,沙箱仅做连通性验证 |
五、 完整选品链路(面试叙述)
业务员手机拍照/上传商品图 │ Base64编码 ▼ 图片搜索API → offerId列表(相似货源) │ ▼ 商品详情API(alibaba.item.get) → SKU/MOQ/批发价 │ ▼ 匹配ERP内部SKU or 新建草稿商品 → 采购员人工确认 → 创建1688订单
如需要我可以补充 图片压缩预处理函数(Pillow自动缩到500KB) 或 与商品详情API联动的完整选品脚本。