Java爬虫淘宝拍立淘item_search_img拍接口示例代码

淘宝拍立淘(item_search_img)接口允许开发者上传一张商品图片,返回与之相似的商品列表,广泛用于比价、选品、竞品监控等场景。下面给出一份"纯 Java 版"爬取思路与示例代码,不依赖任何官方 SDK,也不带外链,方便快速集成到自有爬虫框架中。


一、核心流程

  1. 注册淘宝开放平台账号,创建应用,拿到 app_key / app_secret,并申请 taobao.item_search_img 权限。

  2. 把待搜索图片转成淘宝认可的"外部地址":

    • 方案 A:先调淘宝 pic/upload 接口拿到 imgId;

    • 方案 B:把图片直传 OSS/七牛等可公网访问的地址,复制 URL 即可。

  3. 按淘宝签名规范生成 sign(MD5,ASCII 升序 + app_secret 前后包夹)。

  4. 用 POST 方式提交到 eco.taobao.com/router/rest,Content-Type 为 application/x-www-form-urlencoded。

  5. 解析返回 JSON,提取 items→item 数组里的 title、price、pic_url、detail_url、sales 等字段。


二、关键参数

参数名 必填 说明
method 固定 taobao.item_search_img
app_key 应用唯一标识
timestamp 格式 yyyy-MM-dd HH:mm:ss
format json
v 2.0
sign_method md5
sign 按规范生成的签名
imgid 图片 URL(或 upload 后的 id)
cat 类目 ID,如 50010788 表示女装
page 页码,默认 1

三、Java 签名与请求示例

java 复制代码
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;
import org.json.JSONObject;

public class PailitaoCrawler {

    private static final String APP_KEY     = "your_app_key";
    private static final String APP_SECRET  = "your_app_secret";
    private static final String GATEWAY     = "https://eco.taobao.com/router/rest";

    public static void main(String[] args) throws Exception {
        String imgUrl = "https://your-domain.com/demo.jpg"; // 公网可访问
        String json   = searchByImage(imgUrl, 1);
        System.out.println(json);
    }

    public static String searchByImage(String imgUrl, int page) throws Exception {
        Map<String, String> params = new LinkedHashMap<>();
        params.put("method",       "taobao.item_search_img");
        params.put("app_key",      APP_KEY);
        params.put("timestamp",    new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        params.put("format",       "json");
        params.put("v",            "2.0");
        params.put("sign_method",  "md5");
        params.put("imgid",        imgUrl);
        params.put("page",         String.valueOf(page));

        String sign = generateSign(params, APP_SECRET);
        params.put("sign", sign);

        String body = buildQuery(params);
        return httpPost(GATEWAY, body);
    }

    private static String generateSign(Map<String, String> params, String secret) throws Exception {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder(secret);
        for (String k : keys) sb.append(k).append(params.get(k));
        sb.append(secret);
        byte[] bytes = MessageDigest.getInstance("MD5").digest(sb.toString().getBytes(StandardCharsets.UTF_8));
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) hex.append(String.format("%02X", b));
        return hex.toString();
    }

    private static String buildQuery(Map<String, String> params) throws Exception {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> e : params.entrySet()) {
            if (sb.length() > 0) sb.append('&');
            sb.append(e.getKey()).append('=')
              .append(URLEncoder.encode(e.getValue(), "UTF-8"));
        }
        return sb.toString();
    }

    private static String httpPost(String url, String body) throws Exception {
        java.net.HttpURLConnection conn = (java.net.HttpURLConnection) new java.net.URL(url).openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        try (OutputStream os = conn.getOutputStream()) {
            os.write(body.getBytes(StandardCharsets.UTF_8));
        }
        try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
            StringBuilder res = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) res.append(line);
            return res.toString();
        }
    }
}

四、返回数据快速解析

返回片段示例(已格式化):

javascript 复制代码
{
  "item_search_img_response": {
    "items": {
      "item": [
        {
          "title": "日系宽松卫衣",
          "price": "89.00",
          "pic_url": "https://img.alicdn.com/xxx.jpg",
          "detail_url": "https://item.taobao.com/id=xxx",
          "sales": 1203
        }
      ]
    }
  }
}

用 org.json 或 fastjson 取出数组即可落地到数据库/ES。


五、常见踩坑

  1. sign 错误:确保 ASCII 升序、value 不编码、前后都带 secret。

  2. 图片地址防盗链:外部地址必须 200 且返回 image/*,否则淘宝会报 5001。

  3. 频率限制:默认 5000 次/日,超出会 403,需要缓存或队列削峰。

  4. 类目过滤:cat 传错会返回空列表,可先用 itemcats 接口拉全量映射表。

  5. 分页最多 100 页,每页 20 条,即 2000 条上限,深度翻页意义不大。

相关推荐
alvin_20055 分钟前
python之OpenGL应用(二)Hello Triangle
python·opengl
机器视觉的发动机10 分钟前
AI算力中心的能耗挑战与未来破局之路
开发语言·人工智能·自动化·视觉检测·机器视觉
铁蛋AI编程实战13 分钟前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
HyperAI超神经18 分钟前
在线教程|DeepSeek-OCR 2公式/表格解析同步改善,以低视觉token成本实现近4%的性能跃迁
开发语言·人工智能·深度学习·神经网络·机器学习·ocr·创业创新
jiang_changsheng25 分钟前
RTX 2080 Ti魔改22GB显卡的最优解ComfyUI教程
python·comfyui
R_.L28 分钟前
【QT】常用控件(按钮类控件、显示类控件、输入类控件、多元素控件、容器类控件、布局管理器)
开发语言·qt
Zach_yuan37 分钟前
自定义协议:实现网络计算器
linux·服务器·开发语言·网络
云姜.42 分钟前
java多态
java·开发语言·c++
CoderCodingNo1 小时前
【GESP】C++五级练习题 luogu-P1865 A % B Problem
开发语言·c++·算法
陳10301 小时前
C++:红黑树
开发语言·c++