搜索 SO 和 Google,我发现有一些 Java HTML 解析器,各方一致推荐。不幸的是,很难找到有关各种库的优缺点的任何信息。我希望有些人花了一些时间比较这些库,并可以分享他们学到的东西。
这是我所看到的:
如果我错过了一个主要的解析器,我也很想听听它的优缺点。
谢谢!
几乎所有已知的 HTML 解析器都实现了W3C DOM API(JAXP API 的一部分,用于 XML 处理的 Java API)并为您提供了一个org.w3c.dom.Document可供 JAXP API 直接使用的支持。主要差异通常可以在所讨论的解析器的特性中找到。大多数解析器在一定程度上宽容和宽容非格式良好的 HTML(“tagsoup”),例如JTidy、NekoHTML、TagSoup和HtmlCleaner。您通常使用这种 HTML 解析器来“整理”HTML 源代码(例如,将 HTML-valid 替换为<br>XML-valid <br />),以便您可以使用 W3C DOM 和 JAXP API“以通常的方式”遍历它。
org.w3c.dom.Document
<br>
<br />
唯一跳出来的是HtmlUnit和Jsoup。
HtmlUnit提供了一个完全自己的 API,它使您可以像 Web 浏览器一样以编程方式行事。即输入表单值、单击元素、调用 JavaScript 等。它不仅仅是一个 HTML 解析器。它是一个真正的“无 GUI 网络浏览器”和 HTML 单元测试工具。
Jsoup还提供了完全自己的 API。它使您可以使用类似jQuery的CSS 选择器来选择元素,并提供一个灵活的 API 来遍历 HTML DOM 树以获取感兴趣的元素。
尤其是 HTML DOM 树的遍历是 Jsoup 的主要优势。使用过的人都org.w3c.dom.Document知道使用冗长的 API 遍历 DOM 是多么NodeList痛苦Node。诚然,XPath让生活更轻松,但仍然是另一个学习曲线,最终可能仍然很冗长。
NodeList
Node
XPath
这是一个示例,它使用像 JTidy 这样的“普通”W3C DOM 解析器结合 XPath 来提取问题的第一段和所有回答者的姓名(我使用 XPath,因为没有它,代码需要收集感兴趣的信息否则会增长 10 倍,而无需编写实用程序/辅助方法)。
String url = "http://stackoverflow.com/questions/3152138"; Document document = new Tidy().parseDOM(new URL(url).openStream(), null); XPath xpath = XPathFactory.newInstance().newXPath(); Node question = (Node) xpath.compile("//*[@id='question']//*[contains(@class,'post-text')]//p[1]").evaluate(document, XPathConstants.NODE); System.out.println("Question: " + question.getFirstChild().getNodeValue()); NodeList answerers = (NodeList) xpath.compile("//*[@id='answers']//*[contains(@class,'user-details')]//a[1]").evaluate(document, XPathConstants.NODESET); for (int i = 0; i < answerers.getLength(); i++) { System.out.println("Answerer: " + answerers.item(i).getFirstChild().getNodeValue()); }
下面是一个示例,如何使用 Jsoup 进行完全相同的操作:
String url = "http://stackoverflow.com/questions/3152138"; Document document = Jsoup.connect(url).get(); Element question = document.select("#question .post-text p").first(); System.out.println("Question: " + question.text()); Elements answerers = document.select("#answers .user-details a"); for (Element answerer : answerers) { System.out.println("Answerer: " + answerer.text()); }
你看得到差别吗?它不仅代码更少,而且如果您已经对 CSS 选择器有一定的经验(例如通过开发网站和/或使用 jQuery),Jsoup 也相对容易掌握。
现在每个人的优缺点应该很清楚了。如果您只想使用标准的 JAXP API 来遍历它,那么请使用第一个提到的解析器组。有很多。选择哪一个取决于它提供的功能(HTML 清理如何让您轻松?是否有一些侦听器/拦截器和特定于标签的清理器?)以及库的健壮性(它多久更新/维护/修复? )。如果您喜欢对 HTML 进行单元测试,那么 HtmlUnit 是您的最佳选择。如果您想从 HTML 中提取特定数据(这通常是现实世界的要求),那么 Jsoup 就是您的最佳选择。