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

使用Jsoup批量爬取URL时,如何在异常后保持代码运行?

嘿,这个问题我批量爬取页面的时候可太熟悉了!SocketTimeoutException直接打断整个循环确实闹心,给你几个实用的方案,让你的爬虫稳稳跑完1000个URL:

处理Jsoup爬取时的SocketTimeoutException,保持程序持续运行

核心思路就是精准捕获异常并隔离出错的URL,再搭配重试、超时优化等手段,既减少异常发生,又保证循环不中断。

1. 基础操作:用try-catch包裹单个URL的爬取逻辑

把每个URL的请求代码单独放进try-catch块里,这样某一个URL出错时,只会跳过它,不会终止整个循环。示例代码:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.List;

public class Crawler {
    public static void main(String[] args) {
        List<String> urls = List.of("https://example.com/page1", "https://example.com/page2", "..."); // 你的1000个URL列表

        for (String url : urls) {
            try {
                // 配置合理的超时时间,比如10秒,避免无限等待
                Document doc = Jsoup.connect(url)
                        .timeout(10000)
                        .get();
                
                // 这里写你的HTML数据处理逻辑
                System.out.println("成功爬取:" + url);
            } catch (SocketTimeoutException e) {
                // 捕获超时异常,记录日志或标记该URL后续处理
                System.err.println("连接超时,跳过URL:" + url);
            } catch (IOException e) {
                // 兜底捕获其他IO异常(比如连接拒绝、DNS失败等)
                System.err.println("爬取失败,跳过URL:" + url + ",错误信息:" + e.getMessage());
            }
        }
    }
}

2. 进阶:给超时的URL加重试机制

很多超时是临时网络波动导致的,重试1-2次大概率能成功。可以封装一个带重试的工具方法:

private static Document fetchWithRetry(String url, int maxRetries) throws IOException {
    int attempt = 0;
    while (attempt < maxRetries) {
        try {
            return Jsoup.connect(url)
                    .timeout(10000)
                    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") // 模拟浏览器UA
                    .get();
        } catch (SocketTimeoutException e) {
            attempt++;
            System.err.println("第" + attempt + "次重试URL:" + url);
            // 重试前加短暂延迟,避免频繁请求触发反爬
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
    }
    // 多次重试仍失败,抛出异常让上层处理
    throw new SocketTimeoutException("重试" + maxRetries + "次后仍超时:" + url);
}

然后在循环里调用这个方法:

for (String url : urls) {
    try {
        Document doc = fetchWithRetry(url, 2); // 最多重试2次
        // 处理数据...
    } catch (SocketTimeoutException e) {
        System.err.println("最终失败,跳过URL:" + url);
    } catch (IOException e) {
        System.err.println("其他错误:" + url + "," + e.getMessage());
    }
}

3. 优化Jsoup超时配置

默认超时可能不符合目标网站的响应速度,你可以精细化配置:

  • .timeout(15000):统一设置连接+读取的总超时(毫秒)
  • 分别设置连接和读取超时:
Jsoup.connect(url)
        .timeout(0) // 先关闭总超时限制
        .connectionTimeout(5000) // 连接超时5秒
        .readTimeout(10000); // 读取响应超时10秒

4. 额外提醒:避免被目标网站封禁

爬1000个URL很容易被识别为爬虫,除了处理异常,还要注意:

  • 每次请求后加随机延迟:Thread.sleep(new Random().nextInt(2000) + 1000);(1-3秒随机)
  • 始终设置浏览器UA,避免被拦截
  • 控制并发数(新手建议先单线程爬,熟悉后再用线程池)

这样处理后,你的爬虫遇到超时或其他IO异常时,就不会直接崩溃,而是优雅地跳过或重试出错的URL,顺利完成1000个链接的爬取!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:26:05