You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JSoup爬取速卖通仅获取6条图片src,其余为空的问题求助

JSoup爬取速卖通图片仅部分获取有效src值的解决方案

问题描述

我用以下JSoup代码爬取速卖通女士手表分类页面的图片数据:

Document document = Jsoup.connect("https://www.aliexpress.com/category/200214036/women-watches.html?spm=2114.search0103.3.7.765d221bi3J3Io&site=glo&g=y").get();
Elements titleElement = document.select("div.item > div.img > div.pic > a.picRind > img");
String essay = essayElement.text(); // 这里是笔误,忽略即可
int i = 0;
String linkss[] = new String[titleElement.size()];
for(Element el : titleElement){
    linkss[i] = el.attr("abs:src");
    System.out.println(linkss[i]);
    i++;
}

运行后发现titleElement.size()显示有48个元素,但打印图片src时仅6个有有效值,其余为空,请问该如何解决?

原因分析

这是因为速卖通采用了图片懒加载技术:页面初始加载时,只有当前视口内的图片会把真实地址放在src属性里,而未进入可见区域的图片,真实地址会被存放在自定义属性(比如data-src)中,只有当用户滚动页面到图片位置时,JavaScript才会把真实地址赋值给src

JSoup只能获取页面的静态HTML源码,不会执行页面中的JavaScript,所以自然拿不到那些懒加载图片的真实地址。

解决步骤

1. 确认图片的真实地址属性

打开目标页面,按F12进入开发者工具,查看那些空src的图片元素,你会发现速卖通通常把懒加载图片的真实地址存在data-src属性中。

2. 修改JSoup代码,优先读取懒加载属性

修改代码逻辑,先尝试获取data-src的绝对地址,如果该属性为空,再回退到src属性。同时添加模拟浏览器的请求头,避免被反爬拦截:

Document document = Jsoup.connect("https://www.aliexpress.com/category/200214036/women-watches.html?spm=2114.search0103.3.7.765d221bi3J3Io&site=glo&g=y")
        .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
        .timeout(10000) // 设置超时时间,避免请求卡住
        .get();
Elements imgElements = document.select("div.item > div.img > div.pic > a.picRind > img");
List<String> validImageUrls = new ArrayList<>();

for(Element imgEl : imgElements) {
    // 优先获取data-src的绝对URL
    String imgUrl = imgEl.attr("abs:data-src");
    // 如果data-src为空,再尝试src属性
    if (imgUrl.isEmpty()) {
        imgUrl = imgEl.attr("abs:src");
    }
    // 只收集有效地址
    if (!imgUrl.isEmpty()) {
        validImageUrls.add(imgUrl);
        System.out.println(imgUrl);
    }
}

System.out.println("成功获取到 " + validImageUrls.size() + " 个有效图片地址");

3. 进阶应对复杂动态渲染

如果后续遇到更复杂的情况(比如图片地址是通过JS动态计算生成的),JSoup就无法处理了,这时可以使用支持JavaScript执行的工具,比如Selenium,模拟完整的浏览器加载过程,再获取渲染后的页面源码进行解析。

内容的提问来源于stack exchange,提问作者Zishan

火山引擎 最新活动