必须调用openconnection()并获取输入流才能读取网页内容;需检查响应码、设置超时、指定字符编码、处理重定向、设置user-agent、关闭连接,且无法获取js渲染后的内容。

用 java.net.URL 打开连接后读不到网页内容?
直接 new URL("https://example.com") 只是构造了一个地址对象,不发起请求,也不加载数据。必须调用 openConnection(),再显式获取输入流才能读源码。
常见错误现象:NullPointerException 或空字符串 —— 忘了调用 getInputStream(),或者没处理重定向、字符编码。
- 务必检查
HttpURLConnection.getResponseCode()是否为 200,否则可能拿到 301/404 响应体(甚至空) - 默认使用平台编码读取流,中文会乱码;必须用
HttpURLConnection.getContentEncoding()或响应头Content-Type中的charset指定编码,比如UTF-8 - 别跳过
setConnectTimeout()和setReadTimeout(),否则网络卡住会无限阻塞
HttpURLConnection 不自动处理 302 重定向?
Java 默认对 HttpURLConnection 的重定向行为是“有限自动”:JDK 7+ 对 GET/HEAD 请求默认跟随 3xx,但前提是 setInstanceFollowRedirects(true)(默认是 true),且服务器返回的 Location 是绝对 URL。一旦遇到相对路径、307/308,或手动设置了 setInstanceFollowRedirects(false),就会停在重定向响应上,读到的是 HTML 跳转页而非目标页源码。
- 检查响应码是否为 301/302,如果是,手动解析
getHeaderField("Location")并重建URL再请求 - 避免依赖自动重定向,尤其在爬虫场景下——它不保留 Cookie、不复用连接,还可能绕过你设置的请求头
- 若需完整重定向链追踪(比如调试跳转逻辑),必须自己循环处理,不能只靠一次
connect()
为什么读出来的源码里有 JavaScript 渲染的内容缺失?
java.net.URL + HttpURLConnection 只拿原始 HTML 响应体,不执行 JS、不解析 DOM、不触发 AJAX 请求。所谓“网页源码”,在这里就是服务器吐出的那坨纯文本,和你在浏览器里右键“查看网页源代码”看到的一致,但和 F12 开发者工具里 Elements 面板显示的动态结果完全不同。
立即学习“Java免费学习笔记(深入)”;
- 如果目标内容由
fetch()或axios加载,或通过document.write()插入,URL方式一定拿不到 - 别试图用正则从 HTML 里硬扒 JSON 数据块——先确认该数据是否真在初始 HTML 中(查看 Network → Doc 标签页的响应),否则徒劳
- 需要渲染后内容?换方案:用
WebDriver(如 ChromeDriver)或带 JS 执行能力的 HTTP 客户端(如 Playwright Java),不是URL类的问题
用 URL 实现基础爬虫时最常漏掉的三件事
很多人写完 url.openStream() 就以为完事了,结果线上跑几天就挂:超时、连接泄漏、被封 IP。根本原因不是代码逻辑错,而是忽略了 HTTP 协议层的实际约束。
- 每次
HttpURLConnection用完必须显式调用disconnect(),否则连接不会释放,容易耗尽 socket 资源 - 没设
setRequestProperty("User-Agent", "...")—— 大量网站会直接拒掉空 UA 的请求,返回 403 或空白页 - 没加请求间隔(
Thread.sleep(1000)),高频请求会被服务端限流或拉黑,且违反robots.txt约束
复杂点在于:这些不是语法错误,编译全过,本地测几次也正常,但一放真实环境就崩。最容易被忽略的是连接没关和 UA 没设——它们不会报错,只会静默失败。











