发布于 2010-07-01 08:00:33
一般信息
几乎所有已知的HTML解析器都实现了W3C DOM API ( JAXP API的一部分,用于XML处理的Java API ),并返回一个可供JAXP API直接使用的org.w3c.dom.Document
。主要的区别通常在于所讨论的解析器的特性。大多数解析器在某种程度上对非格式的超文本标记语言(“标签汤”)都是宽宏大量的,比如JTidy、NekoHTML、TagSoup和HtmlCleaner。您通常使用这种HTML解析器来“整理”HTML源代码(例如,将HTML有效的<br>
替换为XML有效的<br />
),这样您就可以使用W3C DOM和JAXP API以“通常的方式”遍历它。
HtmlUnit
HtmlUnit提供了一个完全自带的应用程序接口,它可以让你以编程的方式像act浏览器一样工作。例如,输入表单值、单击元素、调用JavaScript等。它不仅仅是一个HTML解析器。它是一个真正的“无GUI的real浏览器”和HTML单元测试工具。
Jsoup
Jsoup还提供了一个完全自己的应用程序接口。它为您提供了使用jQuery-like CSS selectors选择元素的可能性,并提供了一个灵活的API来遍历HTML DOM树以获取感兴趣的元素。
特别是对HTML DOM树的遍历是Jsoup的主要优点。使用过org.w3c.dom.Document
的人都知道使用冗长的NodeList
和Node
API遍历DOM是多么痛苦。诚然,XPath
让生活变得更容易,但这仍然是另一条学习曲线,最终可能仍然很冗长。
这里有一个例子,它使用一个“普通的”W3C DOM解析器,比如JTidy和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),它也是相对容易掌握的。
摘要
现在,每种方法的利弊应该已经足够清楚了。如果只想使用标准JAXP API遍历它,那么使用前面提到的一组解析器。他们中有相当多的a lot。选择哪一个取决于它提供的功能(如何让HTML清理变得容易?是否有一些侦听器/拦截器和特定于标签的清理器?)以及库的健壮性(多长时间更新/维护/修复一次?)。如果你喜欢对超文本标记语言进行单元测试,那么HtmlUnit是个不错的选择。如果您希望从HTML中提取特定的数据(这通常是现实世界的需求),那么Jsoup就是最佳选择。
发布于 2010-07-01 04:43:03
发布于 2010-07-01 02:39:54
将The validator.nu HTML Parser添加到您的列表中,它是HTML5解析算法在Java语言中的一个实现。
从好的方面来说,它是专门为匹配HTML5而设计的,并且是HTML5验证器的核心,因此很有可能匹配未来浏览器的解析行为,达到非常高的准确度。
不利的一面是,没有浏览器的遗留解析完全像这样工作,而且HTML5仍处于草案阶段,可能会发生变化。
在实践中,这样的问题只影响晦涩难懂的角落情况,并且对于所有实际目的来说,都是一个优秀的解析器。
https://stackoverflow.com/questions/3152138
复制相似问题