在电商选品、比价系统及供应链管理中,以图搜货是核心痛点。本文基于1688开放平台官方能力,详细解析
1688.item_search_img接口的调用全流程。不同于网上的碎片化信息,本文提供经过企业级验证的Python代码,解决签名、时间戳、图片上传等核心难点,助你快速构建自动化选品工具。
一、 技术原理与核心能力
1688图片搜索API(俗称“拍立淘”)并非简单的爬虫,而是基于**计算机视觉(CV)**技术。
-
技术栈:深度学习特征提取(CNN)+ 海量商品图库检索。
-
搜索模式:
- 同款搜索 (
search_type=1) :寻找完全相同或高度相似的商品(SKU级匹配)。 - 相似搜索 (
search_ type=0) :寻找风格、形状相似的商品。
- 同款搜索 (
-
应用场景:自动化工单处理、竞品分析、一件代发选品、防侵权监测。
二、 接入门槛与权限申请(关键)
注意:此接口严格限制为企业用户。
-
账号要求:必须拥有企业认证的1688账号(需营业执照)。
-
应用创建:在1688开放平台控制台]创建应用,获取
app_key和app_secret。 -
接口授权:必须单独申请
1688.item_search_img接口权限。- 技巧:在申请理由中填写“用于企业供应链数字化升级,辅助采购选品”,通过率极高。
三、 接口调用详解
请求地址:https://api.1688.com/router/rest (基于网页[1]验证)
请求方法:POST (推荐,支持大图Base64;也可用GET传URL)
协议:HTTPS
核心参数表:
| 参数名 | 必选 | 说明 |
|---|---|---|
| method | 是 | 固定值:1688.item_search_img |
| app_key | 是 | 你的App Key |
| timestamp | 是 | 秒级时间戳,需与服务器时间误差<500ms |
| v | 是 | API版本号,固定为 2.0 |
| sign_method | 是 | 签名方式,如 md5 |
| imgid | 是 | 图片公网URL 或 图片文件的Base64编码 |
| search_type | 是 | 1=同款,0=相似 |
| sort | 否 | 排序字段(_sale销量,_price价格) |
| page_size | 否 | 每页数量,最大50 |
四、 企业级 Python 实战代码
特性:
- 完美签名:严格遵循Open API 2.0签名规则,自动排序。
- 高容错:处理网络超时、图片读取失败、JSON解析错误。
- 灵活上传:支持本地图片自动转Base64,或直接传URL。
import requests
import hashlib
import time
import base64
import os
class OneBoundImageSearch:
"""
1688图片搜索API封装
支持本地图片文件路径或公网URL搜索
"""
def __init__(self, app_key, app_secret):
self.app_key = app_key
self.app_secret = app_secret
self.url = "https://api.1688.com/router/rest" # 官方路由地址
def _generate_sign(self, params):
"""生成签名"""
# 1. 参数名ASCII码升序排序
sorted_params = sorted(params.items())
# 2. 拼接字符串: secret+key1value1key2value2+secret
param_str = ''.join(f'{k}{v}' for k, v in sorted_params)
sign_str = f'{self.app_secret}{param_str}{self.app_secret}'
# 3. MD5加密并转大写
return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
def _prepare_img_data(self, img_path_or_url):
"""
智能识别输入:
1. 如果是本地文件路径,读取并转Base64
2. 如果是http开头,直接返回URL
"""
if img_path_or_url.startswith('http://') or img_path_or_url.startswith('https://'):
return img_path_or_url
elif os.path.exists(img_path_or_url):
with open(img_path_or_url, 'rb') as f:
return base64.b64encode(f.read()).decode('utf-8')
else:
raise ValueError("图片路径或URL无效")
def search(self, img_input, search_type=1, sort='_sale', page_size=20):
"""
执行搜索
:param img_input: 本地图片路径 或 图片URL
"""
# 1. 构建基础参数
params = {
'method': '1688.item_search_img',
'app_key': self.app_key,
'timestamp': str(int(time.time())), # 秒级
'v': '2.0',
'format': 'json',
'sign_method': 'md5',
# --- 业务参数 ---
'imgid': self._prepare_img_data(img_input),
'search_type': str(search_type), # 1同款
'sort': sort,
'page_size': str(page_size)
}
# 2. 生成签名
params['sign'] = self._generate_sign(params)
# 3. 发送请求 (使用POST防止URL过长)
try:
response = requests.post(self.url, data=params, timeout=15)
response.raise_for_status() # 检查HTTP错误
result = response.json()
# 4. 解析结果 (兼容不同版本的返回结构)
# 处理成功情况
if result.get('code') == '200' or result.get('success') is True:
items = result.get('result', {}).get('items', []) or result.get('items', [])
return {
'success': True,
'total': len(items),
'data': items[:10] # 只返回前10个高价值结果
}
else:
return {
'success': False,
'msg': result.get('msg', '未知错误'),
'sub_msg': result.get('sub_msg', '')
}
except requests.exceptions.Timeout:
return {'success': False, 'msg': '请求超时'}
except requests.exceptions.RequestException as e:
return {'success': False, 'msg': f'网络异常: {str(e)}'}
except Exception as e:
return {'success': False, 'msg': f'解析异常: {str(e)}'}
# --- 使用示例 ---
if __name__ == '__main__':
# 1. 配置你的密钥
SEARCHER = OneBoundImageSearch(
app_key='your_app_key',
app_secret='your_app_secret'
)
# 2. 搜索 (支持本地图片路径 或 URL)
# image_path = "C:/path/to/your/shoe.jpg"
image_url = "https://example.com/product.jpg"
res = SEARCHER.search(image_url, search_type=1, sort='_sale')
if res['success']:
print(f"🎉 搜索成功,找到 {res['total']} 个结果:\n")
for i, item in enumerate(res['data'], 1):
print(f"{i}. [{item.get('title', '无标题')}]")
print(f" 💰 价格: {item.get('price')}")
print(f" 📈 销量: {item.get('sales', 0)}")
print(f" 🔗 链接: {item.get('detailUrl')}\n")
else:
print(f" 搜索失败: {res['msg']}")
五、 避坑指南(常见错误码解析)
根据网页[1]及实战经验,以下是高频问题:
-
code: 15/Invalid signature(签名错误)- 原因:参数排序错误,或者拼接时漏了
app_secret。 - 解决:确保
sign生成时,参数是按字母排序的,且拼接格式为secret+key1value1...+secret。
- 原因:参数排序错误,或者拼接时漏了
-
code: 20/Service currently unavailable(服务不可用)- 原因:QPS(每秒查询率)超限,或应用被封禁。
- 解决:检查控制台配额,增加限流逻辑(如
time.sleep(1))。
-
code: 401/Invalid app key(Key无效)- 原因:
app_key错误,或未通过实名/企业认证。
- 原因:
-
图片下载失败/图片格式错误- 原因:传入的图片URL无法被1688服务器访问(内网地址),或图片损坏。
- 解决:尽量使用高质量公网图床链接,或直接上传Base64。
六、 总结
通过上述代码,开发者可以轻松将“以图搜同款”能力集成到ERP、CRM或独立站系统中。相比于传统的爬虫,API方式更稳定、数据更结构化。
核心建议:
- 图片预处理:在上传前,使用OpenCV裁剪背景,能显著提高同款匹配率。
- 缓存机制:对搜索过的图片MD5做缓存,避免重复调用产生费用。
- 合规性:严禁将获取的数据用于非授权的商业爬虫,遵守《1688平台API使用协议》。