Jakie są plusy i minusy wiodących parserów HTML Java? [zamknięte]

Szukając tak i Google, odkryłem, że istnieje kilka parserów HTML Java, które są konsekwentnie zalecane przez różne strony. Niestety trudno znaleźć informacje o mocnych i słabych stronach poszczególnych bibliotek. Mam nadzieję, że niektórzy poświęcili trochę czasu na porównywanie tych bibliotek i mogą podzielić się tym, czego się nauczyli.

Oto co mam widziany:

I jeśli jest jakiś główny parser, który przegapiłem, chciałbym usłyszeć o jego zaletach i wadach.

Dzięki!

Author: skaffman, 2010-06-30

6 answers

Ogólne

Prawie wszystkie znane parsery HTML implementują W3C Dom API (część JAXP API, Java API for XML processing) i daje org.w3c.dom.Document powrót, który jest gotowy do bezpośredniego użycia przez JAXP API. Główne różnice znajdują się zwykle w cechach analizowanego parsera. Większość parserów jest do pewnego stopnia wyrozumiała i pobłażliwa dla nie-dobrze uformowanego HTML ("tagsoup"), jak JTidy, NekoHTML, Tagi i HtmlCleaner . Zazwyczaj używa się tego rodzaju parserów HTML do " uporządkowania "źródła HTML (np. zastąpienia HTML-valid <br> przez XML-valid <br />), tak aby można było przemierzać je" w zwykły sposób " za pomocą W3C DOM i JAXP API.

Jedynymi, które wyskakują są HtmlUnit i Jsoup .

HtmlUnit

HtmlUnit zapewnia całkowicie własne API, które daje możliwość działania jak przeglądarka programowo. Czyli wpisz formularz wartości, kliknij elementy, wywołaj JavaScript, itd. To znacznie więcej niż sam parser HTML. Jest to prawdziwe "narzędzie do testowania stron internetowych bez GUI" i HTML.

Jsoup

Jsoup zapewnia również całkowicie własne API. Daje możliwość wyboru elementów za pomocą jQuery-podobnie jak selektory CSS i zapewnia sprytne API do przemierzania drzewa HTML DOM, aby uzyskać interesujące elementy.

Szczególnie trawersowanie drzewa HTML DOM jest główną siłą Jsoup. Ci, którzy pracowali z org.w3c.dom.Document wiedzą, jaki to ból przemierzać DOM używając verbose NodeList oraz Node APIs. Prawda, XPath ułatwia życie, ale nadal jest to kolejna krzywa uczenia się i może skończyć się nadal gadatliwy.

Oto przykład, który używa "zwykłego" parsera DOM W3C, takiego jak JTidy w połączeniu z XPath, aby wyodrębnić pierwszy akapit twojego pytania i nazwy wszystkich odpowiedzi (używam XPath, ponieważ bez niego kod potrzebny do zebrania interesujących informacji urosłby 10 razy większy, bez pisania narzędzi / metod pomocniczych).

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());
}
A oto przykład jak zrobić dokładnie to samo z 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());
}
Widzisz różnicę? Jest to nie tylko mniej kodu, ale Jsoup jest również stosunkowo łatwy do opanowania, jeśli masz już umiarkowane doświadczenie z selektorami CSS (np. poprzez tworzenie stron internetowych i / lub używanie jQuery).

Podsumowanie

Plusy i minusy każdego z nich powinny być już wystarczająco jasne. Jeśli po prostu chcesz użyć standardowego API JAXP, przejdź do pierwszej wspomnianej grupy parserów. Jest ich bardzo dużo. Który z nich wybrać zależy od funkcji, które zapewnia (w jaki sposób czyszczenie HTML jest dla ciebie łatwe? czy są jakieś słuchacze / przechwytywacze i środki czyszczące specyficzne dla tagów?) i solidność biblioteki (jak często jest aktualizowana/utrzymywana/naprawiana?). Jeśli chcesz przetestować HTML, a następnie HtmlUnit jest droga do zrobienia. Jeśli chcesz wyodrębnić określone dane z HTML (co jest bardziej niż często wymaganiem w świecie rzeczywistym), Jsoup jest dobrym rozwiązaniem.

 216
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-28 11:24:16

Ten artykuł porównuje niektóre aspekty następujących parserów:

  • NekoHTML
  • JTidy
  • Tagi
  • HtmlCleaner

W żadnym wypadku nie jest to pełne podsumowanie, A jest z 2008 roku. Ale może Ci to pomóc.

 13
Author: Matt Solnit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-07 05:32:27

Dodaj The validator.nu HTML Parser, implementacja algorytmu parsowania HTML5 w Javie, do twojej listy.

Na plus, jest specjalnie zaprojektowany, aby dopasować HTML5, a w sercu walidatora HTML5, więc bardzo prawdopodobne, aby dopasować zachowanie parsowania przyszłej przeglądarki z bardzo wysokim stopniem dokładności.

Po stronie minusowej, Żadna spuścizna przeglądarek nie działa dokładnie tak, a HTML5 jest nadal w wersji roboczej, może ulec zmianie.

W praktyce takie problemy dotyczą tylko niejasnych przypadków narożnych i jest dla wszystkich praktycznych celów doskonałym parserem.

 7
Author: Alohci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-30 18:39:53

Znalazłem Jericho parser HTML jest bardzo dobrze napisany, aktualizowany (czego wiele parserów nie jest), bez zależności i łatwy w użyciu.

 7
Author: MJB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 17:25:18

Dodam do @MJB odpowiedź po pracy z większością bibliotek parsowania HTML w Javie, jest ogromny pro/con, który jest pominięty: parsery, które zachowują formatowanie i niepoprawność HTML na wejściu i wyjściu.

To jest większość parserów po zmianie dokumentu zdmuchnie białe znaki, komentarze i niepoprawność DOM, szczególnie jeśli są biblioteką podobną do XML.

Jericho jest jedynym parserem, który pozwala na manipulowanie paskudny HTML, zachowując formatowanie białych znaków i niepoprawność HTML (jeśli istnieje).

 6
Author: Adam Gent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-03 14:38:08

Dwie inne opcje to HTMLCleaner i HTMLParser .

Wypróbowałem większość parserów tutaj dla ramki crawler / data extraction, które opracowałem. Używam HTMLCleaner do większości prac ekstrakcji danych. Jest to spowodowane tym, że obsługuje dość nowoczesny dialekt HTML, XHTML, HTML 5, z przestrzeniami nazw i obsługuje DOM, więc możliwe jest używać go z wbudowaną w Javę implementacją XPath .

O wiele łatwiej jest to zrobić z HTMLCleaner niż niektóre inne parsery: na przykład jsoup obsługuje interfejs podobny do DOM, a nie DOM, więc wymagany jest montaż. Jericho ma interfejs SAX-line, więc znowu wymaga trochę pracy, chociaż Sujit Pal ma dobry opis jak to zrobić ale w końcu HTMLCleaner po prostu działał lepiej.

Używam również HTMLParser i Jericho do zadania ekstrakcji tabeli, które zastąpiło jakiś kod napisany przy użyciu libhtml-tableextract-perl. Używam HTMLParser filtruje HTML dla tabeli, a następnie używa Jericho do jej analizy. Zgadzam się z komentarzami MJB i Adama, że Jericho jest dobre w niektórych przypadkach, ponieważ zachowuje podstawowy HTML. Ma rodzaj niestandardowego interfejsu SAX, więc dla przetwarzania XPath HTMLCleaner jest lepszy.

Parsowanie HTML w Javie jest zaskakująco trudnym problemem, ponieważ wszystkie parsery wydają się zmagać z pewnymi rodzajami zniekształconych treści HTML.

 3
Author: Mark Butler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:25