Hier ist der “Groovy Way” um aus einer HTML-Datei Daten zu extrahieren. Als Beispiel sollen alle deutschen Großstädte mit der Einwohnerzahl ausgegeben werden (Wikipedia).
Als Parser bietet Groovy den eingebauten XmlSlurper
an. Dieser funktioniert sehr gut bei XML, aber bei HTML ergeben sich Probleme, z.B. beim Fehlen von schließenden Tags. Lösung ist die Verwendung eines alternativen SAXParsers, der mit HTML richtig umgehen kann (TagSoup). Die Einbindung von TagSoup erfolgt mit @Grab
in der Zeile 1, damit erspart man sich das Herunterladen der Bibliothek. Und in der Zeile 3 wird der alternative SaxParser gesetzt.
Die Zeilen 4 und 5 lesen und parsen die HTML-Datei. Das Lesen der Datei ist hier wegen eines UTF8-Errors etwas umständlich.
Jetzt extrahieren wir die gewünschten Daten (Stadt und Einwohnerzahl). Dazu suchen wir in der Zeile 7 die entsprechende Tabelle, iterieren anschließend über alle Zeilen und holen die Werte aus der zweiten und sechsten Spalte (Zeilen 11 und 12).
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='1.2' ) def slurper = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser()) Reader streamReader = new InputStreamReader( new FileInputStream("index.htm"), "UTF-8") def htmlParser = slurper.parse(streamReader) // parse nimmt auch eine URL def table = htmlParser.'**'.find{ it.name() == 'table' && it.@class == 'wikitable sortable'} table.tr.eachWithIndex { row, rowIdx -> def city, people row.'**'.findAll { it.name() == 'td' }.eachWithIndex { value, index -> if (index == 1) city = value.a.text() if (index == 5) people = Float.valueOf(value.span.text()) as Integer } if (city) println "$city -> $people" }
Als Ergebnis erhalten wir:
... Reutlingen -> 112484 Remscheid -> 110563 Koblenz -> 106417 Bergisch Gladbach -> 105723 Erlangen -> 105629 Moers -> 105506 Trier -> 105260 Jena -> 105129 Siegen -> 103424 Hildesheim -> 102794 Salzgitter -> 102394 Cottbus -> 102091