JSoup : Analyse HTML en Java

Mihai Maxim le 31 janvier 2023

blog-image

Présentation de JSoup

Le web scraping peut être considéré comme une chasse au trésor numérique. Vous parcourez un site web et en tirez toutes les informations dont vous avez besoin. Cette technique est utilisée pour toutes sortes de choses, comme la recherche des prix les plus bas, l'analyse des sentiments des clients ou la collecte de données pour la recherche.

Java est considéré comme un langage de programmation idéal pour le web scraping car il dispose d'une grande variété de bibliothèques et de frameworks qui peuvent faciliter le processus. L'une des bibliothèques les plus connues pour le web scraping en Java est JSoup. JSoup vous permet de naviguer et de rechercher dans le code HTML d'un site web et d'en extraire toutes les données dont vous avez besoin.

En combinant Java et JSoup, vous pouvez créer des applications de web scraping géniales qui peuvent extraire des données de sites web rapidement et facilement. Dans cet article, je vais vous présenter les bases du web scraping avec JSoup.

Mise en place d'un projet JSoup

Dans cette section, nous allons créer un nouveau projet Java avec Maven et le configurer pour qu'il s'exécute à partir de la ligne de commande à l'aide du plugin exec-maven. Cela vous permettra d'empaqueter et d'exécuter facilement votre projet sur un serveur, ce qui favorisera l'automatisation et l'extensibilité du processus d'extraction de données. Ensuite, nous allons installer la bibliothèque JSoup.

Création d'un projet Maven

Maven est un outil d'automatisation de la construction pour les projets Java. Il gère les dépendances, les constructions et la documentation, ce qui facilite la gestion de projets Java complexes. Avec Maven, vous pouvez facilement gérer et organiser le processus de construction, les dépendances et la documentation de votre projet. Il permet également une intégration facile avec des outils et des cadres de travail.

L'installation de Maven est un processus simple qui peut être réalisé en quelques étapes.

Tout d'abord, téléchargez la dernière version de Maven depuis le site officiel(https://maven.apache.org/download.cgi).

Une fois le téléchargement terminé, extrayez le contenu de l'archive dans un répertoire de votre choix.

Ensuite, vous devez configurer les variables d'environnement.

Sous Windows, définissez la variable JAVA_HOME à l'emplacement de votre JDK et ajoutez le dossier bin de l'installation Maven à la variable PATH.

Sous Linux/macOS, vous devez ajouter les lignes suivantes à votre fichier ~/.bashrc ou ~/.bash_profile :

export JAVA_HOME=chemin/vers/le/jdk

export PATH=$PATH:chemin/vers/maven/bin

Confirmez l'installation de Maven en exécutant mvn --version dans un terminal.

Une fois Maven installé, vous pouvez créer un nouveau projet Java Maven :

 mvn archetype:generate -DgroupId=com.project.scraper 

-DartifactId=jsoup-scraper-project

-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Cela crée un nouveau dossier appelé "jsoup-scraper-project" contenant le contenu du projet.

Le point d'entrée de l'application (la classe principale) se trouve dans le paquet "com.project.scraper".

Exécution du projet à partir de la ligne de commande

Pour exécuter un projet Java Maven à partir de la ligne de commande, nous utiliserons le plugin exec-maven.

To install the plugin, you need to add it to the project's pom.xml file. This can be done by adding the following code snippet to the <build><plugins> section of the pom.xml file:

<build>

<plugins>

<plugin>

<groupId>org.codehaus.mojo</groupId>

<artifactId>exec-maven-plugin</artifactId>

<version>3.1.0</version>

<executions>

<execution>

<goals>

<goal>java</goal>

</goals>

</execution>

</executions>

<configuration>

<mainClass>com.project.scraper.App</mainClass>

</configuration>

</plugin>

</plugins>

</build>

Veillez à sélectionner le bon chemin pour la classe principale du projet.

Utilisez mvn package exec:java dans le terminal (dans le répertoire du projet) pour exécuter le projet.

Installation de la bibliothèque JSoup

Pour installer la bibliothèque JSoup, ajoutez la dépendance suivante au fichier pom.xml de votre projet :

<dependency>

<groupId>org.jsoup</groupId>

<artifactId>jsoup</artifactId>

<version>1.14.3</version>

</dependency>

Visitez le site https://mvnrepository.com/artifact/org.jsoup/jsoup pour vérifier la dernière version.

Analyse du code HTML en Java avec JSoup

Dans cette section, nous allons explorer le site web https://www.scrapethissite.com/pages/forms/ et voir comment nous pouvons extraire les informations sur les équipes de hockey. En examinant un site web réel, vous comprendrez les concepts et les techniques utilisés dans le web scraping avec JSoup et comment vous pouvez les appliquer à vos propres projets.

Récupérer le HTML

Pour obtenir le code HTML d'un site web, vous devez lui adresser une requête HTTP. Dans JSoup, la méthode connect() est utilisée pour créer une connexion à une URL spécifiée. Elle renvoie un objet Connexion, qui peut être utilisé pour configurer la requête et récupérer la réponse du serveur.

Voyons comment nous pouvons utiliser la méthode connect() pour récupérer le code HTML de notre URL et l'écrire dans un fichier HTML local (hockey.html) :

package com.project.scraper;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import java.io.*;

import java.io.IOException;

public class App

{

public static void main( String[] args )

{

String RAW_HTML;

try {

Document document = Jsoup.connect("https://www.scrapethissite.com/pages/forms/")

.get();

RAW_HTML = document.html();

FileWriter writer = new FileWriter("hockey.html");

writer.write(RAW_HTML);

writer.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

Nous pouvons maintenant ouvrir le fichier et examiner la structure du HTML à l'aide des outils de développement :

blog-image

Les données dont nous avons besoin se trouvent dans un tableau HTML sur la page. Maintenant que nous avons accédé à la page, nous pouvons extraire le contenu du tableau à l'aide de sélecteurs.

Rédaction de sélecteurs

Les sélecteurs de JSoup présentent des similitudes avec les sélecteurs de JavaScript. Ils ont tous deux une syntaxe similaire et permettent de sélectionner des éléments dans un document HTML en fonction de leur nom de balise, de leur classe, de leur identifiant et de leurs propriétés CSS.

Voici quelques-uns des principaux sélecteurs que vous pouvez utiliser avec JSoup :

  • getElementsByTag() : Sélectionne les éléments en fonction de leur nom de balise.
  • getElementsByClass() : Sélectionne les éléments en fonction de leur nom de classe.
  • getElementById() : Sélectionne un élément sur la base de son identifiant.
  • select() : Sélectionne les éléments sur la base d'un sélecteur CSS (similaire à querySelectorAll)

Utilisons-en quelques-uns pour extraire tous les noms d'équipes :

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

...

Nous avons itéré sur chaque ligne, et pour chacune d'entre elles, nous avons imprimé le nom de l'équipe à l'aide du sélecteur de classe "name".

Le dernier exemple met l'accent sur la flexibilité et la possibilité d'appliquer les méthodes de sélection plusieurs fois sur les éléments qui ont été extraits. Ceci est particulièrement utile lorsqu'il s'agit de documents HTML complexes et volumineux.

Voici une autre version qui utilise les flux Java et la méthode select() pour imprimer tous les noms des équipes :

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

...

Imprimons maintenant tous les en-têtes et toutes les lignes du tableau :

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

...

Remarquez que nous avons utilisé des flux pour stocker les rangées. Voici une façon plus simple de procéder, en utilisant des boucles 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;

}

Gestion de la pagination

Lors de l'extraction de données d'un site web, il est fréquent que les informations soient réparties sur plusieurs pages. Afin de récupérer toutes les données pertinentes, il est nécessaire d'envoyer des requêtes à chaque page du site web et d'extraire les informations de chacune d'entre elles. Nous pouvons facilement mettre en œuvre cette fonctionnalité dans notre projet.

blog-image

Tout ce que nous avons à faire, c'est de modifier le paramètre de requête page_num dans l'URL et d'effectuer une autre requête HTTP à l'aide de la méthode connect().

int pageLimit = 25;

String [] tableHeaders = new String[0];

Vector<String[][]> rowsGroups = new Vector<String [][]>();

for (int currentPage=1; currentPage<pageLimit; currentPage++) {

try {

Document document = Jsoup.connect("https://www.scrapethissite.com/pages/forms/?page_num=" + currentPage)

.get();

if(currentPage == 1) {

Elements tableHeadersElements = document.select("table th");

tableHeaders = tableHeadersElements.stream()

.map(element -> element.text())

.toArray(String[]::new);

}

Elements tableRowsElements = document.select("table .team");

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;

}

rowsGroups.add(tableRows);

} catch (IOException e) {

e.printStackTrace();

}

// do something with the headers and the the table rows groups

}

Comme les tableaux de chaque page ont les mêmes en-têtes, vous devez vous assurer de ne pas les récupérer plusieurs fois.

Le code complet

Voici le code complet qui extrait tous les tableaux du site web https://www.scrapethissite.com/pages/forms/. J'ai également inclus une fonction qui enregistre les données au format .CSV :

package com.project.scraper;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.nodes.Element;

import org.jsoup.select.Elements;

import java.io.*;

import java.io.IOException;

import java.util.Vector;

public class App

{

public static void main( String[] args )

{

int pageLimit = 25;

String [] tableHeaders = new String[0];

Vector<String[][]> rowsGroups = new Vector<String [][]>();

for (int currentPage=1; currentPage<pageLimit; currentPage++) {

try {

Document document = Jsoup.connect("https://www.scrapethissite.com/pages/forms/?page_num=" + currentPage)

.get();

if(currentPage == 1) {

Elements tableHeadersElements = document.select("table th");

tableHeaders = tableHeadersElements.stream()

.map(element -> element.text())

.toArray(String[]::new);

}

Elements tableRowsElements = document.select("table .team");

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;

}

rowsGroups.add(tableRows);

} catch (IOException e) {

e.printStackTrace();

}

}

writeFullTableToCSV(rowsGroups, tableHeaders, "full_table.csv");

}

public static void writeFullTableToCSV(Vector<String[][]> rowsGroups, String[] headers, String fileName) {

File file = new File(fileName);

try {

FileWriter writer = new FileWriter(file);

// write the headers first

for (int i = 0; i < headers.length; i++) {

writer.append(headers[i]);

if (i != headers.length - 1) {

writer.append(",");

}

}

writer.append("\n");

// write all the rows groups

for (String [][] rowsGroup : rowsGroups) {

for (String[] row : rowsGroup) {

for (int i = 0; i < row.length; i++) {

writer.append(row[i]);

if (i != row.length - 1) {

writer.append(",");

}

}

writer.append("\n");

}

}

writer.flush();

writer.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

Conclusion

Dans cet article, nous avons vu comment installer Maven et créer un nouveau projet Java Maven, ainsi que comment exécuter le projet à partir de la ligne de commande. Nous avons également expliqué comment installer la bibliothèque JSoup en ajoutant la dépendance au fichier pom.xml du projet. Enfin, nous avons présenté un exemple d'utilisation de JSoup pour analyser le code HTML et extraire des données d'un site web. En suivant les étapes décrites dans cet article, vous devriez avoir une base solide pour mettre en place un projet JSoup et commencer à extraire des données de sites web. JSoup offre un large éventail d'options et de possibilités pour le web scraping et je vous encourage à les explorer et à les appliquer à vos propres projets.

Comme vous l'avez vu, les données sont souvent partagées entre plusieurs pages web. Le fait d'effectuer des requêtes rapides vers le même domaine peut conduire à l'interdiction de votre IP. Avec notre produit, WebScrapingAPI, vous n'aurez plus à vous soucier de ces problèmes. Notre API vous permet d'effectuer autant de requêtes que vous le souhaitez. Et le meilleur, c'est que vous pouvez l'essayer gratuitement.

Nouvelles et mises à jour

Restez au courant des derniers guides et nouvelles sur le web scraping en vous inscrivant à notre lettre d'information.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Articles connexes

vignette
Cas d'utilisationL'utilisation du Web Scraping pour les données alternatives en finance : Un guide complet pour les investisseurs

Explorez le pouvoir de transformation du web scraping dans le secteur financier. Des données sur les produits à l'analyse des sentiments, ce guide donne un aperçu des différents types de données web disponibles pour les décisions d'investissement.

Mihnea-Octavian Manolache
avatar de l'auteur
Mihnea-Octavian Manolache
13 minutes de lecture
vignette
La science du Web ScrapingLe Web Scraping en toute simplicité : l'importance de l'analyse des données

Découvrez comment extraire et organiser efficacement des données pour le web scraping et l'analyse de données grâce à l'analyse de données, aux bibliothèques d'analyse HTML et aux métadonnées schema.org.

Suciu Dan
avatar de l'auteur
Suciu Dan
12 minutes de lecture
vignette
Cas d'utilisationXPath et les sélecteurs CSS

Les sélecteurs XPath sont-ils meilleurs que les sélecteurs CSS pour le web scraping ? Découvrez les points forts et les limites de chaque méthode et faites le bon choix pour votre projet !

Mihai Maxim
avatar de l'auteur
Mihai Maxim
8 minutes de lecture