HtmlUnit è un framework che affonda le sue radici in JUnit, un framework per i test di unità per linguaggio Java. L‘esperienza con JUnit è risultata fondamentale per far crescere la metodologia di “sviluppo guidato dai test”, utilissima in fase di progettazione e di implementazione.
Introduzione
Negli ultimi anni abbiamo assistito a una forte espansione del web e delle informazioni in esso contenute. Gli utenti utilizzano quindi il web come una fonte inesauribile di informazioni, dal quale estrarre solo quelle di interesse specifico: infatti le informazioni presenti spaziano su numerosi argomenti e presentano diversi gradi di rilevanza ai fini della ricerca dell’utente. In particolare, alcune di queste informazioni vengono classificate in letteratura come informazioni “rumorose” [1]: con questa accezione si intendono quelle informazioni che non sono pertinenti con il contenuto informativo della pagina web, ma si traducono infatti in banner pubblicitari, intestazioni e note a piè di pagina, plug-in e altro ancora. Questo tipo di “rumore” è presente ovunque nel web, in quanto produce vantaggi economici per fornitori di servizi web, aziende pubblicitarie e sponsor in genere. Purtroppo, però, il rumore si distanzia molto da ciò che l’utente cerca nel web e spesso costituisce addirittura fattori di disturbo alla navigazione lineare.
Inoltre, c’è da considerare che la sempre crescente espansione del web ha reso necessaria l’ideazione di uno strumento capace di reperire informazioni selezionate in relazione alla pertinenza con l’argomento di ricerca delle informazioni: un sistema di questo genere presenterebbe, quindi, importanti problemi di prestazioni in termini di “precision” e “recall” [1] nel caso in cui dovesse memorizzare intere pagine web, comprensive di tutto il rumore che hanno incorporato.
La soluzione a questo problema è stata proposta negli ultimi anni attraverso lo sviluppo di processi basati sulla suddivisione delle pagine web in blocchi semanticamente omogenei, eliminando quindi quelli di più bassa pertinenza.
Questo compito risulta, però, non troppo semplice da mettere in pratica, proprio perchè le pagine web sono pensate, e quindi strutturate, per il consumo da parte di utenti umani attraverso l’utilizzo di browser web: per questo motivo, risultano spesso difficilmente processabili da programmi che girano su calcolatori. Un apporto importante al corretto funzionamento di questi strumenti, quindi, sarebbe l’estrazione e la conservazione in locale delle informazioni reperite, in modo da elaborarle e analizzare, per poi riproporle, integrandole magari con altre informazioni: ma non sempre queste operazioni risultano fattibili.
Gli strumenti utilizzati per l’estrazione delle informazioni dal web vengono chiamati wrapper (si veda in particolare [3] e [4]): il loro lavoro consiste nella suddivisione della pagina web basandosi sulla costruzione di una sua rappresentazione ad albero DOM (Documet Object Model), come rappresentato in figura 1
Figura 1 – Esempio di costruzione di albero DOM di una generica pagina web partendo dai tag HTML
In particolare, essi svolgono in sequenza i seguenti compiti:
- effettuano il parsing di una pagina web (X/HTML), laddove il parser è uno strumento in grado di interpretare un particolare linguaggio (in questo caso X/HTML) e individuare le informazioni in esso contenute;
- estraggono i dati di interesse;
- riversano i dati in un altro formato elettronico (XML, RDBMS, etc.).
Come visibile nell’esempio della figura 1, l’albero DOM fa riferimento alla struttura sintattica della pagina HTML e cerca quindi di identificare i vari sotto-alberi facendo riferimento ai tag più usati come
Vorremmo che il test verifichi la creazione dei cinque campi di testo; segue il codice implementato attraverso HtmlUnit che risolve il problema posto.
public void testDocumentWrite() throws Exception { final WebClient webClient = new WebClient(); final HtmlPage page = (HtmlPage)webClient.getPage( new URL( "http://myserver/test.html" ) ); final HtmlForm form = page.getFormByName("form1"); for( int i=1; i<= 5; i++ ) { final String expectedName = "textfield"+i; assertEquals( "text", form.getInputByName(expectedName).getTypeAttribute()); } }
Vediamo ora come effettuare il parsing di una pagina web contenente una tabella. Negli esempi che seguono faremo riferimento alla seguente pagina HTML.
Numero | Descrizione |
---|---|
1 | Bicicletta |
Il frammento di codice che segue mostra come iterare fra le righe e le celle:
final HtmlTable table = (HtmlTable)page.getHtmlElementById("table1"); final List rows = table.getRows(); for (final Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) { final HtmlTableRow row = (HtmlTableRow) rowIterator.next(); System.out.println("Trovata una riga"); final List cells = row.getCells(); for (final Iterator cellIterator = cells.iterator(); cellIterator.hasNext();) { final HtmlTableCell cell = (HtmlTableCell) cellIterator.next(); System.out.println(" Trovata una cella: " + cell.asText()); } }
Il codice di esempio che segue mostra come accedere a una specifica cella attraverso numero di riga e colonna.
final WebClient webClient = new WebClient(); final HtmlPage page = (HtmlPage)webClient.getPage( new URL("http://foo.com") ); final HtmlTable table = (HtmlTable)page.getHtmlElementById("table1"); System.out.println( "Cell (1,2)="+ table.getCellAt(1,2);
Conclusioni
In questo primo articolo è stata presentata una breve panoramica sulla teoria dell’estrazione delle informazioni e del testing di applicazioni web-oriented. Abbiamo infine imparato a utilizzare il framework HtmlUnit attraverso degli esempi di difficoltà crescente. Per ulteriori approfondimenti si rimanda alla bibliografia a corredo, soprattutto alla documentazione presente sul sito web ufficiale del progetto [2].
Riferimenti
[1] C. Biancalana – F. Gasparetti – A. Micarelli, “Intelligent Search on the Internet”, in O. Stock – M. Schaerf (eds.), “Reasoning, Action and Interaction in AI Theories and Systems”, LNAI Festschrift Volume 4155 of the Lecture Notes in Computer Science series, Springer, Berlin, 2006.
[2] HtmlUnit
http://htmlunit.sourceforge.net/
[3] Lang Yi – Bing Liu – Xiaoli Li, “Eliminating Noisy Information in Web Pages for Data Mining”. SIGKDD ’03, August 24-27, 2003. ACM, 2003.
[4] Sandip Debnath – Prasenjit Mitra – C. Lee Giles, “Automatic Extraction of Informative Blocks from Webpages”. SAC ’05, March 13-17, 2005, Santa Fe, New Mexico, USA. ACM, 2005.