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

175

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

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

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

Спасибо!

Ави Лен
источник

Ответы:

223

Общее

Почти все известные 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и NodeAPI-интерфейсы. Правда,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 - это то, что вам нужно.

BalusC
источник
Здесь есть огромный аргумент "за" и "против": Jericho - единственный известный мне анализатор, который позволяет вам манипулировать неприятным HTML, сохраняя при этом форматирование пробелов и некорректность HTML (если есть).
Адам Гент
3
Jsoupэто хорошо. Я попытался связать его с другим модулем, который работает с org.w3c.dom.*API. Обнаружил, что Jsoup не подчиняется org.w3c.dom.*контракту
Thamme Gowda
13

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

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

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

Мэтт Солнит
источник
Это ответ только для ссылки. Можете ли вы добавить соответствующие подробности здесь?
Восстановить Монику - Нотмайнард
7

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

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

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

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

Alohci
источник
7

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

MJB
источник
6

Я просто добавлю к ответу @MJB после работы с большинством библиотек разбора HTML в Java, здесь пропущен огромный аргумент pro / con: парсеры, которые сохраняют форматирование и некорректность HTML при вводе и выводе.

То есть большинство синтаксических анализаторов при изменении документа стирают пробелы, комментарии и некорректность DOM, особенно если они представляют собой XML-подобную библиотеку.

Иерихон - единственный из известных мне анализаторов, который позволяет вам манипулировать неприятным HTML, сохраняя при этом форматирование пробелов и некорректность HTML (если есть).

Адам Гент
источник
3

Два других варианта - это HTMLCleaner и HTMLParser .

Я перепробовал большинство синтаксических анализаторов для разрабатываемого мной механизма поиска / извлечения данных. Я использую HTMLCleaner для основной работы по извлечению данных. Это связано с тем, что он поддерживает достаточно современный диалект HTML, XHTML, HTML 5 с пространствами имен и поддерживает DOM, поэтому его можно использовать со встроенной реализацией Java в XPath .

С HTMLCleaner сделать это намного проще, чем с некоторыми другими анализаторами: JSoup, например, поддерживает DOM-подобный интерфейс, а не DOM, поэтому требуется некоторая сборка . Иерихон имеет интерфейс линии SAX, так что опять же он требует некоторой работы, хотя Sujit Pal имеет хорошее описание того, как это сделать, но в итоге HTMLCleaner просто работал лучше.

Я также использую HTMLParser и Jericho для задачи извлечения таблицы, которая заменила некоторый код, написанный с использованием Perl libhtml-tableextract-perl . Я использую HTMLParser для фильтрации HTML для таблицы, а затем использую Jericho для его анализа. Я согласен с замечаниями MJB и Адама, что Иерихон хорош в некоторых случаях, потому что он сохраняет основной HTML. Он имеет своего рода нестандартный интерфейс SAX, поэтому для XPath лучше использовать HTMLCleaner.

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

Марк Батлер
источник