Guide des sélecteurs HTML pour le Web Scraping

Guides, Grattage, Python, Nov-08-20245 minutes de lecture

Les sélecteurs HTML sont essentiels pour le web scraping, car ils permettent aux développeurs de cibler des éléments spécifiques sur une page web. En utilisant ces sélecteurs, les développeurs peuvent extraire des données avec précision.

Le web scraping consiste à obtenir des données à partir de sites web en naviguant dans leur structure HTML. Les sélecteurs HTML sont essentiels, car ils vous permettent de repérer des balises, des attributs ou des contenus spécifiques. Qu'il s'agisse d'extraire des prix de produits ou des titres, les sélecteurs sont votre guide.

L'utilisation de sélecteurs HTML permet de rationaliser efficacement l'extraction des données et de réduire les erreurs. Ils vous aident à vous concentrer sur les éléments importants, ce qui vous permet d'économiser du temps et des efforts lors de la collecte d'informations à partir de sources en ligne.

Dans ce blog, nous allons explorer comment utiliser les sélecteurs ci-dessous avec Python et la bibliothèque"Beautifulsoup" :

  • Sélecteurs d'identité
  • Sélecteurs de classe
  • Sélecteurs d'attributs
  • Sélecteurs hiérarchiques
  • Combinaison de ces sélecteurs

Sélecteurs d'ID

En HTML, les ID sont des identifiants uniques attribués à des éléments spécifiques, garantissant que deux éléments ne partagent pas le même ID. Cette unicité fait des sélecteurs d'ID des outils idéaux pour cibler des éléments particuliers d'une page web. Par exemple, si vous scrapez une page web comportant plusieurs sections, chaque section peut avoir son propre identifiant, ce qui vous permet d'extraire des données d'une section particulière sans interférence.

Prenons par exemple ce site web, en particulier l'élément ci-dessous <div id="pages"> ...</div>

Cet élément contient d'autres éléments HTML imbriqués, mais l'essentiel est qu'il est unique sur ce site web et que nous pouvons tirer parti de ce scénario, par exemple lorsque nous voulons récupérer des sections particulières du site web. Dans ce cas, cet élément contient d'autres articles que nous expliquerons avec les autres sélecteurs ci-dessous. Voici à quoi ressemble cette section de la page :

Prenons un exemple simple en utilisant les bibliothèques "requests" et "bs4" de Python :

import requests
from bs4 import BeautifulSoup
# Step 1: Send a GET request to the website
url = "https://www.scrapethissite.com/pages/"
response = requests.get(url)
if response.status_code == 200:
   # Step 2: Parse the HTML content with BeautifulSoup
   soup = BeautifulSoup(response.text, 'html.parser')
  
   # Step 3: Find the div with id="pages"
   pages_div = soup.find("div", id="pages")
  
   # Step 4: Display the content or handle it as needed
   if pages_div:
       print("Content of the div with id='pages':")
       print(pages_div.text.strip())
   else:
       print("No div with id='pages' found.")
else:
   print(f"Failed to retrieve the webpage. Status code: {response.status_code}")

Explication :

  • Envoyer une requête : La bibliothèque des requêtes envoie une requête GET pour récupérer le contenu HTML de l'URL cible.
  • Analyser le HTML : BeautifulSoup analyse le HTML, ce qui nous permet d'effectuer des recherches dans la structure du document.
  • Find Specific <div>: Nous utilisons soup.find("div", id="pages") pour localiser le <div> avec l'élément id="pages".
  • Contenu de l'affichage : Si le <div> est trouvé, nous imprimons son contenu. Si ce n'est pas le cas, un message indique qu'il est manquant.

Limites des sélecteurs d'identifiants :

Les sélecteurs d'identifiants sont puissants mais ont des limites. Les ID dynamiques qui changent à chaque chargement de page peuvent rendre difficile une extraction cohérente des données. Dans ce cas, il peut être nécessaire d'utiliser d'autres sélecteurs pour obtenir des résultats fiables.

Sélecteurs de classe

Les sélecteurs de classe sont flexibles car ils vous permettent de cibler des groupes d'éléments qui partagent la même classe. Ils sont donc essentiels pour les pages web contenant des éléments récurrents. Par exemple, un site web affichant une liste de produits peut attribuer la même classe à chaque élément du produit.

Prenons un autre exemple en utilisant ce site web. Nous avons identifié plus haut un <div id="pages"> à l'aide du sélecteur d'ID et dans cet élément div il y a quelques articles qui ont la même classe.

Comme vous pouvez le voir, nous avons quatre éléments de la même classe <div class="page">

Voici comment ils se présentent sur le site web :

Dans le code ci-dessous, nous sélectionnons tous les éléments de la classe "page", ce qui renvoie une liste qui peut être utilisée pour d'autres analyses.

import requests
from bs4 import BeautifulSoup
# Step 1: Send a GET request to the website
url = "https://www.scrapethissite.com/pages/"
response = requests.get(url)
if response.status_code == 200:
   # Step 2: Parse the HTML content with BeautifulSoup
   soup = BeautifulSoup(response.text, 'html.parser')
  
   # Step 3: Find all elements with class="page"
   page_elements = soup.find_all("div", class_="page")
  
   # Step 4: Save each element's text content in a list
   pages_list = [page.text.strip() for page in page_elements]
  
   print("Content of elements with class 'page':")
   for i, page in enumerate(pages_list, start=1):
       print(f"Page {i}:")
       print(page)
       print("-" * 20)
else:
   print(f"Failed to retrieve the webpage. Status code: {response.status_code}")

Explication :

  • Envoyer une requête : Nous utilisons les requêtes pour envoyer une demande GET à l'URL, afin de récupérer le contenu HTML de la page web.
  • Analyser le HTML avec BeautifulSoup : Si la requête est réussie, BeautifulSoup analyse le HTML, ce qui nous permet de rechercher et d'interagir avec les éléments.
  • Recherche d'éléments par classe : Nous utilisons soup.find_all("div", class_="page") pour localiser tous les <div> avec la classe "page", en les renvoyant sous forme de liste.
  • Sauvegarde dans une liste : Nous extrayons et nettoyons le contenu textuel de chaque élément, en l'enregistrant dans une liste appelée pages_list.

Limites des sélecteurs de classe

Lors de l'utilisation de sélecteurs de classe, il faut être conscient des problèmes potentiels tels que la sélection d'éléments non désirés. La présence de plusieurs classes sur un même élément peut nécessiter un filtrage supplémentaire pour obtenir un ciblage précis.

Sélecteurs d'attributs

Les sélecteurs d'attributs vous permettent de cibler des éléments en fonction de la présence, de la valeur ou de la valeur partielle d'attributs spécifiques dans les balises HTML. Cette fonction est particulièrement utile lorsque les classes ou les identifiants ne sont pas uniques ou lorsque vous devez filtrer des éléments dotés d'attributs dynamiques, tels que data-* ou href dans les liens.

Dans l'exemple suivant, nous sélectionnons toutes les images de la page d'accueil. page web et extraire leur URL source ou src attributs. C'est ainsi que l'élément apparaît dans la structure html et dans la vue de la page web :

Dans le code suivant, nous utilisons BeautifulSoup pour analyser tous les fichiers <img> et en extraire les éléments src et les stocker dans une liste.

import requests
from bs4 import BeautifulSoup
# Step 1: Send a GET request to the website
url = "https://www.scrapethissite.com/pages/frames/"
response = requests.get(url)
if response.status_code == 200:
   # Step 2: Parse the HTML content with BeautifulSoup
   soup = BeautifulSoup(response.text, 'html.parser')
  
   # Step 3: Find all <img> elements with a 'src' attribute
   image_elements = soup.find_all("img", src=True)
  
   # Step 4: Save the 'src' attributes in a list
   images_list = [img['src'] for img in image_elements]
  
   print("Image sources found on the page:")
   for i, src in enumerate(images_list, start=1):
       print(f"Image {i}: {src}")
else:
   print(f"Failed to retrieve the webpage. Status code: {response.status_code}")

Limites des sélecteurs de classe

Les sélecteurs d'attributs ne peuvent sélectionner que des éléments dotés d'attributs statiques, ce qui les rend moins efficaces pour le contenu dynamique, comme les éléments chargés par JavaScript. Ils dépendent de structures HTML stables, de sorte que des modifications fréquentes de la présentation du site web peuvent les perturber. Ils ne peuvent pas non plus gérer des filtrages complexes ou des conditions multiples, ce qui limite leur précision. Ils peuvent également repérer des éléments involontaires si des attributs tels que la classe ou le nom sont partagés par plusieurs éléments.

Sélecteurs hiérarchiques

Les sélecteurs hiérarchiques vous permettent de cibler des éléments HTML en fonction de leur position et de leur relation avec d'autres éléments dans la structure HTML. Cette approche est particulièrement utile lorsque vous travaillez avec des tableaux ou des listes imbriquées, où les données sont organisées dans un format parent-enfant.

Dans cet exemple, nous utilisons des sélecteurs hiérarchiques pour extraire des données d'un tableau de statistiques sur les équipes de hockey trouvé sur cette page web.
Le tableau contient des lignes <tr> représentant chaque équipe, et chaque ligne contient des cellules <td> avec des informations telles que le nom de l'équipe, l'année, les victoires et les défaites. Chaque ligne comporte le class="team"et l'identifie comme une entrée pertinente dans nos données. En naviguant à partir de la page <table> to each <tr> and then to each <td>Nous pouvons ainsi capturer efficacement les données de manière structurée.

Vous trouverez ci-dessous deux images qui vous aideront à visualiser l'emplacement de ce tableau dans la structure HTML et la façon dont il apparaît sur la page web.

Examinons maintenant le code ci-dessous pour voir comment les sélecteurs hiérarchiques peuvent être utilisés pour extraire ces données :

import requests
from bs4 import BeautifulSoup

url = "https://www.scrapethissite.com/pages/forms/"

# Step 1: Send a GET request to the website
response = requests.get(url)

if response.status_code == 200:
   # Step 2: Parse the HTML content with BeautifulSoup
   soup = BeautifulSoup(response.text, 'html.parser')
  
   # Step 3: Find all rows in the table with class="team"
   teams_data = []
   team_rows = soup.find_all("tr", class_="team")
  
   # Step 4: Extract and store each team's data
   for row in team_rows:
       team = {
           "name": row.find("td", class_="name").text.strip(),
           "year": row.find("td", class_="year").text.strip(),
           "wins": row.find("td", class_="wins").text.strip(),
           "losses": row.find("td", class_="losses").text.strip(),
           "ot_losses": row.find("td", class_="ot-losses").text.strip(),
           "win_pct": row.find("td", class_="pct").text.strip(),
           "goals_for": row.find("td", class_="gf").text.strip(),
           "goals_against": row.find("td", class_="ga").text.strip(),
           "goal_diff": row.find("td", class_="diff").text.strip(),
       }
       teams_data.append(team)
  
   # Step 5: Display the extracted data
   for team in teams_data:
       print(team)
else:
   print(f"Failed to retrieve the webpage. Status code: {response.status_code}")

Limites des sélecteurs hiérarchiques

Les sélecteurs hiérarchiques dépendent de la structure HTML, de sorte que les modifications de la présentation peuvent facilement interrompre le script de scraping. Ils sont également limités au contenu statique et ne peuvent pas accéder aux éléments chargés dynamiquement par JavaScript. Ces sélecteurs nécessitent souvent une navigation précise dans les relations parent-enfant, ce qui peut s'avérer difficile dans les structures profondément imbriquées. En outre, ils peuvent être inefficaces lors de l'extraction de données dispersées, car ils doivent traverser plusieurs niveaux pour atteindre des éléments spécifiques.

Utiliser des sélecteurs combinés pour un meilleur ciblage

Chaque type de sélecteur a une fonction unique et leur combinaison nous permet de naviguer et de capturer des données avec précision à partir d'un contenu imbriqué ou structuré. Par exemple, l'utilisation d'un sélecteur d'ID permet de localiser la zone de contenu principale, les sélecteurs de classe permettent d'isoler les éléments répétés, les sélecteurs d'attributs permettent d'extraire des liens ou des images spécifiques, et les sélecteurs hiérarchiques permettent d'atteindre les éléments imbriqués dans des sections spécifiques. Ensemble, ces techniques constituent une approche puissante pour l'extraction de données structurées.

import requests
from bs4 import BeautifulSoup
# Target URL
url = "https://www.scrapethissite.com/pages/"
response = requests.get(url)
if response.status_code == 200:
   # Step 2: Parse the HTML content with BeautifulSoup
   soup = BeautifulSoup(response.text, 'html.parser')
  
   # Use ID selector to find the main content
   main_content = soup.find(id="pages")
  
   # Use class selector to find each "page" section
   pages = main_content.find_all("div", class_="page") if main_content else []
  
   # Extract details from each "page" section using hierarchical selectors
   for page in pages:
       # Use hierarchical selector to find title link and URL within each "page"
       title_tag = page.find("h3", class_="page-title")
       title = title_tag.text.strip() if title_tag else "No Title"
       link = title_tag.find("a")["href"] if title_tag and title_tag.find("a") else "No Link"
      
       # Use class selector to find the description
       description = page.find("p", class_="lead session-desc").text.strip() if page.find("p", class_="lead session-desc") else "No Description"
      
       print(f"Title: {title}")
       print(f"Link: {link}")
       print(f"Description: {description}")
       print("-" * 40)
else:
   print(f"Failed to retrieve the webpage. Status code: {response.status_code}")

Explication du code

  • Sélecteur d'ID : Nous commençons par localiser la zone de contenu principale avec id="pages", qui contient les sections dont nous avons besoin.
  • Sélecteur de classe : À l'intérieur de cette zone principale, nous utilisons class="page" pour trouver chaque bloc de contenu individuel représentant une section d'intérêt.
  • Sélecteurs hiérarchiques : Dans chaque bloc de "page", nous utilisons :
    • page.find("h3", class_="page-title") pour trouver le titre.
    • title_tag.find("a")["href"] pour récupérer l'URL du lien à partir de la balise d'ancrage dans le titre.
  • Sélecteur d'attributs: Nous accédons à l'attribut href de chaque lien pour capturer les URL exactes associées à chaque section.
  • Résultat : Le script imprime le titre, le lien et la description de chaque section, ce qui donne une vue structurée des données extraites de la page.

Conclusion

Dans le domaine du web scraping, savoir utiliser les sélecteurs HTML peut grandement améliorer vos compétences en matière d'extraction de données et vous permettre de collecter des informations importantes avec précision. Les sélecteurs tels que l'ID, la classe, l'attribut et les sélecteurs hiérarchiques ont chacun des utilisations spécifiques pour différentes tâches de scraping. En utilisant ces outils ensemble, vous pouvez relever un large éventail de défis en matière de web scraping en toute confiance.

Pour vous entraîner, des sites tels que Scrape This Site et Books to Scrape offrent de bons exemples pour vous aider à affiner vos compétences. Et si vous avez besoin d'aide ou si vous souhaitez entrer en contact avec d'autres personnes intéressées par le web scraping, n'hésitez pas à rejoindre notre canal Discord à l'adresse https://discord.com/invite/scrape.

Bon scraping !