Вопрос-ответ

What are the pros and cons of the leading Java HTML parsers? [closed]

Каковы плюсы и минусы ведущих Java-парсеров HTML?

Поискав в SO и Google, я обнаружил, что существует несколько Java-парсеров HTML, которые постоянно рекомендуются различными сторонами. К сожалению, трудно найти какую-либо информацию о сильных и слабых сторонах различных библиотек. Я надеюсь, что некоторые люди потратили некоторое время на сравнение этих библиотек и могут поделиться тем, что они узнали.

Вот что я увидел:

И если есть какой-то крупный парсер, который я пропустил, я бы тоже хотел услышать о его плюсах и минусах.

Спасибо!

Переведено автоматически
Ответ 1

Общая информация

Почти все известные HTML-парсеры реализуют W3C DOM API (часть JAXP API, Java API для обработки XML) и предоставляют вам org.w3c.dom.Document обратную сторону, которая готова к прямому использованию JAXP API. Основные различия обычно заключаются в функциях данного парсера. Большинство парсеров в определенной степени снисходительны к некорректному HTML ("tagsoup"), таким как JTidy, NekoHTML, TagSoup и HTMLCleaner. Обычно вы используете такого рода парсеры HTML для "приведения в порядок" исходного кода HTML (например, заменяя действительный HTML <br> на действительный XML <br />), чтобы вы могли просматривать его "обычным способом", используя W3C DOM и JAXP API.

Единственные, которые бросаются в глаза, - это HtmlUnit и Jsoup.

HtmlUnit

HtmlUnit предоставляет полностью собственный API, который дает вам возможность программно действовать как веб-браузер. Т. е. Вводить значения формы, щелкать элементы, вызывать JavaScript и так далее. Это гораздо больше, чем просто парсер HTML. Это настоящий веб-браузер без графического интерфейса и инструмент модульного тестирования HTML.

Jsoup

Jsoup также предоставляет полностью собственный API. Это дает вам возможность выбирать элементы с помощью jQuery-подобных CSS селекторов и предоставляет удобный API для обхода дерева HTML DOM, чтобы получить интересующие элементы.

В частности, обход дерева HTML DOM является основной силой Jsoup. Те, кто работал с org.w3c.dom.Document, знают, какая адская боль проходить через DOM с использованием verbose NodeList и Node API. Да, XPath это упрощает жизнь, но, тем не менее, это еще одна кривая обучения, и в конечном итоге она может оказаться по-прежнему многословной.

Вот пример, в котором используется "простой" W3C DOM-парсер, такой как JTidy, в сочетании с XPath для извлечения первого абзаца вашего вопроса и имен всех ответивших (я использую XPath, поскольку без него код, необходимый для сбора интересующей информации, в противном случае увеличился бы в 10 раз, без написания служебных / вспомогательных методов).

String url = "http://javalang.ru/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://javalang.ru/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 - это правильный путь.

Ответ 2

В этой статье сравниваются некоторые аспекты следующих парсеров:


  • NekoHTML

  • JTidy

  • TagSoup

  • HTMLCleaner

Это ни в коем случае не полное резюме, и оно датировано 2008 годом. Но оно может оказаться полезным.

Ответ 3

Добавьте в свой список синтаксический анализатор validator.nu HTML, реализацию алгоритма синтаксического анализа HTML5 в Java.

С положительной стороны, он специально разработан для работы с HTML5 и лежит в основе валидатора HTML5, поэтому с высокой вероятностью будет соответствовать поведению будущего браузера при синтаксическом анализе с очень высокой степенью точности.

С другой стороны, ни один из устаревших браузеров не работает точно так, как этот, и, поскольку HTML5 все еще находится в стадии разработки, могут быть внесены изменения.

На практике такие проблемы затрагивают только неясные угловые случаи, и для всех практических целей это отличный парсер.

Ответ 4

Я обнаружил, что парсер HTML Jericho очень хорошо написан, поддерживается в актуальном состоянии (чего нет у многих парсеров), не имеет зависимостей и прост в использовании.

java