Общее
Почти все известные HTML-парсеры реализуют DOM API W3C (часть JAXP API, Java API для обработки XML) и дают вам org.w3c.dom.Document
обратную связь, которая готова для прямого использования API JAXP. Основные различия обычно заключаются в особенностях рассматриваемого синтаксического анализатора. Большинство синтаксических анализаторов в некоторой степени прощают и снисходительно относятся к некорректно сформированному HTML («tagsoup»), например JTidy , NekoHTML , TagSoup и HtmlCleaner . Вы обычно используете этот вид HTML-парсеров, чтобы «привести в порядок» исходный код HTML (например, заменив HTML-действительный <br>
на XML-действительный <br />
), чтобы вы могли пройти его «обычным способом», используя DOM W3C и API JAXP.
Единственные, которые выскакивают - это HtmlUnit и Jsoup .
HtmlUnit
HtmlUnit предоставляет полностью собственный API, который дает вам возможность программно вести себя как веб-браузер. Т.е. введите значения формы, щелкните элементы, вызовите JavaScript и т. Д. Это гораздо больше, чем один HTML-парсер. Это настоящий «веб-браузер без GUI» и инструмент для модульного тестирования HTML.
Jsoup
Jsoup также предоставляет полностью собственный API. Это дает вам возможность выбирать элементы, используя jQuery- подобные CSS-селекторы, и предоставляет удобный API для обхода дерева HTML DOM, чтобы получить интересующие элементы.
В частности, обход HTML DOM-дерева - главная сила Jsoup. Те, с кем работали, org.w3c.dom.Document
знают, что это за адская боль - обходить DOM, используя подробные NodeList
и Node
API-интерфейсы. Правда,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());
}
Вы видите разницу? Это не только меньше кода, но Jsoup также относительно легко понять, если у вас уже есть умеренный опыт работы с CSS-селекторами (например, разработка веб-сайтов и / или использование jQuery).
Резюме
Плюсы и минусы каждого должны быть достаточно ясны сейчас. Если вы просто хотите использовать стандартный JAXP API для его обхода, перейдите к первой упомянутой группе анализаторов. Их довольно много . Какой из них выбрать, зависит от того, какие функции он предоставляет (как вам легко сделать очистку HTML? Есть ли слушатели / перехватчики и очистители для тегов?) И надежности библиотеки (как часто она обновляется / поддерживается / исправляется? ). Если вам нравится модульное тестирование HTML, то HtmlUnit - это то, что вам нужно. Если вам нравится извлекать конкретные данные из HTML (что чаще всего является требованием реального мира), то Jsoup - это то, что вам нужно.