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
相关产品推荐
相关产品推荐

