Os seletores no JSoup têm semelhanças com os seletores em JavaScript. Ambos têm uma sintaxe semelhante e permitem-lhe selecionar elementos de um documento HTML com base no nome da tag, classe, id e propriedades CSS.
Aqui estão alguns dos principais seletores que pode utilizar com o JSoup:
- getElementsByTag(): Seleciona elementos com base no nome da sua tag.
- getElementsByClass(): Seleciona elementos com base no nome da sua classe.
- getElementById(): Seleciona um elemento com base no seu id.
- select(): Seleciona elementos com base num seletor CSS (semelhante ao querySelectorAll)
Agora vamos usar alguns deles para extrair todos os nomes das equipas:
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
...
Percorremos todas as linhas e, para cada uma, exibimos o nome da equipa utilizando o seletor de classe «name».
O último exemplo destaca a flexibilidade e a capacidade de aplicar métodos de seleção várias vezes nos elementos que foram extraídos. Isto é particularmente útil ao lidar com documentos HTML complexos e de grande dimensão.
Eis outra versão que utiliza fluxos Java e o método select() para imprimir todos os nomes das equipas:
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
...
Agora vamos imprimir todos os cabeçalhos e linhas da tabela:
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
...
Repare que utilizámos streams para armazenar as linhas. Aqui está uma forma mais simples de o fazer, utilizando loops 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;
}