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

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

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

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

Спасибо!

Ответы

Ответ 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 - это способ пойти.

Ответ 2

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

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

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

Ответ 3

Добавить Validator.nu HTML Parser, реализация алгоритма синтаксического анализа HTML5 в Java, в ваш список.

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

В минусовой стороне не работает аналог анализа браузеров точно так же, как и HTML5 по-прежнему в проекте, могут быть изменены.

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

Два других варианта: HTMLCleaner и HTMLParser.

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

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

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

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