使用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
相关产品推荐
相关产品推荐

