Extraction et analyse de données Web avec Python et BeautifulSoup

Sorin-Gabriel Marica le 13 juillet 2021

Les racleurs de sites web sont des outils précieux qui vous aident à extraire des informations spécifiques d'un site web. Théoriquement, vous pourriez le faire manuellement, mais le web scraping vous permet de traiter de grandes quantités de données de manière plus efficace et plus productive.

L'un des langages de programmation les plus populaires pour le web scraping est Python. Ce langage est accompagné de la bibliothèque BeautifulSoup, qui simplifie le processus. Ensemble, ce duo rend le web scraping beaucoup plus facile qu'avec d'autres langages.

A mon avis, utiliser BeautifulSoup est la façon la plus simple de construire un scraper web simple à partir de zéro. Si vous voulez en savoir plus, lisez la suite car je vais vous montrer comment créer votre propre scraper web en utilisant Python et BeautifulSoup.

Aperçu de BeautifulSoup

BeautifulSoup, comme indiqué dans leur documentation, est une bibliothèque Python pour extraire des données de fichiers HTML et XML. Vous pouvez donc utiliser Python pour extraire le contenu HTML d'un site web et utiliser BeautifulSoup pour analyser ce HTML afin d'en extraire les informations pertinentes.

Le principal avantage d'utiliser BeautifulSoup est la syntaxe simple qu'elle offre. Avec cette bibliothèque, vous pouvez naviguer dans l'arbre DOM, rechercher des éléments spécifiques ou modifier le contenu HTML. Tous ces avantages en ont fait la bibliothèque python la plus populaire pour l'analyse des documents HTML et XML.

Installation

Pour installer BeautifulSoup, vous pouvez consulter le guide ici, car l'installation est différente selon la machine que vous utilisez. Dans cet article, j'utilise un système Linux et il suffit de lancer la commande suivante :

pip install beautifulsoup4

Si vous utilisez python3, vous devrez peut-être installer la bibliothèque en utilisant la commande suivante :

pip3 install beautifulsoup4

Gardez à l'esprit que python3 est déjà installé sur ma machine. Si vous ne connaissez pas Python, vous pouvez trouver un guide sur la façon de l'installer ici. Vous pouvez également consulter notre guide ultime pour construire un scraper web avec Python pour plus d'informations sur le sujet.

Construire un scraper avec BeautifulSoup

Maintenant, si tout s'est bien passé, nous sommes prêts à construire notre propre scraper. Pour cet article, j'ai choisi de récupérer les 100 meilleurs films de tous les temps à partir de RottenTomatoes et de tout enregistrer aux formats JSON et CSV.

Récupération de la source de la page

Pour se familiariser avec BeautifulSoup, nous allons d'abord récupérer le code HTML complet de la page et le sauvegarder dans un nouveau fichier appelé "page.txt".

Si vous souhaitez voir la source HTML d'une page, vous pouvez le faire dans Google Chrome en appuyant sur CTRL+U. Cela ouvrira un nouvel onglet, et vous verrez quelque chose comme ceci :

blog-image

Pour obtenir la même source avec BeautifulSoup et Python, nous pouvons utiliser le code suivant :

import requests
from bs4 import BeautifulSoup

scraped_url = 'https://www.rottentomatoes.com/top/bestofrt/'
page = requests.get(scraped_url)

soup = BeautifulSoup(page.content, 'html.parser')

file = open('page.txt', mode='w', encoding='utf-8')
file.write(soup.prettify())

Dans ce code, nous faisons une requête à la page RottenTomatoes et ajoutons ensuite tout le contenu de la page dans un objet BeautifulSoup. La seule utilisation de BeautifulSoup dans cet exemple est la fonction finale appelée "prettify()", qui formate le code html pour le rendre plus facile à lire.

To understand the function better, for this HTML code “<div><span>Test</span></div>”, prettify, will add the tabulations and transform it in this formatted code:

<div>

   <span>

       Test

   </span>

</div>

Le résultat final du code est la création d'un fichier appelé page.txt qui contient la totalité de la page source de notre lien :

blog-image

Notez qu'il s'agit de la source de la page avant l'exécution de tout code Javascript. Il arrive que des sites web choisissent de modifier le contenu de leur page de manière dynamique. Dans ce cas, la source de la page sera différente du contenu réel affiché à l'utilisateur. Si vous avez besoin que votre scraper exécute du Javascript, vous pouvez lire notre guide sur la création d'un scraper web avec Selenium, ou vous pouvez utiliser WebScrapingAPI, notre produit qui s'occupe de ce problème pour vous.

Obtenir les données web

Si vous regardez la page source précédente, vous verrez que vous pouvez trouver les noms des films et leur note. Heureusement pour nous, RottenTomatoes ne charge pas la liste des films dynamiquement, nous pouvons donc aller de l'avant et récupérer les informations nécessaires.

Tout d'abord, nous inspectons la page et voyons comment le HTML est structuré. Pour ce faire, vous pouvez cliquer avec le bouton droit de la souris sur un titre de film et choisir l'option "Inspecter l'élément". La fenêtre suivante devrait s'afficher :

blog-image

I used the red line to highlight the useful information from this image. You can see that the page displays the top movies in a table and that there are four cells on each table row (<tr> element).

La première cellule contient la position du film, la deuxième contient des informations sur les évaluations (élément de la classe tMeterScore ), la troisième contient le titre du film et la dernière cellule indique le nombre de critiques.

Connaissant cette structure, nous pouvons maintenant commencer à extraire les informations dont nous avons besoin.

import requests
from bs4 import BeautifulSoup

links_base = 'https://www.rottentomatoes.com'
scraped_url = 'https://www.rottentomatoes.com/top/bestofrt/'
page = requests.get(scraped_url)

soup = BeautifulSoup(page.content, 'html.parser')

table = soup.find("table", class_="table") # We extract just the table code from the entire page
rows = table.findAll("tr") # This will extract each table row, in an array

movies = []

for index, row in enumerate(rows):
if index > 0: # We skip the first row since this row only contains the column names
link = row.find("a") # We get the link from the table row
rating = row.find(class_="tMeterScore") # We get the element with the class tMeterScore from the table row
movies.append({
"link": links_base + link.get('href'), # The href attribute of the link
"title": link.string.strip(), # The strip function removes blank spaces at the beginning and the end of a string
"rating": rating.string.strip().replace("&nbsp;", ""), # We remove &nbsp; from the string and the blank spaces
})

print(movies)

Lorsque vous exécutez ce code, vous devriez obtenir un résultat comme celui-ci :

blog-image

Dans cet exemple, nous extrayons le contenu du tableau et parcourons les lignes du tableau. Comme la première ligne ne contient que les noms des colonnes, nous l'ignorons.

On the rest of the rows, we continue the process by extracting the anchor (<a>) element and the span element with the class “tMeterScore”. Having them, we can now retrieve the information needed.

Le titre du film se trouve dans l'élément anchor, le lien est l'attribut "href" de l'anchor, et la note se trouve dans l'élément span avec la classe "tMeterScore". Nous créons simplement un nouveau dictionnaire pour chaque ligne et l'ajoutons à notre liste de films.

Sauvegarde des données web

Jusqu'à présent, le scraper a récupéré et formaté les données, mais nous ne les avons affichées que dans le terminal. Nous pouvons également enregistrer les informations sur notre ordinateur sous forme de JSON ou de CSV. Le code complet du scraper (y compris la création d'un fichier local) est le suivant :

import requests
from bs4 import BeautifulSoup
import csv
import json

links_base = 'https://www.rottentomatoes.com'
scraped_url = 'https://www.rottentomatoes.com/top/bestofrt/'
page = requests.get(scraped_url)

soup = BeautifulSoup(page.content, 'html.parser')

table = soup.find("table", class_="table") # We extract just the table code from the entire page
rows = table.findAll("tr") # This will extract each table row from the table, in an array

movies = []

for index, row in enumerate(rows):
if index > 0: # We skip the first row since this row only contains the column names
link = row.find("a") # We get the link from the table row
rating = row.find(class_="tMeterScore") # We get the element with the class tMeterScore from the table row
movies.append({
"link": links_base + link.get('href'), # The href attribute of the link
"title": link.string.strip(), # The strip function removes blank spaces at the beginning and the end of a string
"rating": rating.string.strip().replace("&nbsp;", ""), # We remove &nbsp; from the string and the blank spaces
})

file = open('movies.json', mode='w', encoding='utf-8')
file.write(json.dumps(movies))

writer = csv.writer(open("movies.csv", 'w'))
for movie in movies:
writer.writerow(movie.values())

Aller encore plus loin dans la recherche

Maintenant que vous avez toutes les informations, vous pouvez choisir d'aller plus loin dans le scraping. N'oubliez pas que chaque film a un lien. Vous pouvez continuer à scraper les pages des films et extraire encore plus d'informations à leur sujet.

Par exemple, si vous consultez la page du film It Happened One Night (1934), vous pouvez voir que vous pouvez encore récupérer des informations utiles telles que le score du public, la durée du film, le genre, etc.

Cependant, le fait d'effectuer toutes ces demandes en peu de temps semble très inhabituel et pourrait conduire à des validations CAPTCHA ou même à des blocages d'IP. Pour éviter cela, vous devez utiliser des proxys rotatifs afin que le trafic envoyé ait l'air naturel et qu'il provienne de plusieurs IP.

Autres caractéristiques de BeautifulSoup

Alors que notre scraper RottenTomatoes est complet, BeautifulSoup a encore beaucoup à offrir. Chaque fois que vous travaillez sur un projet, vous devriez garder le lien de la documentation ouvert afin de pouvoir rechercher rapidement une solution lorsque vous êtes bloqué.

Par exemple, BeautifulSoup permet de naviguer dans l'arbre DOM de la page :

from bs4 import BeautifulSoup

soup = BeautifulSoup("<head><title>Title</title></head><body><div><p>Some text <span>Span</span></p></div></body>", 'html.parser')

print(soup.head.title) # Will print "<title>Title</title>"
print(soup.body.div.p.span) # Will print "<span>Span</span>"

Cette fonction peut vous aider à sélectionner un élément qui ne peut être identifié par ses attributs. Dans ce cas, le seul moyen de le trouver est la structure du DOM.

Un autre avantage de BeautifulSoup est qu'il est possible de modifier la source de la page :

from bs4 import BeautifulSoup

soup = BeautifulSoup("<head><title>Title</title></head><body><div><p>Some text <span>Span</span></p></div></body>", 'html.parser')

soup.head.title.string = "New Title"
print(soup)
# The line above will print "<head><title>New Title</title></head><body><div><p>Some text <span>Span</span></p></div></body>"

Cela peut s'avérer très utile si vous souhaitez créer un service permettant aux utilisateurs d'optimiser leurs pages. Par exemple, vous pouvez utiliser le script pour gratter un site web, récupérer le CSS, le minifier et le remplacer dans la source HTML. Les possibilités sont infinies !

Toujours gratter intelligemment

Je tiens à ce que vous reteniez ceci : utiliser Python et Beautifulsoup pour le web scraping est une excellente idée. Cela facilite grandement le processus par rapport à d'autres langages de programmation.

Le scraper que nous avons construit pour récupérer les films les mieux notés de tous les temps sur RottenTomatoes peut être codé en quelques minutes seulement, et vous pouvez même l'utiliser avec le scraper IMDB de notre guide ultime pour le scraping avec PHP.

Cependant, certains sites web sont plus accessibles aux scrapers que d'autres. Si le projet présenté dans cet article est simple et amusant, d'autres le sont tout autant. Parfois, les sites web font tout ce qui est en leur pouvoir pour empêcher que leur contenu soit scrappé.

Dans certaines situations, la seule façon de gratter du contenu est de masquer votre travail avec plusieurs IP et un vrai navigateur. Pour ce type de situation, nous avons créé WebScrapingAPI, une solution puissante qui offre des proxies rotatifs, un rendu Javascript, et qui vous permet de scraper n'importe quel site web avec un minimum de maux de tête !

Ne me croyez pas sur parole, essayez-le vous-même ! Vous pouvez commencer votre essai gratuit dès maintenant et obtenir 5000 appels API sans avoir à fournir de données sensibles telles que les détails de votre carte de crédit.

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
GuidesComment récupérer les données des produits Amazon : Un guide complet des meilleures pratiques et des outils

Explorez les complexités du scraping des données de produits Amazon avec notre guide approfondi. Des meilleures pratiques aux outils tels que l'API Amazon Scraper, en passant par les considérations juridiques, apprenez à relever les défis, à contourner les CAPTCHA et à extraire efficacement des informations précieuses.

Suciu Dan
avatar de l'auteur
Suciu Dan
15 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
GuidesDébloquez les sites web et protégez votre identité avec les proxies et Axios Node.js

Apprenez à utiliser les proxys avec Axios et Node.js pour un web scraping efficace. Conseils, exemples de code et avantages de l'utilisation de WebScrapingAPI inclus.

Suciu Dan
avatar de l'auteur
Suciu Dan
7 minutes de lecture