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

使用HtmlUnit解析时能否修复HTML错误?如<?td>替代</td>问题

解决HtmlUnit解析含<?td>错误HTML的方案

嘿,这个问题我之前处理过类似的场景,HtmlUnit对不规范HTML的容错能力确实不如Chrome这类浏览器强,不过我们完全可以通过自定义处理来实现类似Chrome的修复效果,下面给你两个可行的方案:

方案一:解析前自定义HTML预处理(最推荐)

这个思路和Chrome保存页面时的修复逻辑类似——在HtmlUnit开始解析HTML之前,先把有问题的<?td>替换成正确的</td>。我们可以通过包装WebClient的WebConnection来实现:

WebClient webClient = new WebClient();

// 自定义WebConnection,拦截响应并修复HTML
webClient.setWebConnection(new WebConnectionWrapper(webClient) {
    @Override
    public WebResponse getResponse(WebRequest request) throws IOException {
        WebResponse originalResponse = super.getResponse(request);
        // 获取原始HTML字符串
        String rawHtml = originalResponse.getContentAsString();
        // 替换所有错误的<?td>标签为</td>
        String fixedHtml = rawHtml.replaceAll("\\<\\?td\\>", "</td>");
        
        // 返回修复后的响应内容
        return new WebResponseWrapper(originalResponse) {
            @Override
            public String getContentAsString() {
                return fixedHtml;
            }
        };
    }
});

// 之后正常请求页面即可
HtmlPage page = webClient.getPage("你的目标URL");

这个方法的优势在于从根源修正HTML,HtmlUnit拿到的已经是规范的代码,完全避免了后续解析时的异常,效果和Chrome保存后修复的逻辑一致。

方案二:利用IncorrectnessListener监听+DOM后修复

你提到的IncorrectnessListener主要用于监听HtmlUnit解析时发现的不规范问题,但它本身无法直接修改HTML内容。不过我们可以结合它和DOM遍历,在解析完成后手动修正页面结构:

WebClient webClient = new WebClient();

// 设置监听器捕获解析错误
webClient.setIncorrectnessListener((message, origin) -> {
    // 可以在这里打印错误信息,确认<?td>是否被检测到
    System.out.println("解析错误:" + message);
});

HtmlPage page = webClient.getPage("你的目标URL");

// 遍历所有<td>元素,检查并修复未闭合的情况
List<HtmlTd> tdList = page.getByXPath("//td");
for (HtmlTd td : tdList) {
    // 检查当前td的后续兄弟节点是否包含错误的<?td>(可能被解析为注释节点)
    Node nextSibling = td.getNextSibling();
    while (nextSibling != null) {
        if (nextSibling instanceof DomComment && nextSibling.getNodeValue().equals("?td")) {
            // 移除错误的注释节点
            nextSibling.getParentNode().removeChild(nextSibling);
            // 确保td已经正确闭合(HtmlUnit可能已自动处理,这里做双重保障)
            break;
        }
        nextSibling = nextSibling.getNextSibling();
    }
}

不过这个方案相对麻烦,因为HtmlUnit可能已经把<?td>解析成了注释节点,需要额外判断和处理,不如预处理方案直接高效。

额外小提示

你还可以调整HtmlUnit的容错配置,让它更宽容地处理不规范HTML:

  • webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);:忽略错误状态码
  • webClient.getOptions().setThrowExceptionOnScriptError(false);:忽略脚本错误
  • webClient.getOptions().setPrintContentOnFailingStatusCode(true);:打印错误响应内容,方便调试

但这些配置只是让HtmlUnit更“耐造”,不能直接修复标签错误,还是预处理方案最靠谱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:14:49