1688 的 item_search_img 接口(又称 "1688 拍立淘")是阿里巴巴开放平台提供的图像搜索接口,支持通过图片(URL 或本地图片)搜索 1688 平台上的同款或相似商品。该接口基于阿里巴巴的图像识别技术,能够快速匹配商品库中视觉特征相似的商品,广泛应用于供应商查找、同款比价、供应链管理等场景。
一、接口核心特性分析
- 接口功能与定位
核心功能:通过图片特征匹配 1688 平台商品,返回相似商品列表及详细信息
技术原理:基于深度学习的图像特征提取与比对,支持商品主体识别、特征匹配
应用场景:
供应商查找:通过样品图片找到生产厂家
同款比价:找到同款商品的不同供应商价格
电商选品:根据市场热销商品图片寻找货源
供应链管理:快速匹配产品与供应商 - 认证机制
1688 开放平台采用 appkey + 签名 认证方式,具体流程:
开发者在 1688 开放平台注册应用,获取 appkey 和 appsecret
每次请求时,将所有参数按 ASCII 码升序排序
拼接参数并结合 appsecret 生成 MD5 签名
服务器验证签名有效性,防止参数篡改 核心参数与响应结构
请求参数
参数名 类型 是否必填 说明
method String 是 接口方法名,固定为 alibaba.item.search.img
app_key String 是 应用的 appkey
timestamp String 是 时间戳,格式 yyyy-MM-dd HH:mm:ss
format String 否 响应格式,默认 json
v String 是 接口版本,固定为 2.0
sign String 是 签名
image_url String 二选一 图片 URL(公网可访问)
image String 二选一 本地图片 Base64 编码(不含前缀)
page Number 否 页码,默认 1
page_size Number 否 每页数量,默认 40,最大 100
sort String 否 排序方式:price_asc、price_desc、sales
响应核心字段
分页信息:总商品数、总页数、当前页
商品列表:每个商品包含
基础信息:商品 ID、标题、主图、详情页链接
价格信息:价格区间、起订量、批发价
供应商信息:供应商 ID、名称、所在地、信用等级
交易信息:30 天成交量、买家数、重复采购率
二、Python 脚本实现
以下是调用 1688 item_search_img 接口的完整实现,支持图片 URL 和本地图片两种搜索方式:
import requests
import hashlib
import time
import json
import base64
import logging
from typing import Dict, Optional, List
from requests.exceptions import RequestException
from pathlib import Path配置日志
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
class AlibabaImageSearchAPI:
def init(self, appkey: str, appsecret: str):
"""
初始化1688图片搜索接口客户端
:param appkey: 1688开放平台appkey
:param appsecret: 1688开放平台appsecret
"""
self.appkey = appkey
self.appsecret = appsecret
self.base_url = "https://gw.open.1688.com/openapi/http/1/system.oauth2"
self.session = requests.Session()
def _generate_sign(self, params: Dict) -> str:
"""生成1688 API签名"""
# 1. 按参数名ASCII升序排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接为key=value&key=value格式
sign_str = "&".join([f"{k}={v}" for k, v in sorted_params])
# 3. 拼接appsecret并MD5加密
sign_str += self.appsecret
return hashlib.md5(sign_str.encode()).hexdigest().upper()
def _get_timestamp(self) -> str:
"""生成时间戳(yyyy-MM-dd HH:mm:ss)"""
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
def _local_image_to_base64(self, image_path: str) -> Optional[str]:
"""将本地图片转换为Base64编码"""
image_file = Path(image_path)
# 检查文件是否存在
if not image_file.exists() or not image_file.is_file():
logging.error(f"图片文件不存在: {image_path}")
return None
# 检查文件格式
valid_extensions = ['.jpg', '.jpeg', '.png', '.gif']
if image_file.suffix.lower() not in valid_extensions:
logging.error(f"不支持的图片格式: {image_file.suffix},支持格式: {valid_extensions}")
return None
try:
# 读取并编码图片
with open(image_path, 'rb') as f:
image_data = f.read()
base64_str = base64.b64encode(image_data).decode('utf-8')
return base64_str
except Exception as e:
logging.error(f"图片编码失败: {str(e)}")
return None
def search_by_image(self,
image_url: Optional[str] = None,
image_path: Optional[str] = None,
page: int = 1,
page_size: int = 40,
sort: Optional[str] = None) -> Optional[Dict]:
"""
按图片搜索1688商品
:param image_url: 图片URL(二选一)
:param image_path: 本地图片路径(二选一)
:param page: 页码
:param page_size: 每页数量
:param sort: 排序方式
:return: 搜索结果
"""
# 验证图片参数
if not image_url and not image_path:
logging.error("必须提供image_url或image_path参数")
return None
# 构建基础参数
params = {
"method": "alibaba.item.search.img",
"app_key": self.appkey,
"timestamp": self._get_timestamp(),
"format": "json",
"v": "2.0",
"page": str(page),
"page_size": str(page_size)
}
# 添加排序参数
if sort:
params["sort"] = sort
# 添加图片参数
if image_url:
params["image_url"] = image_url
else:
# 处理本地图片
base64_image = self._local_image_to_base64(image_path)
if not base64_image:
return None
params["image"] = base64_image
# 生成签名
params["sign"] = self._generate_sign(params)
try:
# 发送请求
response = self.session.get(
self.base_url,
params=params,
timeout=20 # 图片搜索耗时较长,设置较长超时
)
response.raise_for_status()
result = response.json()
# 处理错误响应
if "error_response" in result:
error = result["error_response"]
logging.error(f"接口错误: {error.get('msg', '未知错误')} (错误码: {error.get('code', '未知')})")
return None
# 格式化响应数据
return self._format_response(result)
except RequestException as e:
logging.error(f"请求异常: {str(e)}")
return None
except json.JSONDecodeError:
logging.error(f"响应解析失败: {response.text[:200]}...")
return None
def _format_response(self, response: Dict) -> Dict:
"""格式化响应数据"""
result = response.get("alibaba_item_search_img_response", {})
data = result.get("result", {})
# 提取分页信息
pagination = {
"total_items": int(data.get("total_results", 0)),
"total_pages": (int(data.get("total_results", 0)) + int(data.get("page_size", 40)) - 1) // int(data.get("page_size", 40)),
"current_page": int(data.get("page", 1)),
"page_size": int(data.get("page_size", 40))
}
# 格式化商品列表
products = []
for item in data.get("items", {}).get("item", []):
product = {
"product_id": item.get("product_id"),
"title": item.get("title"),
"main_image": item.get("main_image"),
"detail_url": item.get("detail_url"),
"price": {
"min_price": float(item.get("min_price", 0)),
"max_price": float(item.get("max_price", 0)),
"unit": item.get("unit", "")
},
"wholesale_price": item.get("wholesale_price", []), # 批发价格区间
"moq": int(item.get("moq", 0)), # 最小起订量
"transaction": {
"sales_count": int(item.get("sales_count", 0)), # 30天销量
"buyer_count": int(item.get("buyer_count", 0)), # 买家数
"repeat_rate": float(item.get("repeat_rate", 0)) # 重复采购率
},
"supplier": {
"supplier_id": item.get("supplier_id"),
"supplier_name": item.get("supplier_name"),
"location": item.get("location"),
"credit_level": item.get("credit_level"),
"year": int(item.get("year", 0)) # 经营年限
},
"similarity": float(item.get("similarity", 0)) # 相似度(0-100)
}
products.append(product)
return {
"pagination": pagination,
"products": products,
"search_id": data.get("search_id") # 搜索ID,可用于后续操作
}
def search_all_pages(self, image_url: Optional[str] = None,
image_path: Optional[str] = None,
max_pages: int = 5) -> List[Dict]:
"""
获取多页搜索结果
:param image_url: 图片URL
:param image_path: 本地图片路径
:param max_pages: 最大页数限制
:return: 所有商品列表
"""
all_products = []
page = 1
while page <= max_pages:
logging.info(f"获取第 {page} 页搜索结果")
result = self.search_by_image(
image_url=image_url,
image_path=image_path,
page=page,
page_size=100 # 使用最大页大小减少请求次数
)
if not result or not result["products"]:
break
all_products.extend(result["products"])
# 检查是否已到最后一页
if page >= result["pagination"]["total_pages"]:
break
page += 1
# 添加延迟,避免触发频率限制
time.sleep(1.5)
return all_products
示例调用
if name == "main":
# 替换为实际的appkey和appsecret(从1688开放平台获取)
APPKEY = "your_appkey"
APPSECRET = "your_appsecret"
# 初始化API客户端
api = AlibabaImageSearchAPI(APPKEY, APPSECRET)
# 方式1:通过图片URL搜索
# search_result = api.search_by_image(
# image_url="https://img.alicdn.com/imgextra/i3/xxx.jpg", # 替换为实际图片URL
# page=1,
# page_size=20,
# sort="sales"
# )
# 方式2:通过本地图片搜索
search_result = api.search_by_image(
image_path="./product_sample.jpg", # 替换为本地图片路径
page=1,
page_size=20,
sort="sales"
)
# 方式3:获取多页结果
# search_result = api.search_all_pages(
# image_path="./product_sample.jpg",
# max_pages=3
# )
if search_result:
# 处理单页结果
if isinstance(search_result, dict) and "products" in search_result:
print(f"共找到 {search_result['pagination']['total_items']} 件相似商品")
print(f"当前第 {search_result['pagination']['current_page']}/{search_result['pagination']['total_pages']} 页\n")
# 打印前5件商品信息
for i, product in enumerate(search_result["products"][:5], 1):
print(f"{i}. {product['title']} (相似度: {product['similarity']}%)")
print(f" 价格: {product['price']['min_price']}-{product['price']['max_price']}{product['price']['unit']}")
print(f" 起订量: {product['moq']}{product['price']['unit']}")
print(f" 30天销量: {product['transaction']['sales_count']} 件")
print(f" 供应商: {product['supplier']['supplier_name']} ({product['supplier']['location']})")
print(f" 链接: {product['detail_url']}")
print("-" * 100)
else:
# 处理多页结果
print(f"共获取到 {len(search_result)} 件商品")
三、接口调用关键技术与注意事项
- 图片处理最佳实践
图片质量:清晰的商品主体图片(无水印、无遮挡)识别效果最佳
图片尺寸:建议图片尺寸在 500x500 到 1000x1000 像素之间
图片格式:优先使用 JPG 格式,识别成功率高于 PNG 和 GIF
Base64 处理:
必须移除 Base64 编码前缀(如data:image/jpeg;base64,)
图片大小控制在 5MB 以内,过大可能导致请求失败
URL 图片:确保图片 URL 为公网可访问,阿里系 CDN 图片识别速度更快 - 常见错误及解决方案
错误码 说明 解决方案
10001 签名错误 检查参数排序是否正确,appsecret 是否匹配
20002 图片格式错误 检查图片格式是否为支持的类型,Base64 编码是否正确
20003 图片无法访问 验证图片 URL 有效性,确保公网可访问
20004 图片识别失败 更换清晰的商品图片,确保主体明确
429 调用频率超限 降低调用频率,实现请求限流机制
403 权限不足 检查应用是否已申请图片搜索接口权限 - 性能优化建议
请求频率控制:默认 QPS 限制为 5,建议控制在 3-4 次 / 秒
图片预处理:对本地图片进行压缩和裁剪,突出商品主体
结果缓存:相同图片的搜索结果可缓存 30-60 分钟
批量处理:对多张图片搜索,使用队列和异步处理提高效率
分页策略:优先获取前 3 页结果(通常包含最相似的商品)
四、应用场景与扩展
典型应用场景
供应商匹配系统:通过样品图片快速找到生产厂家
同款比价工具:对比相同商品在不同供应商的价格和起订量
电商选品助手:根据市场热销商品图片寻找 1688 货源
反向寻源平台:帮助采购商快速找到特定产品的供应商
扩展建议
结合商品详情接口获取更完整的产品信息
实现相似度过滤,只保留高相似度的商品
开发图片批量搜索功能,支持多图同时查询
添加价格趋势分析,监控供应商价格变化
结合地图服务,按地区筛选供应商
通过合理使用 1688 图片搜索接口,开发者可以构建高效的供应链寻源工具,帮助企业快速找到合适的供应商,降低采购成本,提高供应链效率。使用时需遵守 1688 开放平台的使用规范,确保数据使用的合法性。