Los selectores de JSoup tienen similitudes con los selectores de JavaScript. Ambos tienen una sintaxis similar y te permiten seleccionar elementos de un documento HTML en función de su nombre de etiqueta, clase, id y propiedades CSS.
Estos son algunos de los principales selectores que puedes utilizar con JSoup:
- getElementsByTag(): Selecciona elementos en función de su nombre de etiqueta.
- getElementsByClass(): Selecciona elementos en función de su nombre de clase.
- getElementById(): Selecciona un elemento en función de su id.
- select(): Selecciona elementos en función de un selector CSS (similar a querySelectorAll)
Ahora utilicemos algunos de ellos para extraer todos los nombres de los equipos:
try {
Document document = Jsoup.connect("https://www.scrapethissite.com/pages/forms/")
.get();
Elements rows = document.getElementsByTag("tr");
for(Element row : rows) {
Elements teamName = row.getElementsByClass("name");
if(teamName.text().compareTo("") != 0)
System.out.println(teamName.text());
}
} catch (IOException e) {
e.printStackTrace();
}
// Prints the team names:
Boston Bruins
Buffalo Sabres
Calgary Flames
Chicago Blackhawks
Detroit Red Wings
Edmonton Oilers
Hartford Whalers
...
Hemos recorrido cada fila y, para cada una, hemos impreso el nombre del equipo utilizando el selector de clase «name».
El último ejemplo destaca la flexibilidad y la capacidad de aplicar métodos de selector varias veces a los elementos que se han extraído. Esto resulta especialmente útil cuando se trabaja con documentos HTML complejos y de gran tamaño.
Aquí hay otra versión que utiliza flujos de Java y el método select() para imprimir todos los nombres de los equipos:
try {
Document document = Jsoup.connect("https://www.scrapethissite.com/pages/forms/")
.get();
Elements teamNamesElements = document.select("table .team .name");
String[] teamNames = teamNamesElements.stream()
.map(element -> element.text())
.toArray(String[]::new);
for (String teamName : teamNames) {
System.out.println(teamName);
}
} catch (IOException e) {
e.printStackTrace();
}
// Also prints the team names:
Boston Bruins
Buffalo Sabres
Calgary Flames
...
Ahora imprimamos todos los encabezados y filas de la tabla:
try {
Document document = Jsoup.connect("https://www.scrapethissite.com/pages/forms/")
.get();
Elements tableHeadersElements = document.select("table th");
Elements tableRowsElements = document.select("table .team");
String[] tableHeaders =
tableHeadersElements.stream()
.map(element -> element.text())
.toArray(String[]::new);
String[][] tableRows =
tableRowsElements.stream()
.map(
table_row -> table_row
.select("td")
.stream()
.map(row_element -> row_element.text())
.toArray(String[]::new)
)
.toArray(String[][]::new);
for (int i = 0; i < tableHeaders.length; i++) {
System.out.print(tableHeaders[i] + " ");
}
for (int i = 0; i < tableRows.length; i++) {
for (int j = 0; j < tableRows[i].length; j++) {
System.out.print(tableRows[i][j] + " ");
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
// Prints
Team Name Year Wins Losses OT Losses Win ...
Boston Bruins 1990 44 24 0.55 299 264 35
Buffalo Sabres 1990 31 30 0.388 292 278 14
Calgary Flames 1990 46 26 0.575 344 263 81
Chicago Blackhawks 1990 49 23 0.613 284 211 73
Detroit Red Wings 1990 34 38 0.425 273 298 -25
...
Fíjate en que hemos utilizado flujos para almacenar las filas. Aquí tienes una forma más sencilla de hacerlo, utilizando bucles «for»:
String[][] tableRows = new String[tableRowsElements.size()][];
for (int i = 0; i < tableRowsElements.size(); i++) {
Element table_row = tableRowsElements.get(i);
Elements tableDataElements = table_row.select("td");
String[] rowData = new String[tableDataElements.size()];
for (int j = 0; j < tableDataElements.size(); j++) {
Element row_element = tableDataElements.get(j);
String text = row_element.text();
rowData[j] = text;
}
tableRows[i] = rowData;
}