web-dev-qa-db-fra.com

Quels sont les avantages et les inconvénients des principaux analyseurs HTML Java HTML?)?

Recherche SO et Google, j'ai constaté qu'il existe quelques analyseurs syntaxiques Java qui sont systématiquement recommandés par différentes parties. Malheureusement, il est difficile de trouver des informations. J'espère que certaines personnes auront passé du temps à comparer ces bibliothèques et pourront partager ce qu'elles ont appris.

Voici ce que j'ai vu:

Et s'il y a un analyseur principal qui m'a manqué, j'aimerais aussi connaître ses avantages et ses inconvénients.

Merci!

173
Avi Flax

Général

Presque tous les analyseurs HTML connus implémentent le API DOM W3C (une partie de l'API JAXP, Java pour le traitement XML) et vous donne un org.w3c.dom.Document retour prêt à être utilisé directement par l'API JAXP Les différences majeures se trouvent généralement dans les fonctionnalités de l'analyseur en question. "tagsoup"), comme JTidy , NekoHTML , TagSoup et HtmlCleaner . Vous utilisez habituellement ce type d'analyseurs HTML. pour "ranger" la source HTML (par exemple, remplacer le <br> valide par HTML par un <br /> valide par XML, afin que vous puissiez le parcourir "de manière habituelle" à l'aide des DOM W3C et JAXP API.

Les seuls qui sortent sont HtmlUnit et Jsoup .

HtmlUnit

HtmlUnit fournit une API complètement propre qui vous donne la possibilité d'agir comme un navigateur Web par programme. C'est à dire. entrez des valeurs de formulaire, cliquez sur des éléments, appelez JavaScript, etc. C'est beaucoup plus que seul un analyseur HTML. C'est un véritable "navigateur Web sans interface graphique" et un outil de test d'unité HTML.

Jsoup

Jsoup fournit également une API totalement propre. Il vous donne la possibilité de sélectionner des éléments en utilisant jQuery - comme sélecteurs CSS et fournit une API simple pour parcourir l'arborescence DOM HTML afin d'obtenir les éléments qui vous intéressent.

La traversée de l’arbre HTML HTML est la principale force de Jsoup. Ceux qui ont travaillé avec org.w3c.dom.Document Savent à quel point il est très pénible de parcourir le DOM en utilisant le verbose NodeList et Node API. Certes, XPath facilite la vie, mais c’est quand même une autre courbe d’apprentissage qui peut finir par être encore prolixe.

Voici un exemple qui utilise un analyseur DOM "simple" du DOM W3C comme JTidy en combinaison avec XPath pour extraire le premier paragraphe de votre question et les noms de tous les répondants (j'utilise XPath car sans lui, le code nécessaire pour collecter les informations d'intérêt autrement grossirait 10 fois plus gros, sans écrire des méthodes utilitaire/auxiliaire).

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());
}

Et voici un exemple comment faire exactement la même chose avec 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());
}

Voyez-vous la différence? Ce n'est pas seulement moins de code, mais Jsoup est également relativement facile à comprendre si vous avez déjà une expérience modérée des sélecteurs CSS (en développant par exemple des sites Web et/ou en utilisant jQuery).

Sommaire

Les avantages et les inconvénients de chacun devraient être suffisamment clairs maintenant. Si vous souhaitez simplement utiliser l'API JAXP standard pour le parcourir, optez pour le premier groupe d'analyseurs. Il y a de jolis beaucoup d'entre eux. Laquelle choisir dépend des fonctionnalités fournies (comment vous faciliter le nettoyage HTML? Y a-t-il des écouteurs/intercepteurs et des nettoyeurs spécifiques aux balises?) Et de la robustesse de la bibliothèque (à quelle fréquence est-elle mise à jour/maintenue/corrigée?) ). Si vous aimez tester le code HTML, alors HtmlUnit est la solution. Si vous souhaitez extraire des données spécifiques du code HTML (ce qui est souvent l'exigence du monde réel), alors Jsoup est la solution.

221
BalusC

Cet article compare certains aspects des analyseurs syntaxiques suivants:

  • NekoHTML
  • Jidid
  • TagSoup
  • HtmlCleaner

Il ne s’agit nullement d’un résumé complet, et il date de 2008. Mais vous le trouverez peut-être utile.

13
Matt Solnit

J'ai trouvé que Jericho HTML Parser était très bien écrit, mis à jour (ce que beaucoup d’analyseurs ne le sont pas), pas de dépendances et facile à utiliser.

7
MJB

Ajoutez l’analyseur HTML validator.nu HTML , une implémentation de l’algorithme d’analyse HTML5 en Java, à votre liste.

Sur le plan positif, il est spécifiquement conçu pour correspondre à HTML5 et au cœur du validateur HTML5, de sorte qu'il est très probable que le comportement d'analyse du futur navigateur corresponde à un très haut degré de précision.

Sur le plan négatif, l'analyse classique des navigateurs ne fonctionne pas exactement de la même manière, et HTML5 est toujours en mode brouillon, sous réserve de modification.

En pratique, ces problèmes ne concernent que des cas obscurs et constituent, à toutes fins utiles, un excellent analyseur.

7
Alohci

J'ajouterai simplement à la réponse @MJB après avoir utilisé la plupart des bibliothèques d'analyse HTML en Java: il existe un énorme avantage/inconvénient omis: des analyseurs qui préservent la mise en forme et le caractère incorrect du code HTML en entrée et en sortie.

La plupart des analyseurs lorsque vous modifiez le document suppriment les espaces, les commentaires et l'inexactitude du DOM, en particulier s'il s'agit d'une bibliothèque de type XML.

Jericho est le seul analyseur que je connaisse qui vous permette de manipuler du mauvais HTML tout en préservant la mise en forme des espaces et le caractère incorrect du HTML ( s'il y en a).

6
Adam Gent

Deux autres options sont HTMLCleaner et HTMLParser .

J'ai essayé la plupart des analyseurs ici pour un framework d'extraction de données/crawler que je développais. J'utilise HTMLCleaner pour l'essentiel du travail d'extraction de données. En effet, il prend en charge un dialecte raisonnablement moderne: HTML, XHTML, HTML 5, avec des espaces de noms, et prend en charge DOM. Il est donc possible de tilisez-le avec l'implémentation XPath intégrée de Java .

C’est beaucoup plus facile de faire cela avec HTMLCleaner que certains des autres parseurs: JSoup, par exemple, supporte une interface de type DOM plutôt que DOM, donc un certain assemblage requis Jericho a une interface SAX-line donc encore une fois, il nécessite un peu de travail bien que Sujit Pal a une bonne description de la marche à suivre mais à la fin, HTMLCleaner fonctionnait mieux.

J'utilise également HTMLParser et Jericho pour une tâche d'extraction de table, qui a remplacé du code écrit à l'aide de Perl libhtml-tableextract-Perl . J'utilise HTMLParser pour filtrer le code HTML de la table, puis Jericho pour l'analyser. Je suis d'accord avec les commentaires de MJB et Adam selon lesquels Jericho est bon dans certains cas, car il préserve le code HTML sous-jacent. Il possède une sorte d’interface SAX non standard, donc mieux vaut utiliser HTMLCleaner pour le traitement XPath.

L'analyse HTML dans Java est un problème étonnamment difficile, car tous les analyseurs semblent avoir du mal à obtenir certains types de contenu HTML mal formé.

3
Mark Butler