You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jsoup中加载文档前获取HTTP Content-Length

如何在Jsoup爬取前获取文档大小并排序队列

当然可以!你完全可以在调用connection.get()下载完整文档之前,通过HTTP响应头的Content-Length字段预估文档大小,以此实现优先爬取较小文档的需求。下面是具体的实现思路和代码示例:

核心思路:发送HEAD请求获取响应头

HTTP的HEAD请求只会返回响应头信息,不会下载文档正文,这是获取Content-Length最高效的方式——既节省带宽,又能快速拿到我们需要的大小数据。

具体实现步骤

1. 使用Jsoup发送HEAD请求获取文档大小

创建Jsoup连接时指定请求方法为HEAD,执行后从响应中提取Content-Length:

public long getDocumentSize(String url) {
    try {
        Response response = Jsoup.connect(url)
                .method(Connection.Method.HEAD)
                .timeout(5000) // 设置合理超时时间,避免阻塞
                .execute();
        // 从响应头中读取Content-Length
        String lengthStr = response.header("Content-Length");
        if (lengthStr != null && !lengthStr.isEmpty()) {
            return Long.parseLong(lengthStr);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 无法获取长度时返回极大值,让该链接排在队列末尾
    return Long.MAX_VALUE;
}

2. 用优先级队列实现按大小排序

把普通爬取队列换成PriorityQueue,自定义比较器让体积小的URL优先出队:

// 初始化优先级队列,按文档大小升序排序
PriorityQueue<Map.Entry<String, Long>> crawlQueue = new PriorityQueue<>(
        Comparator.comparing(Map.Entry::getValue)
);

// 维护已爬取URL集合,避免重复爬取
Set<String> crawledUrls = new HashSet<>();

// 假设已从初始页面提取到待爬取链接
List<String> initialLinks = ...;

// 遍历链接,获取大小后加入优先级队列
for (String link : initialLinks) {
    if (!crawledUrls.contains(link)) {
        long size = getDocumentSize(link);
        crawlQueue.add(new AbstractMap.SimpleEntry<>(link, size));
        crawledUrls.add(link);
    }
}

// 开始按优先级爬取
while (!crawlQueue.isEmpty()) {
    Map.Entry<String, Long> entry = crawlQueue.poll();
    String currentUrl = entry.getKey();
    
    // 执行正常爬取逻辑:下载文档、提取新链接
    try {
        Document doc = Jsoup.connect(currentUrl).get();
        Elements newLinks = doc.select("a[href]");
        // 对新链接重复流程:获取大小 -> 加入队列
        for (Element link : newLinks) {
            String absLink = link.absUrl("href");
            if (!crawledUrls.contains(absLink)) {
                long linkSize = getDocumentSize(absLink);
                crawlQueue.add(new AbstractMap.SimpleEntry<>(absLink, linkSize));
                crawledUrls.add(absLink);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

关键注意事项

  • 部分网站不支持HEAD请求:如果遇到服务器拒绝HEAD请求的情况,可以退而求其次发送GET请求(但会开始下载正文,效率稍低),或者直接将这类链接设为默认极大值延后爬取。
  • Content-Length可能缺失:动态生成内容、分块传输(Transfer-Encoding: chunked)的响应不会返回Content-Length,此时建议给这类链接设较大默认值,让它们排在有明确大小的链接之后。
  • 必须做URL去重:一定要维护已爬取URL集合,避免重复加入队列和爬取,浪费资源。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:24:43