全部
常见问题
产品动态
精选推荐

Java 爬虫实战:用“官方 API + 签名”一键拿下淘宝商品详情

管理 管理 编辑 删除

—— 从注册账号、生成签名到多线程批量抓取,完整代码直接复制跑通!

在电商数据驱动的时代,淘宝商品详情就是金矿。但淘宝反爬全站顶尖:滑块、IP 封、JS 混淆、x-sign 动态令牌……与其硬刚,不如“合法驾驶”——直接调用官方接口 taobao.item_get_pro,数据最全、最稳、可商用!下面用一篇超长软文,带你纯 Java 实现签名、抓取、解析、落地全流程,文末附源码仓库。


一、先放结果:我们能拿到什么?


字段示例
商品标题【新品】iPhone 15 128G 蓝色 原装正品
价格4999.00
主图URL//img.alicdn.com/imgextra/xxx.jpg
库存356
销量2180
图文详情(HTML)<p>正品保障…</p>
SKU 列表颜色×内存×版本×价格×库存
店铺名称小李数码旗舰店


二、技术选型:为什么Java也能“丝滑”爬虫?


模块选型理由
HTTP 客户端Apache HttpClient 4.x连接池、代理、重试、并发全套API
JSON 解析Jackson 2.15注解+TreeNode双模式,字段缺失不报错
签名算法原生MessageDigest零依赖,与淘宝C版完全一致
并发框架ThreadPoolExecutor8线程+BlockingQueue,限速简单
结果落地OpenCSV一行注解导出CSV,Excel直接打开


三、3 分钟完成“官方通行证”注册

  1. 打开 淘宝开放平台 ➜ 注册开发者
  2. 创建应用 ➜ 拿到 App Key + App Secret
  3. 申请 taobao.item_get_pro 权限(勾选“商品”类目)
  4. 审核约 2h ➜ 通过后即可正式调用,QPS=10,日调用 10W+ 足够


四、签名算法:淘宝的“钥匙”一次讲透

官方规则(MD5 版):sign = MD5(appSecret + 按Key排序(业务参数) + appSecret).toUpperCase()

业务参数不包括 sign 本身,也不包括 ? 和 &。

工具类 SignUtil.java:

java

public final class SignUtil {
    public static String sign(Map<String, String> params, String appSecret) {
        StringBuilder sb = new StringBuilder(appSecret);
        params.entrySet().stream()
              .sorted(Map.Entry.comparingByKey())
              .forEach(e -> sb.append(e.getKey()).append(e.getValue()));
        sb.append(appSecret);
        return md5(sb.toString()).toUpperCase();
    }

    private static String md5(String raw) {
        try {
            byte[] bytes = MessageDigest.getInstance("MD5").digest(raw.getBytes(StandardCharsets.UTF_8));
            return new BigInteger(1, bytes).toString(16);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}


五、核心代码:从参数组装到 JSON 落地

① 构建请求 URL

java

public class TaoBaoClient {
    private static final String API = "https://eco.taobao.com/router/rest";
    private final String appKey, appSecret;

    public String getItemJson(String numIid) throws Exception {
        Map<String, String> p = new LinkedHashMap<>();
        p.put("method", "taobao.item_get_pro");
        p.put("app_key", appKey);
        p.put("v", "2.0");
        p.put("format", "json");
        p.put("sign_method", "md5");
        p.put("timestamp", LocalDateTime.now().toString());
        p.put("num_iid", numIid);
        p.put("fields", "title,price,pic_url,desc,skus,volume");
        p.put("sign", SignUtil.sign(p, appSecret));

        String url = API + "?" + p.entrySet().stream()
                .map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
                .collect(Collectors.joining("&"));

        try (CloseableHttpClient client = HttpClients.createDefault()) {
            return EntityUtils.toString(client.execute(new HttpGet(url)).getEntity());
        }
    }
}

② JSON → POJO(Jackson 注解)

java

@Data @JsonIgnoreProperties(ignoreUnknown = true)
public class ItemResp {
    private Item item;
}

@Data @JsonIgnoreProperties(ignoreUnknown = true)
public class Item {
    private String title;
    private String price;
    private String pic_url;
    private String desc;
    private Skus skus;
    private Long volume; // 销量
}

@Data @JsonIgnoreProperties(ignoreUnknown = true)
public class Skus {
    private List<Sku> sku;
}

@Data @JsonIgnoreProperties(ignoreUnknown = true)
public class Sku {
    private String properties_name; // 颜色:蓝色;内存:128G
    private String price;
    private Long quantity;
}

③ 一行代码解析

java

ItemResp resp = new ObjectMapper().readValue(json, ItemResp.class);
Item item = resp.getItem();
System.out.println(item.getTitle() + " ¥" + item.getPrice());


六、批量抓取:ThreadPool + 限速 + 重试

线程池 8 线程,队列 2k,失败 3 次即跳过:

java

ExecutorService pool = Executors.newFixedThreadPool(8);
ConcurrentLinkedQueue<Item> result = new ConcurrentLinkedQueue<>();

Files.readAllLines(Path.of("items.txt"))
     .forEach(id -> pool.submit(() -> {
         int retry = 0;
         while (retry < 3) {
             try {
                 ItemResp resp = mapper.readValue(client.getItemJson(id), ItemResp.class);
                 result.add(resp.getItem());
                 System.out.println("✅ " + id);
                 break;
             } catch (Exception e) {
                 retry++;
                 System.err.println("⚠️ " + id + " 第" + retry + "次失败");
                 LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
             }
         }
     }));

pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);


七、CSV 落地:OpenCSV 注解导出

java

@Builder
@CsvBindByName
class CsvRow {
    @CsvBindByName String title;
    @CsvBindByName String price;
    @CsvBindByName String pic_url;
    @CsvBindByName String desc;
    @CsvBindByName Long volume;
}

List<CsvRow> rows = result.stream()
        .map(i -> CsvRow.builder()
                .title(i.getTitle())
                .price(i.getPrice())
                .pic_url(i.getPic_url())
                .desc(StringUtils.abbreviate(i.getDesc(), 200))
                .volume(i.getVolume())
                .build())
        .collect(Collectors.toList());

try (Writer w = Files.newBufferedWriter(Path.of("taobao.csv"))) {
    new StatefulBeanToCsvBuilder<CsvRow>(w).build().write(rows);
}


八、反爬 & 合规清单

风险解决方案
签名错误参数按字典序,MD5大写
QPS 超限官方 10/s,线程池限速 8/s
IP 被封走官方 API,不封 IP
数据侵权不重新分发,仅内部分析
商用场景建议购买“数据Plus”套餐,更稳


九、运行截图

bash

$ java -jar taobao-spider.jar
✅ 652874751412
✅ 679573433212
✅ 679329478532
[=] 共抓取 500 条,已写入 taobao.csv

CSV 示例(Excel 直接打开):

表格复制
titlepricepic_urlvolumedesc
iPhone15 128G 蓝色4999.00//img.alicdn.com/xxx.jpg2180正品保障,全国联保…


十、进阶脑洞

  1. Spring Boot 封装 REST 服务,对外提供“商品查询”接口;
  2. Redis 缓存 24h,避免重复调用;
  3. 接入 RabbitMQ,将“失败 ID”丢进队列重试;
  4. 用 ECharts + MySQL 做价格趋势看板;
  5. Docker 镜像 50M,一条命令 docker run -e AK=xxx -e AS=xxx 即可跑。


合法调用,稳中带快;官方接口,永不掉线!
下篇想继续看 “淘宝评论+视频+主图打包下载” ?留言告诉我,安排!

请登录后查看

one-Jason 最后编辑于2025-09-26 16:05:52

快捷回复
回复
回复
回复({{post_count}}) {{!is_user ? '我的回复' :'全部回复'}}
排序 默认正序 回复倒序 点赞倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理员 企业

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推荐': '推荐'}}
{{item.is_suggest == 1? '取消推荐': '推荐'}}
沙发 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暂无简介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打赏
已打赏¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回复' : '回复'}}
删除
回复
回复

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回复 {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打赏
已打赏¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回复' : '回复'}}
删除
回复
回复
查看更多
打赏
已打赏¥{{reward_price}}
33
{{like_count}}
{{collect_count}}
添加回复 ({{post_count}})

相关推荐

快速安全登录

使用微信扫码登录
{{item.label}} 加精
{{item.label}} {{item.label}} 板块推荐 常见问题 产品动态 精选推荐 首页头条 首页动态 首页推荐
取 消 确 定
回复
回复
问题:
问题自动获取的帖子内容,不准确时需要手动修改. [获取答案]
答案:
提交
bug 需求 取 消 确 定
打赏金额
当前余额:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
请输入 0.1-{{reward_max_price}} 范围内的数值
打赏成功
¥{{price}}
完成 确认打赏

微信登录/注册

切换手机号登录

{{ bind_phone ? '绑定手机' : '手机登录'}}

{{codeText}}
切换微信登录/注册
暂不绑定
CRMEB客服

CRMEB咨询热线 咨询热线

400-8888-794

微信扫码咨询

CRMEB开源商城下载 源码下载 CRMEB帮助文档 帮助文档
返回顶部 返回顶部
CRMEB客服