Jsoup è parser HTML5 (conforme alle specifiche WHATWG) le cui API consentono di estrarre dati e manipolare in maniera estremamente semplice documenti sfruttando le potenzialità di DOM, CSS e metodi di accesso simili a quelli offerti da JQuery.
Accedere a documenti HTML
In Jsoup un documento xml è rappresentato dalla classe Document
, i nodi del documento da istanze della classe Node
e i tag da istanze della classe Element
Esistono tre diversi modi per effettuare il parsing di un documento xml ed ottenere così un Document che lo rappresenti:
- caricare il documento da un URL
- caricare il documento da un File
- effettuare il parsing di una String rappresentante il contenuto del documento xml o una parte di questo
Nel primo caso si utilizza il metodo connect della classe Jsoup:
Document doc = Jsoup.connect("http://html.it/").get();
Nel secondo caso si utilizza il metodo parse della classe Jsoup
File input = new File("documento.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://html.it/");
Nel terzo caso si utilizza il metodo parse della classe Jsoup passando una String rappresentante il contenuto del documento, e il base-uri:
String html = "<html> <head> <title> Documento di prova </title> </head> <body> Corpo del body </body> </html>";
Document doc = Jsoup.parse(html, "http://html.it/");
E' possibile effettuare anche il parsing di un frammento di codice HTML mediante il metodo parseBodyFragment
String html = "<div> DIV inserito </div>";
Document doc = Jsoup.parseBodyFragment(html);
Element body = doc.body();
quest'ultimo metodo risulta particolarmente interessante quando si ha la necessità di navigare una parte dell'interno albero HTML senza voler tuttavia caricare tutto il documento all'interno della memoria.
Navigare un documento HTML
Una volta ottenuta l'istanza della classe Document
è possibile procedere alla navigazione del documento sfruttando diversi metodi.
Supponiamo di utilizzare il seguente codice HTML:
<html>
<head>
<title>
Documento HTML di prova
</title>
</head>
<body>
<div> div 1 </div>
<div id="div_2"> div 2 </div>
<div> div 3 </div>
</body>
</html>
E di aver effettuato il parsing del documento HTML in uno dei modi che abbiamo precedentemente illustrato.
A questo punto, per accedere al title del documento si utilizza il metodo title()
del Document
, per cui:
System.out.println(document.title());
Produce in output:
Per accedere al body del documento, si usa invece il metodo body()
Document
In particolare:
per recuperare l'elemento-figlio i-esimo di un altro si usa il metodo child(int index):
Element figlio = document.body().child(0);
per recuperare l'elemento adiacente successivo o precedente ad un dato elemento si usano i metodi nextElementSibling()
previousElementSibling()
Element
Element primo_figlio = documento.body().child(0);
while (primo_figlio.nextElementSibling()!=null)
{
System.out.println(primo_figlio);
primo_figlio = primo_figlio.nextElementSibling();
}
System.out.println(primo_figlio);
Per recuperare tutti gli elementi di un dato tag si usa getElementsByTag()
Elements elementi_div = document.getElementsByTag(“div”);
come risultato si ottiene un oggetto Elements
Element
per recuperare un elemento a partire dall'id si usa il metodo getElementById()
Element div2 = document.getElementById(“div_2”);
Jsoup
Elements elementi = documento.body().getElementsByAttribute("id");
for (Element elemento: elementi)
System.out.println(elemento);
o che abbiamo un dato attributo valorizzato in un modo ben preciso:
Elements elementi = documento.body().getElementsByAttributeValue("id",”div_2”);
for (Element elemento: elementi)
System.out.println(elemento);
Per recuperare l'Element
Element
parent()
Element padre = figlio.parent();
Questi sono i principali modi per accedere agli Element
Document
Se si vuole accedere agli attributi di un Element
attributes()
Attributes attributi = element.attributes();
attr()
Attribute attributo = element.attr(“id”);
Utilizzo dei selettori
Accanto ai metodi tradizionali per l'accesso agli elementi di un documento html, Jsoup introduce uno strumento molto potente per recuperare uno o più elementi attraverso l'uso di selettori.
Un selettore è un'espressione che individua un sottoinsieme degli elementi presenti in un documento.
Una volta definito il selettore è possibile utilizzare il metodo select(String selettore)
di un Element
per selezionare gli elementi individuati dal selettore ottenendo come risultato una collection Elements
.
Il selettore viene costruito considerando che:
"nometag"
: recupera tutti gli elementi che hanno il tag nometag
body.select(“div”)
"#id"
: recupera l'elemento che ha il dato id
body.select(“#div_2”);
".nomeclasse"
: recupera gli elementi che hanno come classe css nome classe
body.select(“.rosso”);
"[nome attributo]"
: recupera gli elementi che hanno l'attributo specificato
body.select(”[id]”)
"[nome_attributo=valore_attributo]"
: recupera gli elementi che hanno per l'attributo indicato il valore indicato
Body.select(“[id=div_2]”);
Ovviamente è possibile utilizzare un selettore composto da una o più delle precedenti regole.
Ad esempio supponendo di voler recuperare tutti gli elementi con tag div e classe css rosso, utilizzeremo il selettore:
Modifica dei contenuti di un documento HTML
Accanto ai metodi per selezionare e navigare gli elementi di un documento xml Jsoup mette a disposizione un insieme di metodi per manipolarne il contenuto.
html(String html)
: modifica l'Element
sostituendolo con il codice passato come argomento.
element.html(“<p>paragrafo</p>”);
prepend(String html)
Element
element.prepend(“<p>paragrafo iniziale</p>”);
append(String html)
Element
element.append(“<p>paragrafo finale</p>”);
Per modificare gli attributi di un Element
element.attr(“class”,”rosso”);
e poi?
Ovviamente lo scopo di questa brevissima introduzione era soltanto quello di offrire una idea generale delle possibilità di utilizzo di questa libreria, le cui possibilità di utilizzo possono spaziare dai consueti contesti web a contesti meno ovvi, come la produzione di pdf/ebook, ad esempio, grazie ad una modalità di programmazione molto intuitiva.