Guide pas à pas du web scraping en Python pour les débutants

Commentaires: 0

Python s'impose comme le meilleur choix pour le web scraping en raison de ses bibliothèques robustes et de sa syntaxe simple. Dans cet article, nous allons explorer les principes fondamentaux du web scraping et vous guider dans la mise en place de votre environnement Python pour créer votre premier web scraper. Nous vous présenterons les principales bibliothèques Python adaptées aux tâches de scraping, notamment Beautiful Soup, Playwright et lxml.

Librairies Python pour le web scraping

Python fournit plusieurs bibliothèques pour faciliter le web scraping. Voici quelques-unes des plus utilisées :

  • requests : une bibliothèque HTTP simple et élégante pour Python, utilisée pour envoyer des requêtes HTTP afin de récupérer des pages web.
  • Beautiful Soup : idéal pour analyser les documents HTML et XML. Il crée des arbres d'analyse à partir du code source de la page, ce qui facilite l'extraction des données.
  • lxml : connu pour sa rapidité et son efficacité, lxml est excellent pour analyser les documents XML et HTML.
  • Playwright : un outil robuste pour l'extraction de contenu dynamique et l'interaction avec les pages web.

Introduction aux requêtes HTTP

HTTP (HyperText Transfer Protocol) est un protocole de couche d'application pour le transfert de données sur le web. Vous saisissez une URL dans le navigateur, qui génère une requête HTTP et l'envoie au serveur web. Le serveur web renvoie ensuite la réponse HTTP au navigateur, qui la restitue sous la forme d'une page HTML. Pour le web scraping, vous devez imiter ce processus et générer des requêtes HTTP à partir de votre script afin d'obtenir le contenu HTTP des pages web de manière programmatique.

Mise en place de votre environnement

Tout d'abord, assurez-vous que Python est installé sur votre système. Vous pouvez le télécharger sur le site officiel de Python.

Un environnement virtuel permet de gérer les dépendances. Utilisez ces commandes pour créer et activer un environnement virtuel :


python -m venv scraping_env
source scraping_env/bin/activate

Ensuite, installez les paquets nécessaires à l'aide des commandes suivantes :


pip install requests
pip install beautifulsoup4 
pip install lxml

Construction d'un scraper web avec Beautiful Soup

Commençons par un simple web scraper utilisant la requête pour scraper du contenu HTML statique.

Faire une requête HTTP GET

Le type de requête HTTP le plus courant est la requête GET, qui est utilisée pour récupérer des données à partir d'une URL spécifiée. Voici un exemple de base de l'exécution d'une requête GET à l'adresse http://example.com.


import requests
url = 'http://example.com'
response = requests.get(url)

Traiter les réponses HTTP

La bibliothèque requests propose plusieurs façons de gérer et de traiter la réponse :

Vérifier le code d'état : s'assurer que la demande a abouti.


if response.status_code == 200:
    print('Request was successful!')
else:
    print('Request failed with status code:', response.status_code)

Extraction du contenu : extraire le texte ou le contenu JSON de la réponse.


# Obtenir le contenu de la réponse sous forme de texte
page_content = response.text
print(page_content)

# Obtenir le contenu de la réponse au format JSON (si la réponse est au format JSON)
json_content = response.json()
print(json_content)

Gestion des erreurs HTTP et des erreurs réseau

Les erreurs HTTP et réseau peuvent survenir lorsqu'une ressource n'est pas accessible, qu'une requête a dépassé le temps imparti ou que le serveur renvoie un statut HTTP d'erreur (par exemple, 404 Not Found, 500 Internal Server Error). Nous pouvons utiliser les objets d'exception soulevés par les requêtes pour gérer ces situations.


import requests

url = 'http://example.com'

try:
    response = requests.get(url, timeout=10)  # Set a timeout for the request
    response.raise_for_status()  # Raises an HTTPError for bad responses
except requests.exceptions.HTTPError as http_err:
    print(f'HTTP error occurred: {http_err}')
except requests.exceptions.ConnectionError:
    print('Failed to connect to the server.')
except requests.exceptions.Timeout:
    print('The request timed out.')
except requests.exceptions.RequestException as req_err:
    print(f'Request error: {req_err}')
else:
    print('Request was successful!')

Extraction de données à partir d'éléments HTML

Pour le web scraping, nous avons souvent besoin d'extraire des données du contenu HTML. Cette partie explique comment localiser et extraire des données à partir d'éléments HTML à l'aide de bibliothèques telles que Beautiful Soup ou lxml.

HTML (HyperText Markup Language) est le langage de balisage standard pour la création de pages web. Il se compose d'éléments imbriqués représentés par des balises, telles que <div>, <p>, <a>, etc. Chaque balise peut avoir des attributs et contenir du texte, d'autres balises ou les deux.

Les sélecteurs XPath et CSS offrent un moyen polyvalent de sélectionner des éléments HTML en fonction de leurs attributs ou de leur position dans le document.

Recherche de sélecteurs XPath et CSS

Lors du web scraping, l'extraction de données spécifiques à partir de pages web nécessite souvent d'identifier les bons sélecteurs XPath ou CSS pour cibler les éléments HTML. Voici comment trouver ces sélecteurs de manière efficace :

La plupart des navigateurs modernes sont dotés d'outils de développement intégrés qui vous permettent d'inspecter la structure HTML des pages web. Voici un guide étape par étape sur la manière d'utiliser ces outils :

  1. Outils de développement ouverts :
    • Dans Chrome : Faites un clic droit sur la page et sélectionnez "Inspecter" ou appuyez sur Ctrl+Shift+I (Windows/Linux) ou Cmd+Opt+I (Mac).
    • Dans Firefox : Cliquez avec le bouton droit de la souris sur la page et sélectionnez "Inspecter l'élément" ou appuyez sur Ctrl+Shift+I (Windows/Linux) ou Cmd+Opt+I (Mac).
  2. Inspecter l'élément :
    • Utilisez l'outil d'inspection (une icône de curseur) pour survoler et cliquer sur l'élément que vous souhaitez récupérer. L'élément est alors mis en évidence dans la vue de la structure HTML.
  3. Copier un sélecteur XPath ou CSS :
    • Cliquez avec le bouton droit de la souris sur l'élément HTML mis en évidence dans le volet des outils de développement.
    • Sélectionnez "Copier", puis choisissez "Copier XPath" ou "Copier le sélecteur" (sélecteur CSS).

1n.png

XPath: /html/body/div/h1

CSS Selector: body > div > h1

Extraction à l'aide de Beautiful Soup

Beautiful Soup est une bibliothèque Python pour l'analyse des documents HTML et XML. Elle fournit des méthodes et des attributs simples pour naviguer et rechercher dans la structure HTML.


from bs4 import BeautifulSoup
import requests

# URL de la page web à récupérer
url = 'https://example.com'

# Envoyer une requête HTTP GET à l'URL
response = requests.get(url)

# Analyser le contenu HTML de la réponse à l'aide de Beautiful Soup
soup = BeautifulSoup(response.content, 'html.parser')

# Utilisez le sélecteur CSS pour trouver toutes les balises <h1> qui se trouvent à l'intérieur des balises <div> # qui sont des enfants directs de la balise <body>
# qui sont des enfants directs de la balise <body>.
h1_tags = soup.select('body > div > h1')

# Itérer sur la liste des balises <h1> ; trouvées et imprimer leur contenu textuel
for tag in h1_tags:
    print(tag.text)

Traitement des erreurs d'analyse

Les erreurs d'analyse se produisent lorsque la structure HTML ou XML n'est pas conforme aux attentes, ce qui entraîne des problèmes d'extraction de données. Elles peuvent être gérées par des exceptions telles que AttributeError.


from bs4 import BeautifulSoup
import requests

# URL de la page web à récupérer
url = 'https://example.com'

# Envoyer une requête HTTP GET à l'URL
response = requests.get(url)

try:
    # Analyser le contenu HTML de la réponse à l'aide de Beautiful Soup
    soup = BeautifulSoup(response.content, 'html.parser')

    # Utilisez le sélecteur CSS pour trouver toutes les balises <h1> qui se trouvent à l'intérieur des balises <div> # qui sont des enfants directs de la balise <body>
    # qui sont des enfants directs de la balise <body>.
    h1_tags = soup.select('body > div > h1')

    # Itérer sur la liste des balises <h1> ; trouvées et imprimer leur contenu textuel
    for tag in h1_tags:
        print(tag.text)
except AttributeError as attr_err:
    # Gérer les cas où une erreur AttributeError pourrait se produire (par exemple, si le contenu de la réponse est None).
    print(f'Attribute error occurred: {attr_err}')
except Exception as parse_err:
    # Gérer toute autre exception pouvant survenir au cours de l'analyse syntaxique
    print(f'Error while parsing HTML: {parse_err}')

Extraction à l'aide de lxml

En plus de Beautiful Soup, une autre bibliothèque populaire pour analyser les documents HTML et XML en Python est lxml. Alors que BeautifulSoup se concentre sur la fourniture d'une interface pratique pour la navigation et la manipulation des données analysées, lxml est connu pour sa vitesse et sa flexibilité, ce qui en fait un choix privilégié pour les tâches critiques en termes de performances.


from lxml.html import fromstring
import requests

# URL de la page web à récupérer
url = 'https://example.com'

# Envoyer une requête HTTP GET à l'URL
response = requests.get(url)

# Analyse le contenu HTML de la réponse à l'aide de la méthode fromstring de lxml
parser = fromstring(response.text)

# Utilisez XPath pour trouver le contenu textuel de la première balise <h1>
# qui se trouve à l'intérieur d'une balise <div>, qui est un enfant direct de la balise <body>.
title = parser.xpath('/html/body/div/h1/text()')[0]

# Imprimer le titre
print(title)

Traitement des erreurs d'analyse

Similaire à Beautiful Soup, lxml vous permet de gérer les erreurs d'analyse de manière élégante en attrapant des exceptions comme lxml.etree.XMLSyntaxError.


from lxml.html import fromstring
from lxml import etree
import requests

# URL de la page web à récupérer
url = 'https://example.com'

# Envoyer une requête HTTP GET à l'URL
response = requests.get(url)

try:
    # Analyse le contenu HTML de la réponse à l'aide de la méthode fromstring de lxml
    parser = fromstring(response.text)

    # Utilisez XPath pour trouver le contenu textuel de la première balise <h1>
    # qui se trouve à l'intérieur d'une balise <div>, qui est un enfant direct de la balise <body>.
    title = parser.xpath('/html/body/div/h1/text()')[0]

    # Imprimer le titre
    print(title)
except IndexError:
    # Gérer le cas où la requête XPath ne renvoie aucun résultat
    print('No <h1> tag found in the specified location.')
except etree.XMLSyntaxError as parse_err:
    # Traiter les erreurs de syntaxe XML lors de l'analyse syntaxique
    print(f'Error while parsing HTML: {parse_err}')
except Exception as e:
    # Gérer les autres exceptions
    print(f'An unexpected error occurred: {e}')

Sauvegarde des données extraites

Une fois que vous avez réussi à extraire des données à partir d'éléments HTML, l'étape suivante consiste à enregistrer ces données. Python propose plusieurs options pour enregistrer les données extraites, notamment dans des fichiers CSV, des fichiers JSON et des bases de données. Voici un aperçu de la manière d'enregistrer les données extraites à l'aide de différents formats :

Enregistrement des données dans un fichier CSV

CSV (Comma-Separated Values) est un format simple et largement utilisé pour stocker des données tabulaires. Le module CSV de Python permet d'écrire facilement des données dans des fichiers CSV.


import csv

# Exemple de données
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Enregistrer les données dans un fichier CSV
with open('scraped_data.csv', mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['Title', 'Paragraph'])
    for paragraph in data['paragraphs']:
        writer.writerow([data['title'], paragraph])

print('Data saved to scraped_data.csv')

Enregistrement des données dans un fichier JSON

JSON (JavaScript Object Notation) est un format d'échange de données léger, facile à lire et à écrire. Le module JSON de Python fournit des méthodes pour enregistrer des données au format JSON.


import json

# Exemple de données
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Enregistrer les données dans un fichier JSON
with open('scraped_data.json', mode='w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=4)

print('Data saved to scraped_data.json')

Techniques avancées de scraping web avec Playwright

Playwright est un outil puissant qui permet de récupérer du contenu dynamique et d'interagir avec des éléments Web. Il peut prendre en charge des sites web à forte composante JavaScript, ce que les analyseurs HTML statiques ne peuvent pas faire.

Installez Playwright et configurez-le :


pip install playwright
playwright install

Récupération de contenu dynamique

Playwright vous permet d'interagir avec des éléments Web comme remplir des formulaires et cliquer sur des boutons. Il peut attendre que les requêtes AJAX soient terminées avant de poursuivre, ce qui le rend idéal pour le scraping de contenu dynamique.

2n.png

Le code fourni effectue du web scraping sur une page de produit Amazon en utilisant Playwright et lxml. Au départ, les modules nécessaires sont importés. Une fonction d'exécution est définie pour encapsuler la logique de scraping. La fonction commence par mettre en place un serveur proxy et lance une nouvelle instance de navigateur avec le proxy et en mode sans tête, ce qui nous permet d'observer les actions du navigateur. Dans le contexte du navigateur, une nouvelle page est ouverte et navigue jusqu'à l'URL du produit Amazon spécifié, avec un délai d'attente de 60 secondes pour garantir le chargement complet de la page.

Le script interagit ensuite avec la page pour sélectionner un style de produit spécifique à partir d'un menu déroulant et une option de produit en utilisant des localisateurs et des correspondances de texte. Après s'être assuré que ces interactions sont terminées et que la page est à nouveau entièrement chargée, le contenu HTML de la page est capturé.

Le contenu HTML est ensuite analysé à l'aide de la méthode fromstring de lxml pour créer un arbre d'éléments. Une requête XPath est utilisée pour extraire le contenu textuel du titre du produit à partir d'un élément spécifique portant l'ID productTitle. Le script inclut une gestion des erreurs pour gérer les cas où la requête XPath ne renvoie pas de résultats, où il y a des erreurs de syntaxe XML pendant l'analyse, ou toute autre exception inattendue. Enfin, le titre du produit extrait par tlxml est imprimé, et le contexte du navigateur et le navigateur sont fermés pour mettre fin à la session.

La fonction run est exécutée dans une session Playwright démarrée par sync_playwright, ce qui garantit que l'ensemble du processus est géré et exécuté dans un environnement contrôlé. Cette structure garantit la robustesse et la résilience aux erreurs lors de l'exécution de la tâche de web scraping.


from playwright.sync_api import Playwright, sync_playwright
from lxml.html import fromstring, etree


def run(playwright: Playwright) -> None:
   # Définir le serveur proxy
   proxy = {"server": "https://IP:PORT", "username": "LOGIN", "password": "PASSWORD"}

   # Lancer une nouvelle instance de navigateur avec le proxy spécifié et en mode sans tête.
   browser = playwright.chromium.launch(
       headless=False,
       proxy=proxy,
       slow_mo=50,
       args=['--ignore-certificate-errors'],
   )

   # Créer un nouveau contexte de navigation
   context = browser.new_context(ignore_https_errors=True)

   # Ouvrir une nouvelle page dans le contexte du navigateur
   page = context.new_page()

   # Naviguer vers la page produit Amazon spécifiée
   page.goto(
       "https://www.amazon.com/A315-24P-R7VH-Display-Quad-Core-Processor-Graphics/dp/B0BS4BP8FB/",
       timeout=10000,
   )

   # Attendre le chargement complet de la page
   page.wait_for_load_state("load")

   # Sélectionnez un style de produit spécifique dans le menu déroulant
   page.locator("#dropdown_selected_style_name").click()

   # Sélectionner une option de produit spécifique
   page.click('//*[@id="native_dropdown_selected_style_name_1"]')
   page.wait_for_load_state("load")

   # Obtenir le contenu HTML de la page chargée
   html_content = page.content()

   try:
       # Analyse du contenu HTML à l'aide de la méthode fromstring de lxml
       parser = fromstring(html_content)

       # Utiliser XPath pour extraire le contenu textuel du titre du produit
       product_title = parser.xpath('//span[@id="productTitle"]/text()')[0].strip()

       # Imprimer le titre du produit extrait
       print({"Product Title": product_title})
   except IndexError:
       # Gérer le cas où la requête XPath ne renvoie aucun résultat
       print('Product title not found in the specified location.')
   except etree.XMLSyntaxError as parse_err:
       # Traiter les erreurs de syntaxe XML lors de l'analyse syntaxique
       print(f'Error while parsing HTML: {parse_err}')
   except Exception as e:
       # Gérer les autres exceptions
       print(f'An unexpected error occurred: {e}')

   # Fermer le contexte du navigateur et le navigateur
   context.close()
   browser.close()


# Utilisez sync_playwright pour démarrer la session Playwright et exécuter le script.
with sync_playwright() as playwright:
   run(playwright)

Le web scraping avec Python est une méthode puissante pour récolter des données sur les sites web. Les outils présentés facilitent l'extraction, le traitement et le stockage des données web à des fins diverses. Dans ce processus, l'utilisation de serveurs proxy pour alterner les adresses IP et la mise en place de délais entre les requêtes sont essentiels pour contourner les blocages. Beautiful Soup est convivial pour les débutants, tandis que lxml est adapté au traitement de grands ensembles de données grâce à son efficacité. Pour des besoins de scraping plus avancés, en particulier avec des sites web JavaScript chargés dynamiquement, Playwright s'avère très efficace.

Commentaires:

0 Commentaires