<cbn-root>元素是什么?如何用Java获取目标网站真实内容?
搞定Angular SPA的动态内容抓取问题
嘿,我来帮你理清这个问题!你遇到的情况其实很典型——<cbn-root>是Angular框架的根组件占位符,这说明你要监控的网站是个单页应用(SPA),下面给你拆解清楚:
先说说<cbn-root>到底是什么
- 它是Angular应用的入口标记:浏览器加载初始HTML时只会看到这个空标签,等Angular的JavaScript运行起来后,才会把实际的页面内容渲染到这个标签里面。这就是为什么你在Chrome审查元素里能看到完整内容(那是JS执行后的DOM),但看页面源码或用默认配置的HtmlUnit请求只能拿到空标签的原因。
- 这里的
cbn应该是项目的自定义前缀(比如网站名称的缩写),Angular开发者通常会给根组件加这种前缀,避免和其他组件或框架冲突。
用Java获取真实内容的两种可行方案
要拿到SPA的动态渲染内容,核心是让工具能执行JavaScript,下面给你两种实用方案:
方案一:给HtmlUnit开启JS渲染
HtmlUnit默认是禁用JS的,只要开启并等待页面渲染完成就能拿到内容:
import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlPage; public class SpaContentFetcher { public static void main(String[] args) throws Exception { try (WebClient webClient = new WebClient()) { // 启用JavaScript支持 webClient.getOptions().setJavaScriptEnabled(true); // 等待后台JS执行完毕(时间可以根据页面复杂度调整,比如5秒) webClient.waitForBackgroundJavaScript(5000); // 可选:禁用CSS渲染来提升速度 webClient.getOptions().setCssEnabled(false); HtmlPage page = webClient.getPage("https://www.drpciv.ro/drpciv-booking/formular/23/exchangingForeignDriverLicence"); // 获取渲染后的完整HTML String renderedHtml = page.asXml(); System.out.println(renderedHtml); } } }
小提示:HtmlUnit对一些现代JS特性的支持可能不如真实浏览器,如果遇到兼容性问题,可以试试下面的方案。
方案二:用Selenium模拟真实浏览器
Selenium会调用真实的浏览器(比如Chrome)来加载页面,完美执行所有JS,能100%获取到和你在浏览器里看到的一样的内容:
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; public class SeleniumScraper { public static void main(String[] args) { // 设置ChromeDriver的路径(根据你的操作系统调整,比如Windows是chromedriver.exe) System.setProperty("webdriver.chrome.driver", "/your/path/to/chromedriver"); // 启用无头模式(不用弹出浏览器窗口,适合后台运行) ChromeOptions options = new ChromeOptions(); options.addArguments("--headless=new"); try (WebDriver driver = new ChromeDriver(options)) { driver.get("https://www.drpciv.ro/drpciv-booking/formular/23/exchangingForeignDriverLicence"); // 等待页面加载完成(最好用显式等待,比如等待某个关键元素出现,这里先用sleep做示例) Thread.sleep(3000); // 获取渲染后的完整页面源码 String renderedHtml = driver.getPageSource(); System.out.println(renderedHtml); } catch (InterruptedException e) { e.printStackTrace(); } } }
注意:使用Selenium需要下载对应版本的浏览器驱动(比如ChromeDriver要和你的Chrome版本匹配),而且可以用WebDriverWait替代Thread.sleep,比如等待预约相关的元素加载出来,这样更可靠。
额外的优化建议
- 如果你只是监控预约空位,其实不用抓取整个页面:打开Chrome的开发者工具(F12),切换到Network标签,刷新页面,看看有没有获取预约数据的XHR/fetch接口,直接调用这些接口会比爬页面更高效、更稳定,还不容易触发反爬。
- 记得控制请求频率,不要太频繁访问,避免被网站封禁IP哦。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

