Quali sono i pro e i contro dei principali parser HTML Java? [chiuso]


175

Cercando SO e Google, ho scoperto che ci sono alcuni parser Java HTML che sono costantemente raccomandati da varie parti. Purtroppo è difficile trovare informazioni sui punti di forza e di debolezza delle varie biblioteche. Spero che alcune persone abbiano speso un po 'a confrontare queste librerie e possano condividere ciò che hanno imparato.

Ecco cosa ho visto:

E se c'è un grande parser che mi manca, mi piacerebbe anche conoscere i suoi pro e contro.

Grazie!

Risposte:


223

Generale

Quasi tutti i parser HTML conosciuti implementano l' API DOM W3C (parte dell'API JAXP, API Java per l'elaborazione XML) e offrono un org.w3c.dom.Documentdorso pronto per l'uso diretto dall'API JAXP. Le differenze principali si trovano di solito nelle caratteristiche del parser in questione. La maggior parte dei parser è in un certo senso indulgente e indulgente con HTML non ben formato ("tagsoup"), come JTidy , NekoHTML , TagSoup e HtmlCleaner . Solitamente si utilizza questo tipo di parser HTML per "riordinare" l'origine HTML (ad esempio, sostituendo l'HTML valido <br>con un XML valido <br />), in modo da poterlo attraversare "nel solito modo" utilizzando l'API W3C DOM e JAXP.

Gli unici che saltano fuori sono HtmlUnit e Jsoup .

HtmlUnit

HtmlUnit fornisce un'API completamente propria che ti dà la possibilità di agire come un browser web a livello di codice. Vale a dire inserire i valori del modulo, fare clic sugli elementi, richiamare JavaScript, eccetera. È molto più che solo un parser HTML. È un vero "browser Web senza GUI" e uno strumento di test delle unità HTML.

Jsoup

Jsoup fornisce anche un'API completamente propria. Ti dà la possibilità di selezionare elementi usando selettori CSS simili a jQuery e fornisce un'API slick per attraversare l'albero DOM HTML per ottenere gli elementi di interesse.

In particolare, l'attraversamento dell'albero DOM HTML è il principale punto di forza di Jsoup. Chi ha lavorato org.w3c.dom.Documentsa che diavolo di dolore è attraversare il DOM usando il verbose NodeListe le NodeAPI. È vero, XPathrende la vita più semplice, ma è comunque un'altra curva di apprendimento e può finire per essere ancora prolissa.

Ecco un esempio che utilizza un "semplice" parser DOM W3C come JTidy in combinazione con XPath per estrarre il primo paragrafo della tua domanda e i nomi di tutti i risponditori (sto usando XPath poiché senza di esso, il codice necessario per raccogliere le informazioni di interesse altrimenti crescerebbe 10 volte più grande, senza scrivere metodi di utilità / aiuto).

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

Ed ecco un esempio su come fare esattamente lo stesso con 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());
}

Vedi la differenza? Non è solo meno codice, ma Jsoup è anche relativamente facile da capire se hai già una moderata esperienza con i selettori CSS (ad esempio sviluppando siti Web e / o usando jQuery).

Sommario

I pro ei contro di ciascuno dovrebbero essere abbastanza chiari ora. Se vuoi semplicemente usare l'API JAXP standard per attraversarla, scegli il primo gruppo di parser menzionato. Ce ne sono molti . Quale scegliere dipende dalle funzionalità fornite (in che modo la pulizia HTML è resa semplice per te? Ci sono alcuni ascoltatori / intercettori e detergenti specifici per tag?) E la robustezza della libreria (con che frequenza viene aggiornata / mantenuta / riparata? ). Se ti piace testare l'unità HTML, HtmlUnit è la strada da percorrere. Se ti piace estrarre dati specifici dall'HTML (che è più spesso il requisito del mondo reale), allora Jsoup è la strada da percorrere.


C'è un enorme pro / contro che viene omesso qui: Jericho è l'unico parser che conosco che ti consente di manipolare il cattivo HTML pur preservando la formattazione degli spazi bianchi e l'erroneità dell'HTML (se ce ne sono).
Adam Gent,

3
Jsoupè buono. Ho provato a interfacciarlo con un altro modulo che funziona con l' org.w3c.dom.*API. Ho scoperto che Jsoup non obbedisce al org.w3c.dom.*contratto
Thamme Gowda il


7

Aggiungi il validator.nu HTML Parser , un'implementazione dell'algoritmo di analisi HTML5 in Java, al tuo elenco.

Tra i lati positivi, è specificamente progettato per abbinare HTML5 e al centro del validatore HTML5, quindi è molto probabile che corrisponda al comportamento di analisi del browser futuro con un livello di precisione molto elevato.

Sul lato negativo, nessuna analisi legacy dei browser funziona esattamente in questo modo e poiché HTML5 è ancora in bozza, soggetto a modifiche.

In pratica, tali problemi riguardano solo oscuri casi angolari ed è, a tutti gli effetti pratici, un eccellente parser.


7

Ho trovato Jericho HTML Parser molto ben scritto, aggiornato (cosa che molti parser non lo sono), nessuna dipendenza e facile da usare.


6

Aggiungerò semplicemente alla risposta @MJB dopo aver lavorato con la maggior parte delle librerie di analisi HTML in Java, c'è un enorme pro / con che viene omesso: parser che preservano la formattazione e l'erroneità dell'HTML in input e output.

Questo è la maggior parte dei parser quando si modifica il documento spazzerà via lo spazio bianco, i commenti e l'erroneità del DOM, in particolare se si tratta di una libreria simile a XML.

Jericho è l'unico parser che conosco che ti permette di manipolare il cattivo HTML pur preservando la formattazione degli spazi bianchi e l'erroneità dell'HTML (se presente).


3

Altre due opzioni sono HTMLCleaner e HTMLParser .

Ho provato la maggior parte dei parser qui per un framework di estrazione dati / crawler che ho sviluppato. Uso HTMLCleaner per gran parte del lavoro di estrazione dei dati. Questo perché supporta un dialetto ragionevolmente moderno di HTML, XHTML, HTML 5, con spazi dei nomi e supporta DOM, quindi è possibile utilizzarlo con l'implementazione XPath integrata di Java .

È molto più facile farlo con HTMLCleaner rispetto ad alcuni degli altri parser: ad esempio JSoup supporta un'interfaccia simile a DOM, anziché DOM, quindi è necessario un assemblaggio . Jericho ha un'interfaccia SAX-line, quindi è necessario un po 'di lavoro, anche se Sujit Pal ha una buona descrizione di come farlo, ma alla fine HTMLCleaner ha funzionato meglio.

Uso anche HTMLParser e Jericho per un'attività di estrazione di tabelle, che ha sostituito un po 'di codice scritto usando libhtml-tableextract-perl di Perl . Uso HTMLParser per filtrare l'HTML per la tabella, quindi uso Jericho per analizzarlo. Concordo con i commenti di MJB e Adam che Jericho è buono in alcuni casi perché conserva l'HTML sottostante. Ha una sorta di interfaccia SAX non standard, quindi per l'elaborazione XPath HTMLCleaner è migliore.

L'analisi dell'HTML in Java è un problema sorprendentemente difficile in quanto tutti i parser sembrano lottare su alcuni tipi di contenuto HTML non valido.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.