常见原因是未设置请求头被反爬拦截,需添加User-Agent、超时和重定向处理;Jsoup不执行JS,动态内容需换工具;注意编码、选择器准确性及反爬应对措施。

用 Jsoup.connect() 抓网页时连不上,常见原因是什么
不是代码写错了,大概率是默认没带请求头,被网站当成爬虫直接拒绝。很多站点(尤其是新闻、电商类)会检查 User-Agent,空 header 会被 403 或 302 重定向到登录页。
- 必须手动加
.header("User-Agent", "Mozilla/5.0 ..."),推荐用 Chrome 当前的 UA 字符串 - 遇到反爬强的站,还要加
.timeout(10000)防超时,.followRedirects(true)处理跳转 - 如果目标页依赖 JavaScript 渲染(比如 Vue/React SPA),
Jsoup拿不到最终 DOM —— 它不执行 JS,这时候得换Puppeteer或Selenium
select() 和 getElementById() 返回结果为空?别急着改 selector
先确认 HTML 是否真加载成功,再查元素是否存在、是否在 iframe 里、是否动态插入。Jsoup 解析的是服务器返回的原始 HTML,不是浏览器渲染后的快照。
- 用
doc.body().html()打印出来看一眼,确认目标结构确实在源码里 -
select("div.content p")匹配失败?试试select("p")看有没有任何p标签,排除层级误判 - ID 选择器要小心大小写和空格:
getElementById("main-content")对应的是<div id="main-content">,不能写成mainContent或漏掉连字符 - 如果页面有多个同名 class,
select(".item")返回Elements列表,取第一个得用.first(),不是直接调用.text()
提取文本时乱码或空白多?注意编码和 whitespace 处理
Jsoup 默认按 UTF-8 解析,但有些网页 meta 声明是 GBK,或者响应头没设 charset,就会导致中文变问号或方块;另外 text() 会合并所有空白符,可能把换行缩进全压成一个空格。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 显式指定编码:
Jsoup.connect(url).charset("GBK").get()(适用于国内老站点) - 想保留原文排版?别用
text(),改用html()或遍历子节点手动拼接 - 清理多余空格用
String.trim().replaceAll("\s+", " "),但注意别误杀中文之间的正常空隙 - 如果目标字段藏在
<script>里(比如 JSON 数据),select("script")取出内容后得自己用正则或JsonParser提取,Jsoup 不解析 script 内容
简单爬虫跑几次就被封 IP?基础反爬应对怎么做
Jsoup 本身没内置限速或代理支持,裸奔请求等于告诉对方“我在扫你”。哪怕只是本地测试,也要模拟真实用户行为。
立即学习“Java免费学习笔记(深入)”;
- 加随机延时:
Thread.sleep(new Random().nextInt(2000) + 1000),别固定 1 秒 - 每次请求换
User-Agent,从列表里随机选,避免 UA 被标记 - 需要长期运行?必须加代理池,用
.proxy("127.0.0.1", 8888)接本地代理(如 Fiddler、Charles),别硬刚目标站防火墙 - 别忽略 robots.txt:
Jsoup.connect("https://example.com/robots.txt").get()先扫一眼,至少避开Disallow路径
真正难的不是取到数据,而是让请求看起来不像脚本——header、频率、cookie、Referer,每个细节都可能成为识别依据。


















