Leçon 9/9 8 min

API et web scraping

Récupérez des données avec requests, explorez les API REST et faites du web scraping avec BeautifulSoup.

requests : faire des requêtes HTTP

La bibliothèque requests est l'outil n°1 pour communiquer avec des API en Python :

Prédisez avant de lire

Avant de dérouler : après r = requests.get("https://api.exemple.com/users"), comment savoir si la requête a réussi avant de faire confiance aux données ? Que signifient r.status_code valant 200 ou 404 ? Et comment récupérer le corps de la réponse JSON sous forme de dictionnaire Python ?

Voir la réponse

La requête peut échouer sans lever d'exception : il faut inspecter r.status_code. 200 = succès (OK) ; 404 = ressource introuvable (Not Found) ; 500 = erreur serveur. On vérifie donc le code (par ex. if r.status_code == 200:) avant d'exploiter le corps, sinon on risque de parser une page d'erreur. r.json() transforme le corps JSON en objet Python (dictionnaire ou liste) : data = r.json(). Astuce : r.raise_for_status() lève une exception automatiquement si le code indique une erreur.

import requests

# GET : récupérer des données
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
print(response.status_code)  # 200

# Convertir la réponse en dictionnaire Python
user = response.json()
print(user["name"])    # Leanne Graham
print(user["email"])   # Sincere@april.biz

Les méthodes principales :

  • requests.get(url) : récupérer des données
  • requests.post(url, json=data) : envoyer des données
  • requests.put(url, json=data) : mettre à jour
  • requests.delete(url) : supprimer

API REST : les concepts

Une API REST utilise des URLs pour organiser les données. Chaque URL représente une ressource :

import requests

# Liste des articles
articles = requests.get("https://api.example.com/articles").json()

# Un article spécifique
article = requests.get("https://api.example.com/articles/42").json()

# Créer un article
nouveau = requests.post("https://api.example.com/articles", json={
    "titre": "Mon article",
    "contenu": "Le contenu ici..."
})
print(nouveau.status_code)  # 201 (créé)

# Avec authentification (token)
headers = {"Authorization": "Bearer mon_token_secret"}
data = requests.get("https://api.example.com/profil", headers=headers)
print(data.json())

Codes HTTP courants : 200 = OK, 201 = Créé, 404 = Non trouvé, 401 = Non autorisé, 500 = Erreur serveur.

Web scraping avec BeautifulSoup

Le web scraping consiste à extraire des données depuis des pages HTML. BeautifulSoup rend ça simple :

import requests
from bs4 import BeautifulSoup

# Télécharger la page
response = requests.get("https://example.com")
soup = BeautifulSoup(response.text, "html.parser")

# Extraire le titre
titre = soup.find("h1").text
print(titre)

# Tous les liens
for lien in soup.find_all("a"):
    href = lien.get("href")
    texte = lien.text.strip()
    print(f"{texte} → {href}")

# Sélecteurs CSS (comme JavaScript)
prix = soup.select(".product-price")
for p in prix:
    print(p.text)

Installation : pip install requests beautifulsoup4

Éthique et bonnes pratiques

Le web scraping est puissant, mais il faut le faire de manière responsable :

  • robots.txt : vérifiez https://site.com/robots.txt avant de scraper. Ce fichier indique ce qui est autorisé.
  • Rate limiting : attendez entre chaque requête pour ne pas surcharger le serveur :
import time

urls = ["https://example.com/page1", "https://example.com/page2"]
for url in urls:
    response = requests.get(url)
    # Traiter la réponse...
    time.sleep(1)  # attendre 1 seconde entre chaque requête
  • Préférez les API : si un site offre une API, utilisez-la plutôt que le scraping.
  • Conditions d'utilisation : certains sites interdisent le scraping. Lisez les CGU.

Pour aller plus loin

Tu maîtrises maintenant les fondamentaux de Python. Voici les directions à explorer :

Références complètes : W3Schools Python · Python.org (docs FR)

Le couteau suisse est ouvert

Python ouvre des portes au-delà du web : data science, intelligence artificielle, automatisation système. C'est le couteau suisse du développeur moderne.

Avec HTML/CSS/JS pour le front, PHP pour le back web, et Python pour tout le reste, tu as un arsenal complet. Chaque langage a sa spécialité, et tu sais maintenant lire, modifier et débugger dans chacun d'eux.

La suite ? Choisis ta spécialisation (web, data, IA, automatisation) et creuse. Les fondations sont là. Construis.

À vous d'essayer

Une API renvoie souvent du JSON. Voici comment le parser et l'exploiter, sans réseau, avec le seul module json de la bibliothèque standard :

import json

# Réponse JSON simulée (comme celle d'une API)
reponse = '{"name": "Leanne Graham", "email": "leanne@april.biz", "tags": ["dev", "python"]}'

# Parser le JSON en dictionnaire Python
user = json.loads(reponse)

print(user["name"])           # Leanne Graham
print(user["email"])          # leanne@april.biz
print(", ".join(user["tags"]))  # dev, python

requests — making HTTP requests

The requests library is the #1 tool for communicating with APIs in Python:

Predict before reading

Before scrolling down: after r = requests.get("https://api.exemple.com/users"), how do you know whether the request succeeded before trusting the data? What does r.status_code equal to 200 or 404 mean? And how do you get the JSON response body as a Python dictionary?

See the answer

The request can fail without raising an exception: you need to inspect r.status_code. 200 = success (OK); 404 = resource not found (Not Found); 500 = server error. Check the code (e.g. if r.status_code == 200:) before using the body, otherwise you risk parsing an error page. r.json() turns the JSON body into a Python object (dictionary or list): data = r.json(). Tip: r.raise_for_status() automatically raises an exception if the status code indicates an error.

import requests

# GET — fetch data
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
print(response.status_code)  # 200

# Convert the response to a Python dictionary
user = response.json()
print(user["name"])    # Leanne Graham
print(user["email"])   # Sincere@april.biz

Main methods:

  • requests.get(url) — fetch data
  • requests.post(url, json=data) — send data
  • requests.put(url, json=data) — update
  • requests.delete(url) — delete

REST APIs — the concepts

A REST API uses URLs to organize data. Each URL represents a resource:

import requests

# List of articles
articles = requests.get("https://api.example.com/articles").json()

# A specific article
article = requests.get("https://api.example.com/articles/42").json()

# Create an article
new = requests.post("https://api.example.com/articles", json={
    "title": "My article",
    "content": "The content here..."
})
print(new.status_code)  # 201 (created)

# With authentication (token)
headers = {"Authorization": "Bearer my_secret_token"}
data = requests.get("https://api.example.com/profile", headers=headers)
print(data.json())

Common HTTP codes: 200 = OK, 201 = Created, 404 = Not Found, 401 = Unauthorized, 500 = Server Error.

Web scraping with BeautifulSoup

Web scraping means extracting data from HTML pages. BeautifulSoup makes it easy:

import requests
from bs4 import BeautifulSoup

# Download the page
response = requests.get("https://example.com")
soup = BeautifulSoup(response.text, "html.parser")

# Extract the title
title = soup.find("h1").text
print(title)

# All links
for link in soup.find_all("a"):
    href = link.get("href")
    text = link.text.strip()
    print(f"{text} → {href}")

# CSS selectors (like JavaScript)
prices = soup.select(".product-price")
for p in prices:
    print(p.text)

Installation: pip install requests beautifulsoup4

Ethics and best practices

Web scraping is powerful, but it must be done responsibly:

  • robots.txt — check https://site.com/robots.txt before scraping. This file indicates what's allowed.
  • Rate limiting — wait between requests to avoid overloading the server:
import time

urls = ["https://example.com/page1", "https://example.com/page2"]
for url in urls:
    response = requests.get(url)
    # Process the response...
    time.sleep(1)  # wait 1 second between each request
  • Prefer APIs — if a site offers an API, use it instead of scraping.
  • Terms of service — some sites prohibit scraping. Read the ToS.

Going further

You now master the fundamentals of Python. Here are directions to explore:

Full references: W3Schools Python · Python.org (docs)

The Swiss army knife is open

Python opens doors beyond the web — data science, artificial intelligence, system automation. It's the modern developer's Swiss army knife.

With HTML/CSS/JS for the front, PHP for the web back-end, and Python for everything else, you have a complete arsenal. Each language has its specialty, and you now know how to read, modify and debug in each of them.

What's next? Choose your specialization — web, data, AI, automation — and dig in. The foundations are there. Keep building.

Try it yourself

An API usually returns JSON. Here's how to parse and use it, without any network, using only the standard-library json module:

import json

# Simulated JSON response (like one from an API)
response = '{"name": "Leanne Graham", "email": "leanne@april.biz", "tags": ["dev", "python"]}'

# Parse the JSON into a Python dictionary
user = json.loads(response)

print(user["name"])           # Leanne Graham
print(user["email"])          # leanne@april.biz
print(", ".join(user["tags"]))  # dev, python

🎯 Pratique

S'entraîner (clique pour ouvrir) :

Prompt IA
Avec l'IA

Copiez ce prompt dans Claude ou ChatGPT :

Écris un script Python qui utilise l'API OpenWeather pour récupérer la météo d'une ville. Affiche la température, l'humidité et la description. Gère les erreurs (ville introuvable, problème réseau).
💬 Ré-explique sans regarder
Ré-explique sans regarder

Sans relire le script de l'IA : avec tes mots, quelles étapes enchaîne un appel API robuste avec requests ? (la requête, la vérification du code HTTP, le passage en dictionnaire, les erreurs à attraper)

Une bonne explication dit : on lance requests.get(url), on vérifie le succès (response.status_code == 200 ou response.raise_for_status()), puis on parse avec response.json() pour obtenir un dictionnaire. Côté erreurs : attraper requests.exceptions.RequestException (réseau, timeout, DNS) et gérer le cas « ville introuvable » via le code 404 renvoyé par l'API, pas via un except nu.
⚖️ Juge le code de l'IA
Accepter ou rejeter le code de l'IA

Tu demandes à l'IA un scraper qui parcourt plusieurs pages. Elle te propose ce code. Ton rôle de relecteur : l'accepter tel quel ou le rejeter, et dire pourquoi.

import requests
from bs4 import BeautifulSoup

for page in range(1, 101):
    url = f"https://example.com/articles?page={page}"
    try:
        html = requests.get(url).text
        soup = BeautifulSoup(html, "html.parser")
        print(soup.find("h1").text)
    except:
        pass
À rejeter. Deux problèmes graves. D'abord, 100 requêtes d'affilée sans aucun time.sleep() : c'est exactement la surcharge serveur que la leçon t'apprend à éviter, et un bon moyen de te faire bannir. Ensuite le except: nu suivi de pass avale TOUT en silence (timeout réseau, page 404, h1 absente qui fait planter .text sur un None) : tu crois scraper 100 pages, tu n'en récupères peut-être aucune sans le savoir. Le réflexe pro : time.sleep(1) dans la boucle, vérifier status_code, et attraper une exception précise (requests.exceptions.RequestException) en logguant l'erreur.
🧠 Rappel libre
Rappel libre

Sans remonter dans la leçon : pour récupérer des données d'une API REST, quelle méthode requests utilises-tu, et comment transformes-tu la réponse en dictionnaire Python ? Et avant de scraper un site, que vérifies-tu ?

On utilise requests.get(url) pour récupérer (GET), puis response.json() pour parser le corps JSON en dictionnaire Python (à ne pas confondre avec response.text qui renvoie du texte brut, ni response.content qui renvoie des bytes). Avant de scraper : on consulte le robots.txt du site et ses conditions d'utilisation, et on espace les requêtes (time.sleep) pour ne pas surcharger le serveur.
Quelle méthode HTTP est utilisée pour récupérer des données depuis une API ?
Comment convertir une réponse HTTP en dictionnaire Python avec requests ?
Que faut-il vérifier avant de scraper un site web ?
Pourquoi ajouter time.sleep(1) entre les requêtes de scraping ?
Prochaine étape

Vous avez fait le tour des bases : variables, listes, fonctions, fichiers et API. Il est temps d'assembler tout ça sur des projets concrets, guidés pas à pas, plutôt que de relire la théorie.

Passer aux projets →

Une erreur dans cette leçon, un passage flou, une question ? Écrivez-moi : chaque retour améliore ce cours.

Besoin d'un développeur pour votre projet ?

Réponse sous 24h · Sans engagement