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.Document
dorso 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.Document
sa che diavolo di dolore è attraversare il DOM usando il verbose NodeList
e le Node
API. È vero, XPath
rende 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.