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