Introduction au DOM
Lors de l'analyse d'un fichier HTML, le navigateur crée dans sa mémoire une représentation des données qui ressemble à une arborescence. Cette représentation s'appelle le DOM (Document Object Model). À chaque balise HTML correspond un nœud dans le DOM. Un nœud possède des propriétés telles que le nom, le contenu, les nœuds enfants, les styles, les événements, etc. Vous trouverez plus d'informations sur le fonctionnement du rendu par le navigateur dans cet article : Comment fonctionne le rendu par le navigateur — les coulisses.
Lorsque nous disons que nous voulons accéder aux données d'une page web, nous voulons simplement parcourir le DOM jusqu'à un ensemble spécifique de nœuds et en extraire le contenu. Dans cet article, je vais vous donner différents conseils pour accéder rapidement à ces nœuds à l'aide des sélecteurs CSS.
Que sont les sélecteurs CSS ?
Pourquoi sont-ils appelés sélecteurs CSS (Cascading Style Sheets) ?
Le CSS sert à définir l'apparence des nœuds sur une page. Avec le CSS, vous pouvez écrire des règles sur l'apparence qu'un nœud doit avoir et sur la manière dont il doit interagir avec les autres nœuds. Une règle se compose d'un sélecteur et d'une liste de styles à remplacer.
Ces sélecteurs sont donc associés au CSS car c'est leur utilisation la plus courante, mais nous ne sommes pas obligés de les utiliser uniquement avec le CSS. Avec le CSS, vous souhaitez sélectionner un nœud et modifier sa propriété de style. Si vous y réfléchissez bien, nous voulons faire la même chose : sélectionner un nœud et effectuer une action sur celui-ci, comme lire son contenu ou déclencher un événement.
Comment fonctionnent les sélecteurs CSS ?
Il vous sera très utile de visualiser le processus de sélection. Imaginons que vous souhaitiez extraire tous les paragraphes d’un site web. Vous voulez récupérer tous les nœuds dont le nom est `p`. Vous pouvez le faire manuellement. Il vous suffit de parcourir chaque nœud du DOM et de sélectionner uniquement ceux pour lesquels node.tagName === 'P' (les noms de balises sont en majuscules).
Voici un petit extrait de code que vous pouvez utiliser :
function scrapeByTagName(node, tagName) {
if (node === null)
return;
node.childNodes.forEach(node => {
//console.log(node.tagName)
if (node.tagName?.toLowerCase() === tagName.toLowerCase()) {
console.log(node)
return
}
scrapeByTagName(node, tagName)
});
}
J'ai créé une page web factice qui ressemble à ceci :
Et voici le code HTML correspondant :
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
</head>
<body>
<div id="wrapper">
<h1 custom-attr="some data">Some Title</h1>
<h2 custom-attr="some other data">Some Subtitle</h2>
<div id="container">
<p custom-attr>paragraph
<span> subparagraph</span>
</p>
<p id="text">paragraph with id #text</p>
<p class="bold">paragraph with class .bold</p>
<p class="text">paragraph with class .text</p>
<p class="text bold">paragraph with class .text.bold</p>
<p class="text italic">paragraph with class .text.italic</p>
</div>
</div>
</body>
</html>
Après avoir exécuté la fonction dans la console du navigateur, j'ai obtenu cette réponse :
Comme vous pouvez le voir, la fonction a enregistré toutes les balises p.
Pour afficher la console du navigateur, vous devez ouvrir les outils de développement et aller dans l'onglet « Console », ou appuyer sur la touche Échap. Vous pouvez ouvrir les outils de développement en cliquant avec le bouton droit sur un élément et en sélectionnant « Inspecter » dans le menu, ou en utilisant le raccourci clavier Ctrl + Maj + I.
Comment utiliser les sélecteurs CSS ?
Nous allons utiliser deux méthodes : `querySelector` et `querySelectorAll`. Ces méthodes sont disponibles sur tous les objets de type `Element`. Les nœuds que nous essayons d'extraire sont de type `HTMLElement`, qui hérite du type `Element`.
querySelector renvoie le premier nœud correspondant au sélecteur. querySelectorAll renvoie une liste contenant tous les nœuds correspondant au sélecteur. Pour reproduire l'exemple présenté précédemment, il suffit d'appeler querySelectorAll et de parcourir la liste renvoyée.
document.querySelectorAll('p').forEach(node => console.log(node))
Vous pouvez voir que j'ai utilisé document.querySelectorAll ; en effet, document est défini dans le contexte de la fenêtre comme étant la racine de la page web, c'est-à-dire l'équivalent de la balise html. Vous pouvez utiliser les méthodes querySelector avec n'importe quel nœud, pas seulement avec le nœud racine.
Pour extraire réellement des données, vous devrez utiliser une bibliothèque capable d'ouvrir une fenêtre de navigateur et d'accéder à une URL. Ce n'est qu'alors que votre code s'exécutera, dans le contexte de cette fenêtre. Pour en savoir plus sur la manière de procéder, je vous recommande cet article : « The Ultimate Guide to Web Scraping with JavaScript and Node.Js ».
Chez WebScrapingAPI, nous utilisons Puppeteer. Puppeteer est une bibliothèque qui nous permet de contrôler des instances de navigateurs Chromium sans interface graphique. Vous pouvez utiliser notre API pour extraire des données d’un site web sans avoir à créer un scraper personnalisé. Nous disposons en effet d’un paramètre nommé extract_rules qui utilise des sélecteurs CSS pour extraire des données d’une URL donnée.
Aide-mémoire des sélecteurs CSS
Le sélecteur *
Ce sélecteur spécifie tous les éléments de l'arborescence. Il n'est pas très utilisé, mais il est bon de le connaître.
Le sélecteur .class
Vous pouvez obtenir un nœud avec une classe spécifique en utilisant .class. Il est principalement utilisé lorsque vous avez une liste d'éléments. Comme les éléments d'une liste ont souvent le même aspect, ils peuvent avoir la même classe. Recherchons la classe .text.
Vous souhaitez peut-être sélectionner le nœud qui possède la classe .bold.
Il semble qu'il y ait un autre élément qui possède la classe .bold. Vous pouvez être plus précis avec le sélecteur de classe en utilisant plusieurs classes concaténées.
Veuillez noter qu'il n'y a pas d'espaces entre les classes.
document.querySelectorAll('.text .bold').forEach(node => console.log(node))
Cette requête ne renvoie aucun résultat dans le code HTML ci-dessus, car elle recherche un élément de classe .text ayant un enfant de classe .bold (pas nécessairement un enfant direct). La requête renverrait l'élément enfant si elle le trouvait.
Le sélecteur #id
Que faire si un élément n'a pas de classe ou si la classe est utilisée trop fréquemment dans le document ? Vous pouvez utiliser l'attribut ID pour obtenir un niveau de spécificité plus élevé. L'inconvénient de l'utilisation du sélecteur id est que, dans la plupart des cas, l'id est unique dans la page HTML, vous ne pouvez donc pas obtenir une liste de nœuds avec celui-ci.

Le sélecteur de nom de nœud
Chaque nœud possède un nom. Il s'agit du nom exact de la balise appariée dans le code HTML. Vous pouvez récupérer tous les nœuds portant un nom spécifique en utilisant ce nom dans le sélecteur.

Le sélecteur [attribut]
Vous pouvez être amené à vouloir sélectionner tous les nœuds possédant un attribut spécifique.
Vous pouvez également spécifier la valeur de l'attribut.
Ou même ce que la valeur de l'attribut doit contenir. Vous pouvez utiliser le tilde ~ avant le signe égal pour définir que la valeur de l'attribut doit contenir une liste de mots.
Le sélecteur d'attribut sera le plus utilisé si vous décidez de créer un scraper. Il est très puissant et offre bien plus de cas d'utilisation que ce que j'ai montré ici. Vous trouverez plus d'informations sur l'utilisation du sélecteur d'attribut ici : Sélecteurs d'attributs W3.
Regroupement de plusieurs sélecteurs
Récupérer tous les nœuds p qui ont un identifiant.
Sélectionner tous les nœuds span qui sont des enfants d'un nœud p.
Récupérer tous les nœuds div qui sont des enfants directs du nœud body.
Récupérer tous les nœuds p ayant la classe .text
Les possibilités de regroupement de ces sélecteurs sont infinies. Essayez de copier le code HTML ci-dessus et d'y ajouter d'autres nœuds. Testez ensuite différentes combinaisons de sélecteurs. Si vous souhaitez en savoir plus sur les sélecteurs CSS en général, Mozilla propose un excellent article qui explique leur fonctionnement dans le développement web.
Résumé
Si vous souhaitez apprendre quelque chose de nouveau, je vous conseille de commencer par comprendre comment cela fonctionne. Oui, c'est une étape facultative, mais elle vous apportera des informations que les autres n'ont pas.
Dans le domaine du développement logiciel, ces informations vous aideront à trouver la bonne réponse à votre problème ou à votre erreur. Vous pourriez prendre les choses en main et même créer une solution personnalisée.
Si vous voulez vraiment comprendre les sélecteurs CSS, vous devez comprendre le DOM. Il s'agit simplement d'un arbre (un graphe acyclique non orienté) composé de nœuds qui ont un nom et certains attributs. C'est tout. Lorsque vous écrivez un sélecteur, vous écrivez simplement une chaîne de caractères qui est analysée et utilisée pour interroger le DOM.




