Apprenez à construire un web scraper en Python, capable d’analyser un site web entier et d’en extraire toutes les données importantes par web scraping.
Le web scraping consiste à extraire des données d’Internet. Plus précisément, un web scraper est un outil qui effectue des tâches de web scraping ; il s’agit essentiellement d’un script. Python est l’un des langages de script les plus faciles et les plus fiables du marché. Il dispose également d’une grande variété de bibliothèques de web scraping. Cela fait de Python le langage de programmation idéal pour le web scraping. Techniquement, le web scraping sous Python ne nécessite que quelques lignes de code.
Dans ce tutoriel, vous apprendrez tout ce que vous devez savoir pour construire un robot d’indexation et un web scraper simples sous Python. Cette application sera exécutée sur un site web entier pour extraire des données de chaque page. Ensuite, toutes les données extraites sont enregistrées dans un fichier CSV. Ce tutoriel vous aidera à comprendre quelles sont les meilleures bibliothèques Python pour le web scraping, lesquelles vous avez intérêt à adopter, et comment les utiliser. Suivez ce tutoriel étape par étape et apprenez à créer un script de web scraping sous Python.
Table des matières
- Prérequis
- Les meilleures bibliothèques Python pour le web scraping
- Construction d’un web scraper en Python
- Conclusion
- FAQ
Prérequis
Pour créer un web scraper sous Python, vous devez disposer au préalable des éléments suivants :
Si Python n’est pas installé sur votre ordinateur, vous pouvez suivre le premier lien ci-dessus pour le télécharger. Si vous utilisez Windows, veillez à cocher la case « Add python.exe to PATH » lors de l’installation de Python, comme ceci :
Ainsi, Windows reconnaîtra automatiquement les commandes python et pip sur votre terminal. Techniquement, pip est un gestionnaire de packages Python. Notez que pip est inclus par défaut dans Python 3.4 ou supérieur. Vous n’avez donc pas besoin de l’installer manuellement.
Vous êtes maintenant prêt à construire votre premier web scraper Python. Mais tout d’abord, vous avez besoin d’une bibliothèque Python de web scraping !
Les meilleures bibliothèques Python pour le web scraping
Vous pouvez construire un script de web scraping entier sans recourir à des bibliothèques particulières, mais ce n’est pas la solution idéale. N’oublions pas que Python est réputé pour sa panoplie étendue de bibliothèques. Plus précisément, il existe plusieurs bibliothèques de web scraping que vous pouvez choisir. Jetons maintenant un coup d’œil aux plus importantes d’entre elles !
Requêtes
La bibliothèque Requests vous permet d’exécuter des requêtes HTTP en Python. En particulier, Requests facilite l’envoi de requêtes HTTP, notamment par rapport aux bibliothèques HTTP standard de Python. Requests joue un rôle clé dans les projets de web scraping sous Python. En effet, pour récupérer les données contenues dans une page web, vous devez d’abord les récupérer via une requête HTTP GET. Il vous faudra peut-être également envoyer d’autres requêtes HTTP au serveur du site cible.
Vous pouvez installer des requêtes avec la commande pip suivante :
pip install requests
Beautiful Soup
La bibliothèque Python Beautiful Soup facilite l’extraction d’informations sur des pages web . En particulier, Beautiful Soup fonctionne avec n’importe quel analyseur HTML ou XML et vous fournit tout ce dont vous avez besoin pour vos instructions d’itération, de recherche et de modification sur l’arborescence d’analyse. Notez que vous pouvez utiliser Beautiful Soup avec html.parser, interpréteur fourni avec la bibliothèque standard de Python, qui vous permet d’analyser des fichiers texte HTML. Plus précisément, vous pouvez utiliser Beautiful Soup pour parcourir le DOM et en extraire les données dont vous avez besoin.
Vous pouvez installer Beautiful Soup avec le pip de la manière suivante :
pip install beautifulsoup4
Selenium
Selenium est une infrastructure de test automatisée, avancée et open source qui vous permet d’exécuter des opérations sur une page web dans un navigateur. En d’autres termes, vous pouvez utiliser Selenium pour demander à un navigateur d’effectuer certaines tâches. Notez que vous pouvez également utiliser Selenium comme bibliothèque de web scraping afin de mettre à profit ses capacités de navigateur sans tête. Si vous n’êtes pas familier avec ce concept, un navigateur sans tête est un navigateur web qui s’exécute sans GUI (Interface utilisateur graphique). S’il est configuré en mode sans tête, Selenium exécutera le navigateur en arrière-plan.
Ainsi, les pages web visitées dans Selenium sont rendues dans un véritable navigateur, capable d’exécuter JavaScript. Par conséquent, Selenium vous permet de scraper des sites web qui reposent sur JavaScript. Gardez à l’esprit que vous ne pouvez pas y parvenir avec Requests ni aucun autre client HTTP. Cela est dû au fait que vous avez besoin d’un navigateur pour exécuter JavaScript, tandis que Requests vous permet seulement d’exécuter des requêtes HTTP.
Selenium vous fournit tout ce dont vous avez besoin pour construire un web scraper ; vous n’avez besoin d’aucune autre bibliothèque. Vous pouvez l’installer avec la commande pip suivante :
pip install selenium
Construction d’un web scraper en Python
Voyons maintenant comment construire un web scraper en Python. Le but de ce tutoriel est d’apprendre à extraire toutes les données de citations figurant sur le site Quotes to Scrape. Pour chaque citation, vous apprendrez à scraper le texte, l’auteur et la liste des balises.
Mais tout d’abord, jetons un coup d’œil au site cible. Voici à quoi ressemble une page de Quotes to Scrape :
Comme vous pouvez le voir, Quotes to Scrape n’est rien de plus qu’un atelier de web scraping pour débutants. Plus précisément, ce site contient une liste de citations sur plusieurs pages. Le web scraper Python que vous allez construire va récupérer toutes les citations contenues sur chaque page et les renvoyer en tant que données CSV.
Maintenant, il est temps de comprendre quelles sont les meilleures bibliothèques Python de web scraping pour atteindre ce but. Comme vous pouvez le constater dans l’onglet Network de la fenêtre Chrome DevTools ci-dessous, le site cible n’exécute aucune requête Fetch/XHR.
En d’autres termes, Quotes to Scrape ne s’appuie pas sur JavaScript pour récupérer les données affichées dans les pages web. Il s’agit d’une situation courante pour la plupart des sites web rendus par serveur. Puisque le site web cible ne s’appuie pas sur JavaScript pour afficher la page ou récupérer des données, vous n’avez pas besoin de Selenium pour votre tâche de web scraping. Vous pouvez toujours l’utiliser, mais ce n’est pas nécessaire.
Comme vous l’avez déjà appris, Selenium ouvre des pages web dans un navigateur. Puisque cela consomme du temps et des ressources, Selenium introduit des coûts supplémentaires à performances égales. Vous pouvez éviter cela en utilisant Beautiful Soup avec Requests. Voyons maintenant comment construire un script simple de web scraping sous Python pour récupérer des données d’un site web avec Beautiful Soup.
Pour commencer
Avant de commencer à écrire les premières lignes de code, vous devez configurer votre projet Python de web scraping. Techniquement, vous n’avez besoin que d’un seul fichier .py. Cependant, l’utilisation d’un environnement de développement intégré (IDE) avancé facilitera votre expérience de codage. Ici, vous allez apprendre à configurer un projet Python dans PyCharm 2022.2.3, mais n’importe quel autre IDE conviendrait aussi.
Tout d’abord, ouvrez PyCharm et sélectionnez « File > New Project… ». Dans la fenêtre contextuelle « New Project », sélectionnez « Pure Python » et initialisez votre projet.
Par exemple, vous pouvez appeler votre projet python-web-scraper
. Cliquez sur « Create » ; vous avez maintenant accès à votre projet Python vierge. Par défaut, PyCharm initialise un fichier main.py.
Pour plus de clarté, vous pouvez le renommer scraper.py.
Voici à quoi ressemblera votre projet :
Comme vous pouvez le voir, PyCharm initialise automatiquement un fichier Python pour vous. Ignorez le contenu de ce fichier et supprimez chaque ligne de code. De cette façon, vous allez commencer à partir de zéro.
Maintenant, il est temps d’installer les dépendances du projet. Vous pouvez installer Requests et Beautiful Soup en lançant la commande suivante sur le terminal :
pip install requests beautifulsoup4
Cette commande installe les deux bibliothèques en même temps. Attendez la fin du processus d’installation. Vous êtes maintenant prêt à vous servir de Beautiful Soup et de Requests pour construire votre web crawler/scraper sous Python. Assurez-vous d’importer les deux bibliothèques en ajoutant les lignes suivantes en haut de votre fichier script scraper.py :
import requests
from bs4 import BeautifulSoup
PyCharm affiche ces deux lignes en gris car les bibliothèques ne sont pas utilisées dans le code. S’il les souligne en rouge, cela signifie qu’un problème s’est produit pendant le processus d’installation. Dans ce cas, essayez des réinstaller.
Voici à quoi devrait maintenant ressembler votre fichier scraper.py. Vous êtes maintenant prêt à commencer à définir votre logique de web scraping.
Connecting to the target URL to scrape
La première chose que vous devez faire dans un web scraper est de vous connecter à votre site cible. Tout d’abord, récupérez l’URL complète de la page sur votre navigateur. Assurez-vous de copier également la partie http:// ou https:// du protocole HTTP. Dans notre cas, il s’agit de l’URL complète du site cible :
https://quotes.toscrape.com
Maintenant, vous pouvez utiliser Requests pour télécharger une page web avec la ligne de code suivante :
page = requests.get('https://quotes.toscrape.com')
Cette ligne affecte simplement le résultat de la méthode request.get() à la page des variables. En arrière-plan, request.get() exécute une requête GET en utilisant l’URL transmise comme paramètre. Il renvoie ensuite un objet Response contenant la réponse du serveur à la requête HTTP.
Si la requête HTTP est exécutée avec succès, page.status_code contiendra 200. En effet, le code de réponse d’état HTTP 200 OK indique que la requête HTTP a été exécutée avec succès. Un code d’état HTTP 4xx ou 5xx représente une erreur. Cela peut se produire pour plusieurs raisons, mais gardez à l’esprit que la plupart des sites web bloquent les requêtes qui ne contiennent pas un en-tête d’agent utilisateur valide. Plus précisément, l’en-tête d’agent utilisateur de la requête est une chaîne qui caractérise l’application et la version du système d’exploitation à l’origine d’une requête. En savoir plus sur les agents utilisateurs pour le web scraping.
Vous pouvez définir un en-tête d’agent utilisateur valide dans Requests de la manière suivante :
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
}
page = requests.get('https://quotes.toscrape.com', headers=headers)
Requests va maintenant exécuter la requête HTTP avec les en-têtes passés comme paramètre.
Vous devez faire attention à la propriété page.text. Elle contient le document HTML renvoyé par le serveur au format chaîne. Fournissez la propriété de texte à Beautiful Soup pour extraire les données de la page web. Voyons comment.
Extraction de données avec le web scraper Python
Pour extraire des données d’une page web, vous devez d’abord identifier les éléments HTML qui contiennent les données qui vous intéressent. Plus précisément, vous devez trouver les sélecteurs CSS requis pour extraire ces éléments du DOM. Vous pouvez y parvenir en utilisant les outils de développement proposés par votre navigateur. Dans Chrome, cliquez avec le bouton droit de la souris sur l’élément HTML souhaité et sélectionnez Inspect.
Comme vous pouvez le voir ici, l’élément HTML <div>
du devis est identifié par la classe quote. Celle-ci contient :
- Le texte de la citation dans un élément HTML
<span>
- L’auteur de la citation dans un élément HTML
<small>
- Une liste de balises dans un élément
<div>
, chacune étant contenue dans un élément HTML<a>
Techniquement, vous pouvez extraire ces données à l’aide des sélecteurs CSS suivants sur .quote :
.text
.author
.tags .tag
Voyons maintenant comment y parvenir avec Beautiful Soup sous Python. Tout d’abord, passons le document HTML page.text dans le constructeur BeautyfulSoup() :
soup = BeautifulSoup(page.text, 'html.parser')
Le second paramètre spécifie l’interpréteur que Beautiful Soup utilisera pour analyser le document HTML. La variable soup contient maintenant un objet BeautifulSoup. Il s’agit d’une arborescence d’analyse générée à partir de l’analyse syntaxique du document HTML contenu dans page.text avec l’interpréteur html.parser intégré dans Python.
À présent, initialisez une variable qui contiendra la liste de toutes les données récupérées.
quotes = []
Il est maintenant temps d’utiliser soup pour extraire des éléments du DOM de la manière suivante :
quote_elements = soup.find_all('div', class_='quote')
La méthode find_all() renvoie la liste de tous les éléments HTML <div> identifiés par la classe quote. En d’autres termes, cette ligne de code équivaut à appliquer le sélecteur CSS .quote pour récupérer la liste des éléments HTML de citation sur la page. Vous pouvez ensuite effectuer une itération sur la liste des citations pour récupérer les données des citations :
for quote_element in quote_elements:
# extracting the text of the quote
text = quote_element.find('span', class_='text').text
# extracting the author of the quote
author = quote_element.find('small', class_='author').text
# extracting the tag <a> HTML elements related to the quote
tag_elements = quote_element.find('div', class_='tags').find_all('a', class_='tag')
# storing the list of tag strings in a list
tags = []
for tag_element in tag_elements:
tags.append(tag_element.text)
Grâce à la méthode find() de Beautiful Soup, vous pouvez extraire l’élément HTML précis qui vous intéresse. Puisqu’il y a plusieurs balises associées à la citation, vous devez stocker celles-ci dans une liste.
Vous pouvez ensuite transformer ces données en dictionnaire et les ajouter à la liste des citations, comme ceci :
quotes.append(
{
'text': text,
'author': author,
'tags': ', '.join(tags) # merging the tags into a "A, B, ..., Z" string
}
)
Le stockage des données extraites dans un tel format de dictionnaire facilitera l’accès à vos données et leur lisibilité.
Vous venez d’apprendre à extraire toutes les données de citations sur une page unique. Mais n’oubliez pas que votre site cible est constitué de plusieurs pages web. Voyons maintenant comment parcourir l’ensemble du site web.
Implémentation de la logique de crawling
En bas de la page d’accueil, vous trouverez un élément HTML “Next →” <a> qui redirige vers la page suivante du site web cible. Cet élément HTML figure sur toutes les pages sauf la dernière. Un tel scénario est commun dans tous les sites web qui s’étalent sur plusieurs pages.
En suivant le lien contenu dans l’élément HTML “Next →” <a>, vous pouvez facilement naviguer sur l’ensemble du site. Commençons donc par la page d’accueil et voyons comment parcourir chaque page du site cible. Il vous suffit de rechercher l’élément HTML .Next <li> et d’extraire le lien correspondant vers la page suivante.
Vous pouvez implémenter votre logique de crawling comme ceci :
# the url of the home page of the target website
base_url = 'https://quotes.toscrape.com'
# retrieving the page and initializing soup...
# getting the "Next →" HTML element
next_li_element = soup.find('li', class_='next')
# if there is a next page to scrape
while next_li_element is not None:
next_page_relative_url = next_li_element.find('a', href=True)['href']
# getting the new page
page = requests.get(base_url + next_page_relative_url, headers=headers)
# parsing the new page
soup = BeautifulSoup(page.text, 'html.parser')
# scraping logic...
# looking for the "Next →" HTML element in the new page
next_li_element = soup.find('li', class_='next')
Cette boucle where est itérée sur chaque page jusqu’à ce qu’il n’y ait plus de page suivante. Plus précisément, elle permet d’extraire l’URL de la page suivante et de l’utiliser pour créer l’URL de la prochaine page à scraper. Elle télécharge ensuite la page suivante. Puis elle la scrape et réitère la logique.
Vous venez d’apprendre à mettre en œuvre une logique de crawling pour scraper un site web tout entier. Il est maintenant temps de voir comment convertir les données extraites dans un format plus exploitable.
Conversion des données au format CSV
Voyons comment convertir la liste de dictionnaires contenant les données des citations en un fichier CSV. Nous allons pour cela utiliser les lignes suivantes :
import csv
# scraping logic...
# reading the "quotes.csv" file and creating it
# if not present
csv_file = open('quotes.csv', 'w', encoding='utf-8', newline='')
# initializing the writer object to insert data
# in the CSV file
writer = csv.writer(csv_file)
# writing the header of the CSV file
writer.writerow(['Text', 'Author', 'Tags'])
# writing each row of the CSV
for quote in quotes:
writer.writerow(quote.values())
# terminating the operation and releasing the resources
csv_file.close()
Ce snippet écrit les données de citations contenues dans la liste des dictionnaires dans un fichier quotes.csv. Notez que csv fait partie de la bibliothèque standard de Python. Vous pouvez donc l’importer et l’utiliser sans installer de dépendance supplémentaire. Plus précisément, il vous suffit de créer un fichier avec open(). Vous pouvez ensuite remplir ce fichier avec la fonction writerow() de l’objet Writer de la bibliothèque csv. Chaque dictionnaire de citation est alors écrit en tant que ligne au format CSV dans le fichier CSV.
Vous êtes passé de données brutes contenues dans un site web à des données structurées stockées dans un fichier CSV. Le processus d’extraction de données est terminé et vous pouvez maintenant jeter un coup d’œil à l’ensemble de votre web scraper Python.
Au final
Voici à quoi ressemble notre script Python complet de web scraping :
import requests
from bs4 import BeautifulSoup
import csv
def scrape_page(soup, quotes):
# retrieving all the quote <div> HTML element on the page
quote_elements = soup.find_all('div', class_='quote')
# iterating over the list of quote elements
# to extract the data of interest and store it
# in quotes
for quote_element in quote_elements:
# extracting the text of the quote
text = quote_element.find('span', class_='text').text
# extracting the author of the quote
author = quote_element.find('small', class_='author').text
# extracting the tag <a> HTML elements related to the quote
tag_elements = quote_element.find('div', class_='tags').find_all('a', class_='tag')
# storing the list of tag strings in a list
tags = []
for tag_element in tag_elements:
tags.append(tag_element.text)
# appending a dictionary containing the quote data
# in a new format in the quote list
quotes.append(
{
'text': text,
'author': author,
'tags': ', '.join(tags) # merging the tags into a "A, B, ..., Z" string
}
)
# the url of the home page of the target website
base_url = 'https://quotes.toscrape.com'
# defining the User-Agent header to use in the GET request below
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
}
# retrieving the target web page
page = requests.get(base_url, headers=headers)
# parsing the target web page with Beautiful Soup
soup = BeautifulSoup(page.text, 'html.parser')
# initializing the variable that will contain
# the list of all quote data
quotes = []
# scraping the home page
scrape_page(soup, quotes)
# getting the "Next →" HTML element
next_li_element = soup.find('li', class_='next')
# if there is a next page to scrape
while next_li_element is not None:
next_page_relative_url = next_li_element.find('a', href=True)['href']
# getting the new page
page = requests.get(base_url + next_page_relative_url, headers=headers)
# parsing the new page
soup = BeautifulSoup(page.text, 'html.parser')
# scraping the new page
scrape_page(soup, quotes)
# looking for the "Next →" HTML element in the new page
next_li_element = soup.find('li', class_='next')
# reading the "quotes.csv" file and creating it
# if not present
csv_file = open('quotes.csv', 'w', encoding='utf-8', newline='')
# initializing the writer object to insert data
# in the CSV file
writer = csv.writer(csv_file)
# writing the header of the CSV file
writer.writerow(['Text', 'Author', 'Tags'])
# writing each row of the CSV
for quote in quotes:
writer.writerow(quote.values())
# terminating the operation and releasing the resources
csv_file.close()
Comme nous l’avons appris ici, vous pouvez construire un web scraper en moins de 100 lignes de code. Ce script Python est capable de parcourir un site web entier, d’extraire automatiquement toutes ses données et de les convertir en fichier CSV.
Félicitations ! Vous venez d’apprendre à construire un web scraper Python avec les bibliothèques Requests et Beautiful Soup !
Exécution du script Python de web scraping
Si vous utilisez PyCharm, exécutez le script en cliquant sur le bouton ci-dessous :
Sinon, lancez la commande Python suivante sur votre terminal, à l’intérieur du répertoire du projet :
python scraper.py
Attendez la fin du processus ; vous avez maintenant accès à un fichier quotes.csv. Ouvrez-le ; il doit contenir les données suivantes :
Et voilà ! Vous avez maintenant les 100 citations du site cible dans un fichier CSV !
Conclusion
Dans ce tutoriel, vous avez découvert ce qu’est le web scraping, ce dont vous avez besoin pour démarrer avec Python, ainsi que les bibliothèques Python les plus adaptées au web scraping. Ensuite, vous avez vu comment utiliser Beautiful Soup et Requests pour construire une application de web scraping à travers un exemple réel. Comme vous l’avez appris, le web scraping sous Python ne nécessite que quelques lignes de code.
Cependant, le web scraping présente diverses difficultés. En particulier, les technologies anti-bot et anti-scraping sont devenues de plus en plus populaires. C’est pourquoi vous avez besoin d’un outil de web scraping automatisé avancé et complet, fourni par Bright Data.
Pour éviter de vous faire bloquer, nous vous recommandons également de choisir un proxy adapté à votre contexte d’utilisation ; pour cela, consultez les différents services de proxys fournis par Bright Data.