Practical Programming

Web scraping : tutoriel basique en Python avec exemple de code

Cet article est le troisième de notre série Web scraping : le guide complet avec tutoriels. Il est fortement recommandé de lire les deux précédents articles avant celui-ci : Data scraping et Web scraping : la vraie définition et Web scraping : quels langages et technologies choisir

Bienvenue dans ce tutoriel basique de web scraping en Python. Pour voir le même tutoriel en Node.js ou en PHP et constater les différences entre chaque langage, rendez-vous sur l’article correspondant : 

Pour commencer simple mais avec un cas d’usage concret, nous allons créer un programme qui va extraire les articles de la page d’accueil de LeMonde.fr.

Peu importe la technologie que vous allez choisir pour coder, vous devez forcément réaliser un travail préliminaire pour conceptualiser votre programme de web scraping et établir son mode de fonctionnement. Je vais vous montrer ma méthodologie. 

Travail préliminaire

Quand on veut se lancer dans l’écriture d’un programme de web scraping, la première chose à faire est de se rendre sur le site ciblé, ici LeMonde.fr.

Dans notre cas, l’objectif de notre programme est simple : extraire tous les articles de la page d’accueil.

Nous allons donc observer le code HTML de la page pour en comprendre la structure et repérer un pattern qui nous permettra de cibler tous les articles de la page d’accueil en faisant le moins d’efforts possibles. En web scraping, les développeurs utilisent la plupart du temps les sélecteurs CSS et/ou les sélecteurs XPath pour sélectionner un ou plusieurs éléments sur la page et en extraire le contenu.

Exemples de sélecteurs CSS pour le web scraping

Il existe de nombreux sélecteurs CSS et chaque élément HTML d’une page peut être sélectionné par de nombreux sélecteurs différents. Ce qui est important est de choisir le bon sélecteur pour sélectionner les éléments que vous avez besoin d’extraire : le sélecteur ne devra pas rater des éléments, ni inclure des éléments dont vous n’avez pas besoin. 

La liste ci-dessous est un extrait traduit de la liste de w3schools qui proposent également un testeur de sélecteur pour vous aider à comprendre leur fonctionnement.

SélecteurExempleDescription de l’exemple
.classe.produitSélectionne tous les éléments avec class=”produit”
.classe1.classe2.nom1.nom2Sélectionne tous les éléments qui contiennent nom1 et nom2 dans leur attribut classe
.classe1 .classe2.nom1 .nom2Sélectionne tous les éléments de classe nom2 contenus dans des éléments de classe nom1
#id#introSélectionne l’élément avec id=”intro”
élémentpSélectionne tous les éléments <p>
élément.classep.descriptionSélectionne tous les éléments <p> avec class=”description”
élément élémentdiv p Sélectionne tous les éléments <p> contenus dans des éléments <div>
élément > élémentdiv > pSélectionne tous les éléments <p> dont le parent est un élément <div>
[attribut=valeur][target=_blank]Sélectionne tous les éléments avec target=”_blank”
:not(sélecteur):not(p)Sélectionne tous éléments qui ne sont pas des éléments <p>

Analysons maintenant la structure du code de la page d’accueil du site ciblé à l’aide des outils de développement de votre navigateur pour trouver le bon sélecteur qui va nous permettre de sélectionner tous les articles de la page et aucun autre élément.

Analyse de la structure HTML pour le web scraping

Une bonne façon de trouver rapidement un sélecteur avec notre navigateur est de faire un clic droit sur un des éléments ciblés (dans notre cas, un article) et de cliquer sur inspecter. Les outils de développement nous montrent alors l’élément HTML et on peut dès lors chercher des patterns ou répétitions dans le code qui nous permettent de trouver un sélecteur. Par exemple : les éléments que l’on cible sont tous de la même classe, ont le même attribut ou le même parent etc. 

Sur le site du Monde, on peut voir par exemple que chaque article semble être contenu dans un élément div de classe article comme le montre la capture ci-dessous : 

Essayons donc de sélectionner tous les éléments div de classe article avec le sélecteur CSS  div.article en le tapant dans la barre de recherche des outils de développement : 

Pour tester un sélecteur CSS ou XPath sur le code d’une page dans Google Chrome, il faut ouvrir les outils de développement avec F12 puis faire apparaître la barre de recherche (entourée en rouge sur la capture ci-dessus) avec Ctrl+F

Le navigateur nous montre ensuite le nombre d’éléments sélectionnés (ici 81) et nous pouvons appuyer successivement sur Entrée pour voir défiler tous les éléments sélectionnés. 

Le sélecteur div.article semble bien nous sélectionner tous les articles de la page d’accueil. En réalité, le sélecteur n’est pas le bon pour notre programme car un peu plus loin sur la page, plusieurs articles sont en réalité contenus dans un élément div.article comme le montre la capture ci-dessous : 

Nous devons donc affiner notre sélecteur CSS pour nous permettre d’obtenir également ces articles à l’intérieur de ces éléments. Sinon, notre scraping produira des erreurs car il considérera cet élément comme un seul et même article alors qu’il en contient en réalité 3. 

Chaque article de presse sur Le Monde étant une page distincte, on peut logiquement considérer que chaque article sur la page d’accueil sera accessible par un lien. Essayons donc d’accéder à chaque élément <a> contenu dans un élément <div class=”article”> avec le sélecteur div.article > a. 

Ca fonctionne ! Nous avons maintenant 151 résultats : il y a bien 151 articles sur la page d’accueil du site

Parfois, dans certains cas complexes, nous sommes jamais sûrs du sélecteur que nous avons choisi. Une petite astuce que j’utilise consiste à tester directement dans la console du navigateur notre sélecteur avec un petit script JavaScript. Ici, je vais tester notre sélecteur avec le code suivant :

const selector = 'div.article > a';
const list = document.querySelectorAll(selector)

for (let i = 0; i < list.length; ++i) {
  console.log(list[i].getAttribute('href'));
}

Ce code nous imprime bien les URL de tous les articles de la page d’accueil, nous pouvons donc choisir ce sélecteur pour notre programme de scraping.

Nous savons donc maintenant comment va fonctionner notre programme de web scraping : 

  • Fetching : Il va se connecter à la page d’accueil du site et en télécharger le code HTML
  • Parsing : Il va parser le code HTML à l’aide du sélecteur CSS div.article > a pour extraire les liens vers chaque article
  • Stockage : Il va stocker les titres et les URL des articles dans un fichier CSV

A nos IDEs ! 

Exemple de code web scraping en Python avec Scrapy

Si vous êtes passé directement à cette partie sans lire les précédentes, je vous conseille au moins de lire la partie précédente “Travail préliminaire”. 

Pour suivre ce guide, vous aurez besoin du framework Scrapy en l’installant avec : 

pip install Scrapy

Scrapy fonctionne très différemment de Puppeteer et automatise certaines tâches. Vous devez commencer par créer un nouveau projet Scrapy (qu’on appellera basic_scraping) avec la commande : 

scrapy startproject basic_scraping

Un dossier de projet est créé, rendez-vous à l’intérieur : 

cd basic_scraping

Créez un  template de web scraping basique avec la commande : 

scrapy genspider lemondebot www.lemonde.fr

Cette commande a généré le code suivant : 

import scrapy
 
class LemondebotSpider(scrapy.Spider):
    name = 'lemondebot'
    allowed_domains = ['www.lemonde.fr']
    start_urls = ['http://www.lemonde.fr/']
 
    def parse(self, response):
        pass

Quelques explications : 

  • name est évidemment le nom de votre bot, de votre programme de scraping que scrapy appelle un “spider”. Bien nommer vos scripts est important pour les maintenir efficacement quand vous en avez des centaines à gérer.
  • allowed_domains est une liste optionnelle de domaines sur lesquels votre programme peut faire des requêtes. Les URL qui ne font pas partie de ces domaines ne seront pas suivies.
  • parse(self, reponse) est la fonction qui sera appelée à chaque fois que votre programme crawle une URL avec succès.

C’est cette fonction parse qui va contenir le code de notre extraction de données via nos sélecteurs CSS

for article in response.css('div.article'):
            yield {
                'titre': article.css(".article__title *::text").extract_first(),
                'url': article.css("a::attr(href)").extract_first()
            }

Même principe qu’en Node.js (tuto web scraping node js), on crée une liste d’éléments <div> de classe “article” et on y extrait les éléments titres et url via nos sélecteurs CSS.  

Lançons maintenant notre script avec la commande : 

scrapy crawl lemondebot

Scrapy nous retourne beaucoup d’informations. Parmi elles, on retrouve les données extraites

Dernière étape : le stockage dans un fichier CSV

Là encore, Scrapy nous facilite la vie. Rendez-vous dans le fichier settings.py dans votre dossier de projet et ajoutez simplement les deux lignes suivantes sous la ligne NEW_SPIDER_MODULE

FEED_FORMAT = "csv"
FEED_URI = "resultats.csv"


Le fichier settings.py avec l’export en CSV

Les résultats dans le fichier CSV sont parfaits : 


On l’a vu, Scrapy nous permet de ne pas réinventer la roue en automatisant un grand nombre de tâches et en vous laissant vous concentrer sur le web scraping pur. 

Le code complet est disponible en téléchargement à la fin de l’article. 

Tous les codes d’exemple complets de web scraping en Node.js, Python et PHP sont en téléchargement sur GitHub.

Pour constater les différences entre chaque langage au niveau du web scraping, je vous conseille de consulter les autres tutoriels

Sinon, vous pouvez passer directement au tutoriel avancé de web scraping de web app avec Puppeteer (Node.js)

Lucas Roquilly

Lucas Roquilly

Commenter

Retrouvez nous

N'hésitez pas à nous suivre sur les différents réseaux sociaux !

Most popular

Most discussed

Share This