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

Selenium HtmlUnitDriver无法加载页面表格元素问题求助

HtmlUnitDriver无法加载Mattermost安全更新页面的延迟加载表格

问题描述

我尝试用Selenium HtmlUnitDriver读取Mattermost安全更新页面的内容,浏览器中页面下半部分的表格是延迟加载的,但HtmlUnitDriver始终无法获取表格内的<tr>元素。已尝试waitForBackgroundJavaScript、滚动页面、点击操作等方式触发加载,均无效。ChromeDriver可以正常实现需求,但更倾向于使用HtmlUnitDriver。

相关代码:

// Set up the driver.
HtmlUnitDriver driver = new HtmlUnitDriver();
driver.getWebClient().getOptions().setMaxInMemory(-1);
driver.getWebClient().getOptions().setHistoryPageCacheLimit(0);
driver.setJavascriptEnabled(true);
driver.getWebClient().getOptions().setThrowExceptionOnScriptError(false);

// Go to webpage.
driver.get("https://mattermost.com/security-updates/");

// Attempt to get elements. This will return no elements.
driver.findElements(By.xpath("//table[@id='mattermostServerTable']/tbody/tr"));

问题原因

HtmlUnitDriver的JavaScript引擎(默认Rhino,新版可选GraalJS)对现代前端框架(如React)、懒加载API(如Intersection Observer)的兼容性远不如ChromeDriver,页面的表格渲染逻辑可能依赖这些HtmlUnit支持不完善的特性;另外,默认的User-Agent可能被网站识别为非标准浏览器,返回简化版内容或跳过懒加载触发逻辑。

解决步骤

1. 升级HtmlUnitDriver到最新版本

新版本的HtmlUnit对现代JS特性支持更好,建议使用最新稳定版,比如在Maven中:

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>htmlunit-driver</artifactId>
    <version>4.10.0</version> <!-- 替换为最新版本 -->
</dependency>

2. 配置WebClient模拟现代浏览器并优化JS/AJAX处理

模拟Chrome浏览器的User-Agent,启用CSS(部分懒加载逻辑依赖元素可见性计算),并配置AJAX控制器同步处理异步请求:

// 模拟Chrome浏览器,使用对应版本的BrowserVersion
HtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.CHROME);
WebClient webClient = driver.getWebClient();

// 启用CSS渲染,部分动态渲染依赖CSS
webClient.getOptions().setCssEnabled(true);
// 启用JS
webClient.getOptions().setJavaScriptEnabled(true);
// 忽略脚本错误和状态码错误
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
// 延长超时时间,确保页面和异步请求加载完成
webClient.getOptions().setTimeout(30000);
// 同步处理AJAX请求,避免异步加载遗漏
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
// 禁用内存限制和缓存,避免加载异常
webClient.getOptions().setMaxInMemory(-1);
webClient.getOptions().setHistoryPageCacheLimit(0);

3. 结合JS执行和显式等待触发表格加载

手动执行JS滚动到表格位置,触发懒加载逻辑,再等待元素加载完成:

driver.get("https://mattermost.com/security-updates/");

// 执行JS滚动到表格元素,触发懒加载
((JavascriptExecutor) driver).executeScript("document.getElementById('mattermostServerTable').scrollIntoView({behavior: 'smooth', block: 'center'});");

// 等待后台JS执行完成,延长等待时间确保表格渲染
webClient.waitForBackgroundJavaScript(15000);

// 显式等待表格行元素出现
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
List<WebElement> rows = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(
    By.xpath("//table[@id='mattermostServerTable']/tbody/tr")
));

// 验证结果
System.out.println("Loaded rows count: " + rows.size());

4. 备选方案:直接通过JS提取表格数据

如果元素定位仍失败,可直接执行JS提取表格数据,绕过元素渲染的兼容性问题:

// 执行JS获取表格所有行的文本内容
List<List<String>> tableData = (List<List<String>>) ((JavascriptExecutor) driver).executeScript("""
    const table = document.getElementById('mattermostServerTable');
    const rows = Array.from(table.querySelectorAll('tbody tr'));
    return rows.map(row => Array.from(row.cells).map(cell => cell.textContent.trim()));
""");

// 输出数据
for (List<String> row : tableData) {
    System.out.println(String.join("\t", row));
}

注意事项

  • 如果页面使用了非常新的JS特性(如ES6+的高级语法),HtmlUnit可能仍无法完全兼容,此时可以尝试启用GraalJS引擎(HtmlUnit 2.60+支持):
    webClient.getOptions().setJavaScriptEngine(JavaScriptEngine.GRAALJS);
    
  • 若上述方案均无效,可能需要暂时使用Headless Chrome作为替代,但如果必须使用HtmlUnit,可尝试向HtmlUnit项目提交兼容性问题报告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:57:14