一、为什么非要自己爬?
- 选品:直播公司每天需要 500+ 新款主图视频做二次剪辑;
- 比价:同一款商品,视频拍得好不好,直接影响转化率;
- 数据训练:做图像-文本多模态模型,需要“商品+视频+标题”成对数据。官方 taobao.item.get 接口确实能回视频地址,但:① 需要“商品服务”权限,企业店 + 品牌备案,个人开发者 99% 被卡;② 返回的 CDN 直链带防盗链,有效期 2 h,不适合长期素材库。因此“网页派”依旧是 2025 年最普惠的方案。
二、整体技术路线
- 淘宝 PC 搜索 → 2. 商品数字 ID → 3. 详情 JSON → 4. 解析出 cloud.video.taobao.com/...mp4 → 5. 下载 → 6. 去重 → 7. 落库 → 8. 云函数定时 → 9. 飞书群播报。全程 Java,不依赖 Selenium,4 核 8 G 笔记本一晚可抓 8w 条视频。
三、开发前准备
- JDK ≥ 11(推荐 17,HTTP Client 自带 HTTP/2);
- Maven 依赖如下,直接复制到 pom.xml:
xml
<dependencies>
<!-- 网络 -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
<!-- 解析 -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.4</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<!-- 下载 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.2-jre</version>
</dependency>
</dependencies>
- 代理池(可选):免费套餐 1 分钟 60 次足够,推荐青果/阿布云按量付费,1 G 流量≈0.8 元。
四、代码实战:五步带走视频
① 关键字搜索拿商品 ID(PC 端)
java
public static List<String> listIds(String keyword, int page) throws IOException {
String url = "https://s.taobao.com/search?q="
+ URLEncoder.encode(keyword, StandardCharsets.UTF_8)
+ "&s=" + (page * 48);
Document doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
.timeout(10_000).get();
Elements items = doc.select("div[data-category=auctions]");
List<String> ids = new ArrayList<>(48);
for (Element it : items) {
ids.add(it.attr("data-nid"));
}
return ids;
}
② 调淘宝移动端 JSON 接口拿视频地址
(跳过无头浏览器,直接 HTTP,2025-10 结构)
java
private static final String API =
"https://api.m.taobao.com/h5/mtop.taobao.detail.getdetail/6.0/?jsv=2.4.11&appKey=12574478&t=%d&sign=%s&api=mtop.taobao.detail.getdetail&v=6.0&data=%s";
public static String fetchVideoUrl(String numIid) throws Exception {
String data = "{\"itemId\":\"" + numIid + "\"}";
long t = System.currentTimeMillis();
String sign = SignUtil.sign(t + "&12574478&" + data + "&"); // 见下文工具类
String url = String.format(API, t, sign, URLEncoder.encode(data, UTF_8));
try (CloseableHttpClient hc = HttpClients.createDefault()) {
HttpGet get = new HttpGet(url);
get.setHeader("User-Agent", "MTOP/3.x (Android; 10; zh-CN)");
String json = EntityUtils.toString(hc.execute(get).getEntity());
JsonNode node = new ObjectMapper().readTree(json);
JsonNode v = node.at("/data/item/video");
return v == null ? null : v.get("url").asText();
}
}
SignUtil 工具类(2025 年 10 月可用,若失效抓包替换)
public class SignUtil {
public static String sign(String raw) {
return DigestUtils.md5DigestAsHex(raw.getBytes()).toUpperCase();
}
}
③ 下载 + 去重 + 断点续传
淘宝视频 9~30 s,大小 600 k~3 M,用 Content-Range 可做断点,但实测 3 M 直接流式下载即可。
java
public static void download(String videoUrl, String numIid, String dest) {
File target = new File(dest, numIid + ".mp4");
if (target.exists()) return;
try (CloseableHttpClient hc = HttpClients.createDefault()) {
HttpGet get = new HttpGet(videoUrl);
get.setHeader("Referer", "https://detail.tmall.com/");
try (CloseableHttpResponse resp = hc.execute(get);
OutputStream out = new FileOutputStream(target)) {
IOUtils.copy(resp.getEntity().getContent(), out);
}
} catch (IOException e) {
log.warn("download fail {}", videoUrl, e);
}
}
④ 落库(MyBatis-Plus 批量)
java
TbVideo v = TbVideo.builder()
.numIid(numIid)
.videoUrl(videoUrl)
.localPath(target.getAbsolutePath())
.fileSize(target.length())
.fileHash(hash(target))
.build();
videoService.save(v);
⑤ 主函数一键跑
java
public static void main(String[] args) throws Exception {
String keyword = "蓝牙耳机";
for (int p = 1; p <= 5; p++) {
List<String> ids = listIds(keyword, p);
for (String id : ids) {
String url = fetchVideoUrl(id);
if (url == null) continue;
download(url, id, "/mnt/nas/taobao_video");
Thread.sleep(600 + RandomUtils.nextInt(0, 400));
}
}
}
五、并发加速:线程池 + 令牌桶
淘宝单 IP 100 QPM 是软上限,超过会 302 到登录页。
用 Guava RateLimiter + 8 线程池,一晚 8w 商品毫无压力。
java
ExecutorService pool = new ThreadPoolExecutor(
8, 8, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2000),
new ThreadFactoryBuilder().setNameFormat("video-%d").build());
RateLimiter limiter = RateLimiter.create(15); // 15/s = 900/min
for (String id : ids) {
limiter.acquire();
pool.submit(() -> {
try {
String v = fetchVideoUrl(id);
if (v != null) download(v, id, "/mnt/nas/taobao_video");
} catch (Exception e) {
log.warn("fail id {}", id, e);
}
});
}
六、云函数部署:每天 8 点自动跑
- 阿里云函数计算 FC运行环境:Java 17内存 512 MB,超时 600 s触发器:Cron 0 0 8 * * *
- 打包 mvn package -DskipTests,上传 FatJar(≈ 35 M);
- NAS 挂载 /mnt/nas/ 存放视频,免占 OSS 流量;
- 跑完调用飞书机器人:
java
String body = "{\"msg_type\":\"text\",\"content\":{\"text\":\"今日新增 312 个主图视频,重复率 21%,磁盘剩余 1.2 T\"}}";
HttpPost post = new HttpPost("https://open.feishu.cn/open-apis/bot/v2/hook/xxx");
post.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
HttpClients.createDefault().execute(post);
七、踩坑与反爬锦囊
- Referer 防盗链视频 CDN 强制 Referer: *.taobao.com,否则 403。
- 302 滑块单 IP 突刺 > 300 QPM 会出滑块,直接休眠 30 min 或切代理。
- 重复文件用 MurmurHash3 64 bit 算指纹,16 字符存库,重复率 28%,省 200 G。
- robots.txt淘宝禁止 /order/、/user/,搜索列表放行,但 UA 请写自家英文名,别冒充百度。
八、合规声明
- 仅抓取“主图视频”,不碰评论、订单、买家秀等隐私数据;
- 数据存储与使用遵循《个人信息保护法》及淘宝服务协议;
- 若用于商业化,建议申请官方 taobao.item.get 接口,拿到 CDN 直链,稳定性 ×10。
九、结语
从解析 HTML、调用移动端 JSON,到并发下载、云函数飞书推送,一条完整的 Java 闭环就打通了。
全部代码可直接扔进 IDEA 跑通,改一行 keyword 就能薅任意品类。
祝各位运营、剪辑、算法工程师们,爬得开心,爆单更开心!