Java 获取 1688 图搜接口开发文档

1688 按图搜索(拍立淘)是 B2B 电商领域极具价值的能力,支持通过上传商品图片检索相似货源。本文将系统性地介绍 Java 环境下接入 1688 图搜接口的完整方案,涵盖官方开放平台 API、跨境/分销场景接口以及第三方聚合服务。
一、接口体系概览
1688 图搜接口根据业务场景分为多条路径,开发者需根据实际需求选择:
表格
接入路径 接口地址 认证方式 适用场景 图片输入方式
官方商品图搜 alibaba.product.image.search OAuth2 access_token 通用商品搜索、比价工具 本地图片上传(multipart)
跨境图搜 跨境采购解决方案内接口 方案订购 + access_token 跨境买家、ERP 服务商 图片 URL
分销图搜 社交电商采购解决方案内接口 方案订购 + access_token 社交分销、内容电商 图片 URL
第三方聚合 API 各服务商自定义地址 apiToken 快速集成、多语言支持 图片 URL / Base64
二、路径一:官方开放平台商品图搜接口
2.1 接入准备
访问 1688 开放平台 注册企业开发者账号
完成实名认证,创建应用获取 App Key 和 App Secret
在应用权限管理中申请 alibaba.product.image.search 接口权限
通过 OAuth2.0 授权流程获取 access_token(有效期 2 小时,需缓存刷新)
2.2 图片要求
表格
要求项 规范 说明
格式 JPG / JPEG / PNG 不支持 GIF、WebP
大小 建议 < 1MB 过大易导致请求超时
分辨率 最小边 ≥ 256 像素 过小影响识别精度
内容 清晰商品主体图 避免模糊、多主体、纯文字图
2.3 核心请求参数
表格
参数名 类型 必选 说明
access_token String 是 OAuth2 授权令牌
image File 是 商品图片文件(multipart 上传)
page Integer 否 页码,默认 1
pageSize Integer 否 每页条数,默认 20,最大 50
similarDegree Float 否 相似度阈值(0~1),默认无限制
2.4 完整 Java 实现代码
java
import okhttp3.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**

  • 1688 官方开放平台 - 按图搜索商品 API Java 客户端

  • 接口:alibaba.product.image.search
    */
    public class Official1688ImageSearchClient {

    // 1688 开放平台网关地址
    private static final String GATEWAY_URL =
    "https://gw.open.1688.com/openapi/param2/1/com.alibaba.product/alibaba.product.image.search";

    private final String accessToken;
    private final OkHttpClient httpClient;

    public Official1688ImageSearchClient(String accessToken) {
    this.accessToken = accessToken;
    this.httpClient = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(30, TimeUnit.SECONDS)
    .build();
    }

    /**

    • 通过本地图片文件搜索相似商品

    • @param imageFile 本地图片文件

    • @param page 页码

    • @param pageSize 每页数量

    • @param similarDegree 相似度阈值(0.0~1.0)

    • @return 搜索结果
      */
      public ImageSearchResult searchByImage(File imageFile, int page, int pageSize, Double similarDegree)
      throws IOException {

      // 构建 multipart 请求体
      MultipartBody.Builder multipartBuilder = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart("access_token", accessToken)
      .addFormDataPart("page", String.valueOf(page))
      .addFormDataPart("pageSize", String.valueOf(pageSize));

      // 添加图片文件
      String mimeType = getMimeType(imageFile.getName());
      multipartBuilder.addFormDataPart(
      "image",
      imageFile.getName(),
      RequestBody.create(MediaType.parse(mimeType), imageFile)
      );

      // 可选:相似度阈值
      if (similarDegree != null) {
      multipartBuilder.addFormDataPart("similarDegree", String.valueOf(similarDegree));
      }

      Request request = new Request.Builder()
      .url(GATEWAY_URL)
      .post(multipartBuilder.build())
      .build();

      try (Response response = httpClient.newCall(request).execute()) {
      if (!response.isSuccessful()) {
      throw new IOException("HTTP 请求失败,状态码: " + response.code());
      }

      String responseBody = response.body().string();
      return parseResponse(responseBody);
      }
      }

    /**

    • 通过图片 URL 搜索(部分场景支持,需先上传图片到 1688 图床获取 URL)
      */
      public ImageSearchResult searchByImageUrl(String imageUrl, int page, int pageSize)
      throws IOException {

      // 注意:官方接口主要支持文件上传,URL 方式需先将图片上传至 1688 图床
      // 此处演示通过 multipart 的变通方式
      FormBody formBody = new FormBody.Builder()
      .add("access_token", accessToken)
      .add("page", String.valueOf(page))
      .add("pageSize", String.valueOf(pageSize))
      .add("imageUrl", imageUrl) // 部分版本支持
      .build();

      Request request = new Request.Builder()
      .url(GATEWAY_URL)
      .post(formBody)
      .build();

      try (Response response = httpClient.newCall(request).execute()) {
      String responseBody = response.body().string();
      return parseResponse(responseBody);
      }
      }

    /**

    • 解析 JSON 响应
      */
      private ImageSearchResult parseResponse(String jsonResponse) {
      JSONObject root = JSON.parseObject(jsonResponse);

      // 检查顶层错误
      if (root.containsKey("error")) {
      JSONObject error = root.getJSONObject("error");
      return ImageSearchResult.error(
      error.getString("code"),
      error.getString("message")
      );
      }

      // 解析 result 结构
      JSONObject result = root.getJSONObject("result");
      if (result == null) {
      return ImageSearchResult.error("NO_RESULT", "响应中无 result 字段");
      }

      boolean success = result.getBooleanValue("success", true);
      if (!success) {
      return ImageSearchResult.error(
      result.getString("errorCode"),
      result.getString("errorMessage")
      );
      }

      // 解析商品列表
      JSONArray productList = result.getJSONArray("productList");
      List products = new ArrayList<>();

      if (productList != null) {
      for (int i = 0; i < productList.size(); i++) {
      JSONObject item = productList.getJSONObject(i);
      SearchProduct product = new SearchProduct();
      product.setProductId(item.getString("productId"));
      product.setTitle(item.getString("title"));
      product.setImageUrl(item.getString("imageUrl"));
      product.setSimilarity(item.getDoubleValue("similarity"));
      product.setPrice(item.getString("price"));
      product.setMinOrderQuantity(item.getString("minOrderQuantity"));
      product.setSellerId(item.getString("sellerId"));
      product.setSellerName(item.getString("sellerName"));
      product.setDetailPageUrl(item.getString("detailPageUrl"));
      products.add(product);
      }
      }

      ImageSearchResult searchResult = new ImageSearchResult();
      searchResult.setSuccess(true);
      searchResult.setTotalResults(result.getIntValue("totalResults"));
      searchResult.setPage(result.getIntValue("page"));
      searchResult.setPageSize(result.getIntValue("pageSize"));
      searchResult.setProducts(products);

      return searchResult;
      }

    /**

    • 根据文件名推断 MIME 类型
      */
      private String getMimeType(String fileName) {
      String ext = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
      return switch (ext) {
      case "jpg", "jpeg" -> "image/jpeg";
      case "png" -> "image/png";
      case "gif" -> "image/gif";
      default -> "application/octet-stream";
      };
      }

    // ==================== 数据模型 ====================

    public static class ImageSearchResult {
    private boolean success;
    private String errorCode;
    private String errorMessage;
    private int totalResults;
    private int page;
    private int pageSize;
    private List products;

    public static ImageSearchResult error(String code, String message) {
    ImageSearchResult r = new ImageSearchResult();
    r.success = false;
    r.errorCode = code;
    r.errorMessage = message;
    return r;
    }

    // Getters & Setters
    public boolean isSuccess() { return success; }
    public void setSuccess(boolean success) { this.success = success; }
    public String getErrorCode() { return errorCode; }
    public void setErrorCode(String errorCode) { this.errorCode = errorCode; }
    public String getErrorMessage() { return errorMessage; }
    public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
    public int getTotalResults() { return totalResults; }
    public void setTotalResults(int totalResults) { this.totalResults = totalResults; }
    public int getPage() { return page; }
    public void setPage(int page) { this.page = page; }
    public int getPageSize() { return pageSize; }
    public void setPageSize(int pageSize) { this.pageSize = pageSize; }
    public List getProducts() { return products; }
    public void setProducts(List products) { this.products = products; }
    }

    public static class SearchProduct {
    private String productId;
    private String title;
    private String imageUrl;
    private double similarity;
    private String price;
    private String minOrderQuantity;
    private String sellerId;
    private String sellerName;
    private String detailPageUrl;

    // Getters & Setters
    public String getProductId() { return productId; }
    public void setProductId(String productId) { this.productId = productId; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getImageUrl() { return imageUrl; }
    public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
    public double getSimilarity() { return similarity; }
    public void setSimilarity(double similarity) { this.similarity = similarity; }
    public String getPrice() { return price; }
    public void setPrice(String price) { this.price = price; }
    public String getMinOrderQuantity() { return minOrderQuantity; }
    public void setMinOrderQuantity(String minOrderQuantity) { this.minOrderQuantity = minOrderQuantity; }
    public String getSellerId() { return sellerId; }
    public void setSellerId(String sellerId) { this.sellerId = sellerId; }
    public String getSellerName() { return sellerName; }
    public void setSellerName(String sellerName) { this.sellerName = sellerName; }
    public String getDetailPageUrl() { return detailPageUrl; }
    public void setDetailPageUrl(String detailPageUrl) { this.detailPageUrl = detailPageUrl; }
    }

    // ==================== 使用示例 ====================

    public static void main(String[] args) {
    // 替换为通过 OAuth2 获取的有效 access_token
    String accessToken = "your_access_token_here";

    Official1688ImageSearchClient client = new Official1688ImageSearchClient(accessToken);

    try {
    File imageFile = new File("/path/to/your/product.jpg");

    ImageSearchResult result = client.searchByImage(imageFile, 1, 20, 0.7);

    if (result.isSuccess()) {
    System.out.println("搜索成功,共找到 " + result.getTotalResults() + " 个商品");
    System.out.println("当前页: " + result.getPage() + ", 每页: " + result.getPageSize());

    for (SearchProduct product : result.getProducts()) {
    System.out.println("------------------------------");
    System.out.println("商品ID: " + product.getProductId());
    System.out.println("标题: " + product.getTitle());
    System.out.println("价格: " + product.getPrice());
    System.out.println("相似度: " + product.getSimilarity());
    System.out.println("最小起订量: " + product.getMinOrderQuantity());
    System.out.println("卖家: " + product.getSellerName());
    System.out.println("详情页: " + product.getDetailPageUrl());
    }
    } else {
    System.err.println("搜索失败: [" + result.getErrorCode() + "] " + result.getErrorMessage());
    }

    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    2.5 Maven 依赖
    xml

    com.squareup.okhttp3 okhttp 4.12.0 com.alibaba fastjson 1.2.83
三、路径二:跨境/分销场景图搜接口

1688 针对不同业务场景提供了专用图搜能力,需先订购对应解决方案。
3.1 跨境图搜商品 API
适用于跨境买家和 ERP 服务商,搜索 1688 跨境商品池中的相似商品。
前置条件:订购《跨境采购解决方案》或《跨境 ERP 对接解决方案》
核心参数:
表格
参数 类型 必选 说明
imageUrl String 是 图片 URL(公网可访问)
page Integer 否 页码,默认 1
priceMin / priceMax String 否 价格区间过滤
sort String 否 排序:price_asc, price_desc, sales_desc
调用流程:
调用图搜跨境商品 API,获取商品列表(含 offerId)
调用 alibaba.cross.productInfo 传入 offerId 获取商品详情
3.2 分销图搜商品 API
适用于社交分销买家,搜索 1688 支持分销的商品池。
前置条件:订购《社交电商采购对接解决方案》
调用流程:
调用图搜分销商品 API,获取 offerId 列表
调用 alibaba.cpsMedia.productInfo 传入 offerId 获取商品详情
3.3 Java 封装(跨境场景)

import okhttp3.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**

  • 1688 跨境图搜商品 API 客户端
    */
    public class CrossBorderImageSearchClient {

    // 跨境图搜接口地址(需根据实际文档确认)
    private static final String CROSS_BORDER_URL =
    "https://gw.open.1688.com/openapi/param2/1/com.alibaba.cross/cross.product.image.search";

    private final String accessToken;
    private final OkHttpClient httpClient;

    public CrossBorderImageSearchClient(String accessToken) {
    this.accessToken = accessToken;
    this.httpClient = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build();
    }

    /**

    • 跨境图搜 - 通过图片 URL 搜索
      */
      public JSONObject searchCrossBorderByImageUrl(String imageUrl, int page,
      String priceMin, String priceMax, String sort) throws IOException {

      FormBody.Builder formBuilder = new FormBody.Builder()
      .add("access_token", accessToken)
      .add("imageUrl", imageUrl)
      .add("page", String.valueOf(page));

      if (priceMin != null) formBuilder.add("priceMin", priceMin);
      if (priceMax != null) formBuilder.add("priceMax", priceMax);
      if (sort != null) formBuilder.add("sort", sort);

      Request request = new Request.Builder()
      .url(CROSS_BORDER_URL)
      .post(formBuilder.build())
      .build();

      try (Response response = httpClient.newCall(request).execute()) {
      String body = response.body().string();
      return JSON.parseObject(body);
      }
      }

    /**

    • 获取跨境商品详情
      */
      public JSONObject getCrossProductDetail(String offerId) throws IOException {
      String url = "https://gw.open.1688.com/openapi/param2/1/com.alibaba.cross/alibaba.cross.productInfo";

      FormBody formBody = new FormBody.Builder()
      .add("access_token", accessToken)
      .add("offerId", offerId)
      .build();

      Request request = new Request.Builder()
      .url(url)
      .post(formBody)
      .build();

      try (Response response = httpClient.newCall(request).execute()) {
      return JSON.parseObject(response.body().string());
      }
      }
      }
      四、路径三:第三方聚合 API 接入
      对于需要快速集成、支持多语言或高并发场景,可使用第三方聚合 API 服务。
      4.1 接口特点
      支持图片 URL 直接搜索(无需上传文件)
      提供多语言返回(en, zh, ru, th, pt, es 等)
      丰富的筛选条件:价格区间、一件代发、工厂认证、包邮等
      统一返回格式,降低接入成本
      4.2 请求参数
      表格
      参数 类型 必选 说明
      img_url String 是 图片 URL(阿里系平台图片可直接识别)
      page Integer 否 页码,默认 1
      page_size Integer 否 每页数量,默认 20,最大 20
      sort String 否 default / sales / price_up / price_down
      price_start / price_end String 否 价格区间
      support_dropshipping Boolean 否 筛选支持一件代发
      is_factory Boolean 否 筛选工厂店
      verified_supplier Boolean 否 筛选实力商家
      language String 否 返回语言,默认 en
      4.3 Java 实现
      java
      import okhttp3.*;
      import com.alibaba.fastjson.JSON;
      import com.alibaba.fastjson.JSONArray;
      import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**

  • 第三方聚合 API - 1688 图搜客户端
    */
    public class ThirdPartyImageSearchClient {

    private final String apiToken;
    private final String baseUrl;
    private final OkHttpClient httpClient;

    public ThirdPartyImageSearchClient(String apiToken, String baseUrl) {
    this.apiToken = apiToken;
    this.baseUrl = baseUrl; // 如 https://api.xxx.com
    this.httpClient = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build();
    }

    /**

    • 通过图片 URL 搜索 1688 商品
      */
      public JSONObject searchByImageUrl(String imageUrl, int page, int pageSize,
      String sort, String priceStart, String priceEnd,
      Boolean supportDropshipping, Boolean isFactory,
      Boolean verifiedSupplier, String language) throws IOException {

      HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl + "/search-items-by-image-url").newBuilder();
      urlBuilder.addQueryParameter("apiToken", apiToken);
      urlBuilder.addQueryParameter("img_url", imageUrl);
      urlBuilder.addQueryParameter("page", String.valueOf(page));
      urlBuilder.addQueryParameter("page_size", String.valueOf(pageSize));

      if (sort != null) urlBuilder.addQueryParameter("sort", sort);
      if (priceStart != null) urlBuilder.addQueryParameter("price_start", priceStart);
      if (priceEnd != null) urlBuilder.addQueryParameter("price_end", priceEnd);
      if (supportDropshipping != null) urlBuilder.addQueryParameter("support_dropshipping", String.valueOf(supportDropshipping));
      if (isFactory != null) urlBuilder.addQueryParameter("is_factory", String.valueOf(isFactory));
      if (verifiedSupplier != null) urlBuilder.addQueryParameter("verified_supplier", String.valueOf(verifiedSupplier));
      if (language != null) urlBuilder.addQueryParameter("language", language);

      Request request = new Request.Builder()
      .url(urlBuilder.build())
      .get()
      .build();

      try (Response response = httpClient.newCall(request).execute()) {
      if (!response.isSuccessful()) {
      throw new IOException("请求失败,状态码: " + response.code());
      }
      return JSON.parseObject(response.body().string());
      }
      }

    /**

    • 简化调用 - 仅传必要参数
      /
      public JSONObject searchByImageUrlSimple(String imageUrl, int page) throws IOException {
      return searchByImageUrl(imageUrl, page, 20, "default", null, null, null, null, null, "zh");
      }
      }
      五、图片上传与 URL 转换
      官方接口要求本地图片上传,而跨境/第三方接口需要图片 URL。实际开发中常需先将图片上传至图床获取 URL。
      5.1 图片上传至 1688 图床
      java
      import okhttp3.
      ;
      import com.alibaba.fastjson.JSON;
      import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.io.IOException;

/**

  • 1688 图片上传工具 - 获取图片 URL
    */
    public class ImageUploadUtil {

    private static final String UPLOAD_URL =
    "https://gw.open.1688.com/openapi/param2/1/com.alibaba.product/alibaba.product.image.upload";

    private final String accessToken;
    private final OkHttpClient httpClient;

    public ImageUploadUtil(String accessToken) {
    this.accessToken = accessToken;
    this.httpClient = new OkHttpClient();
    }

    /**

    • 上传图片到 1688 图床,返回图片 URL
      */
      public String uploadImage(File imageFile) throws IOException {
      RequestBody fileBody = RequestBody.create(
      MediaType.parse("image/jpeg"),
      imageFile
      );

      MultipartBody requestBody = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart("access_token", accessToken)
      .addFormDataPart("image", imageFile.getName(), fileBody)
      .build();

      Request request = new Request.Builder()
      .url(UPLOAD_URL)
      .post(requestBody)
      .build();

      try (Response response = httpClient.newCall(request).execute()) {
      JSONObject result = JSON.parseObject(response.body().string());

      if (result.getBooleanValue("success")) {
      return result.getString("imageUrl"); // 返回公网可访问的图片 URL
      } else {
      throw new IOException("上传失败: " + result.getString("errorMessage"));
      }
      }
      }
      }
      六、返回结果解析
      6.1 官方接口响应结构
      JSON
      {
      "result": {
      "success": true,
      "productList": [
      {
      "productId": "610947785104",
      "title": "2026夏季新款纯棉T恤",
      "imageUrl": "https://cbu01.alicdn.com/xxx.jpg",
      "similarity": 0.92,
      "price": "15.00",
      "minOrderQuantity": "50",
      "sellerId": "b2b-123456789",
      "sellerName": "XX服装厂",
      "detailPageUrl": "https://detail.1688.com/offer/610947785104.html"
      }
      ],
      "totalResults": 156,
      "page": 1,
      "pageSize": 20
      },
      "errorCode": "0",
      "errorMessage": "success"
      }
      6.2 核心返回字段说明
      表格
      字段 类型 说明
      productId String 商品 ID(offerId)
      title String 商品标题
      imageUrl String 商品主图 URL
      similarity Double 与查询图片的相似度(0~1)
      price String 商品价格
      minOrderQuantity String 最小起订量
      sellerId String 卖家 ID
      sellerName String 卖家名称
      detailPageUrl String 商品详情页链接
      totalResults Integer 匹配商品总数
      七、常见问题与解决方案
      表格
      问题现象 错误码 可能原因 解决方案
      认证失败 401 access_token 过期或无效 刷新 OAuth2 令牌,检查授权范围
      参数错误 400 / 4003 图片格式不支持、参数缺失 确认图片为 JPG/PNG,检查必填参数
      图片无法识别 400 图片 URL 非阿里系域名 先上传至 1688 图床获取内部 URL
      权限不足 403 未申请接口权限或未订购解决方案 在开放平台申请对应权限
      调用频率超限 429 QPS 超过限制 实现限流、增加请求间隔、申请提升额度
      服务端错误 500 1688 服务端异常 重试请求,联系平台技术支持
      无搜索结果 - 图片质量差或商品库无匹配 更换清晰商品主图,调整相似度阈值
      八、最佳实践建议
      Token 管理:access_token 有效期 2 小时,建议实现自动刷新机制,使用 Redis 缓存
      图片预处理:上传前压缩图片至 1MB 以内,提高响应速度
      相似度阈值:根据业务场景调整 similarDegree,一般 0.7~0.9 效果较好
      分页策略:搜索结果多时合理分页,避免一次性拉取过多数据
      缓存机制:相同图片的搜索结果缓存 5-15 分钟,减少 API 调用
      降级方案:接口异常时提供关键词搜索兜底
      合规注意:遵守 1688 开放平台使用协议,仅用于合法业务场景
      九、扩展应用场景
      基于 1688 图搜接口可构建以下应用:
      货源查找工具:上传竞品图片,快速找到源头工厂
      供应链比价系统:同款商品多供应商价格对比
      侵权检测:监控自家产品图片是否被他人盗用
      智能选品:通过图片分析市场趋势,辅助采购决策
      ERP 集成:为跨境电商 ERP 提供以图搜货能力

posted @ 2026-06-21 18:14  爱专研的技术土狗  阅读(45)  评论(0)    收藏  举报