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

SpringBoot+Jsoup爬虫存MySQL时无报错中断问题求助

解决爬虫存MySQL中途无报错终止的问题

我之前做爬虫项目时也碰到过一模一样的情况——没报错但程序突然停了,存的数据远达不到预期。结合你的SpringBoot+Jsoup场景,给你几个实用的排查方向和解决办法:

1. 先把「隐藏的异常」揪出来

很多时候程序不是真的“无报错终止”,而是你把异常吞掉了!比如爬取某条数据时页面结构突然变了、网络临时断开,或者存库时遇到主键冲突,但代码里没有完整的try-catch块,导致线程直接挂掉。

建议在单条数据爬取+存库的逻辑外层套上try-catch,把异常信息完整打出来:

// 循环处理每页帖子的逻辑
for (Element postEle : postElements) {
    try {
        // 解析标题、内容、IP等数据
        Post post = parsePostInfo(postEle);
        repo.save(post);
    } catch (Exception e) {
        // 用日志框架打印完整异常栈,别只打一句“出错了”
        log.error("处理帖子失败,元素内容:{}", postEle.html(), e);
        // 可以选择跳过这条,或者把失败的URL/内容记录到临时表后续补爬
        continue;
    }
}

这样哪怕某条数据出问题,整个爬虫也不会直接挂掉,还能精准定位到故障点。

2. 检查数据库连接池与事务配置

Spring Boot默认用HikariCP连接池,如果爬取速度快、批量存库,可能出现连接耗尽或者事务超时的情况:

  • 调整连接池参数:在application.yml里适当增大连接数,适配爬虫的高频写入:
spring:
  datasource:
    hikari:
      maximum-pool-size: 20  # 默认可能是10,爬取场景可以调大
      connection-timeout: 30000
  • 避免大事务:如果习惯把几百条数据攒到内存里再一次性saveAll,事务太大会触发超时或锁表。建议每爬20-50条就提交一次:
List<Post> postBatch = new ArrayList<>();
int batchSize = 50;
for (Element postEle : postElements) {
    Post post = parsePostInfo(postEle);
    postBatch.add(post);
    if (postBatch.size() >= batchSize) {
        repo.saveAll(postBatch);
        postBatch.clear(); // 清空列表释放内存
    }
}
// 处理最后一批不足batchSize的数据
if (!postBatch.isEmpty()) {
    repo.saveAll(postBatch);
}

3. 排查内存溢出问题

如果一次性爬30页1200条数据都存在内存里再批量保存,可能触发OOM(内存溢出),有些情况下JVM会直接退出而不打印日志:

  • 配置JVM参数,让OOM时自动生成堆转储文件:在启动参数里加-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof,后续可以用MAT工具分析内存占用情况。
  • 及时释放内存:爬取一批、保存一批、清空一批,不要让大量数据一直堆在内存里。

4. 检查MySQL端的限制

有时候问题出在MySQL那边:

  • 查看MySQL的错误日志(一般在/var/log/mysql/error.log或自定义路径),看有没有写入超时、主键冲突、max_allowed_packet过小等报错。
  • 如果是主键冲突,检查你的Post实体类是不是把重复概率高的字段(比如IP)设成了主键,应该改用自增主键或者唯一的帖子ID作为主键。

5. 防止被目标网站反爬限制

目标网站可能检测到爬虫,直接断开连接,导致Jsoup获取页面失败进而程序终止:

  • 给Jsoup请求加浏览器请求头:
Document doc = Jsoup.connect(targetUrl)
    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
    .referer("目标网站首页URL")
    .timeout(10000) // 增大超时时间
    .get();
  • 加随机延迟:每爬完一页,随机sleep 500-2000毫秒,降低请求频率:
Thread.sleep(new Random().nextInt(1500) + 500);

优先从异常捕获入手排查,这是最容易找到问题的点,大概率能解决你的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:08:10