Comment extraire les offres d'emploi d'Indeed : Structure, Blocs et la Route SERP
Indeed est le plus grand site d'offres d'emploi sur le web et un indicateur en temps réel du marché du travail. Il est également protégé par Cloudflare avec des noms de classes qui tournent chaque semaine. Voici comment l'extraire de manière durable — et quand éviter le site entièrement.
Indeed attire environ 542 millions de visites par mois, ce qui fait de ses annonces l'un des signaux en temps réel les plus clairs pour le marché du travail — la demande d'embauche par rôle, les fourchettes salariales, quelles entreprises recrutent. C'est aussi un site React protégé par Cloudflare dont les noms de classes CSS visibles tournent assez souvent pour casser un scraper naïf en quelques semaines. Ce guide montre comment extraire les offres d'emploi d'Indeed de manière durable, comment les paginer et les dédupliquer, la réalité Cloudflare, et la verticale SERP des emplois qui vous permet d'éviter complètement le combat.
Lire la page de recherche, s'ancrer sur des attributs stables
L'unité de données d'Indeed est la page de résultats de recherche : la requête plus la localisation vous donne une page de cartes d'emploi. Le piège est de sélectionner sur les noms de classes hachés (des choses comme eu4oa1w0) qu'Indeed régénère. Ancrez-vous plutôt sur les attributs data-testid, qui changent beaucoup moins souvent :
import requests
from bs4 import BeautifulSoup
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
}
proxies = {"http": "http://USER:PASS@gate.quantumproxies.io:8000",
"https": "http://USER:PASS@gate.quantumproxies.io:8000"}
url = "https://www.indeed.com/jobs?q=python&l=New+York%2C+NY"
html = requests.get(url, headers=headers, proxies=proxies, timeout=30).text
soup = BeautifulSoup(html, "html.parser")
jobs = []
for card in soup.select("div.job_seen_beacon"):
title = card.find("a", class_="jcs-JobTitle")
company = card.find("span", attrs={"data-testid": "company-name"})
location = card.find("div", attrs={"data-testid": "text-location"})
jobs.append({
"title": title.get_text(strip=True) if title else None,
"company": company.get_text(strip=True) if company else None,
"location": location.get_text(strip=True) if location else None,
"jk": title["href"].split("jk=")[-1][:16] if title else None,
})
print(len(jobs), "jobs on page 1")
Chaque carte porte une clé d'emploi (jk) — un ID stable que vous utilisez pour dédupliquer à travers les pages et les exécutions. Stockez sur jk, pas l'URL, car la même annonce apparaît avec différents paramètres de suivi.
Pagination et sites par pays
Indeed pagine avec un paramètre start qui s'incrémente par 10. Et ce n'est pas un seul site — chaque pays est un sous-domaine : www.indeed.com pour les États-Unis, uk.indeed.com pour le Royaume-Uni, etc. Faites correspondre votre sortie proxy au pays que vous interrogez pour que la requête soit géographiquement cohérente :
def crawl(query, location, country="www", pages=5):
base = f"https://{country}.indeed.com/jobs"
for start in range(0, pages * 10, 10):
params = {"q": query, "l": location, "start": start}
html = requests.get(base, params=params, headers=headers,
proxies=proxies, timeout=30).text
# parse as above, yield rows
yield html
# freshness filter: fromage accepts only 1, 3, 7 or 14 days
# .../jobs?q=python&l=NYC&fromage=7
Une particularité à connaître : le filtre "publié dans" d'Indeed (fromage) n'accepte que 1, 3, 7 ou 14 jours — les autres valeurs sont ignorées, donc construisez votre logique de fraîcheur autour de ces catégories.

La réalité Cloudflare
Indeed est protégé par Cloudflare, donc une IP de datacenter avec une requête simple obtient souvent un défi au lieu de résultats. Les solutions sont la pile anti-bot habituelle : un User-Agent et un ensemble d'en-têtes de navigateur cohérents, et — le plus grand levier — une sortie résidentielle qui n'est pas pré-évaluée comme automatisation. Un proxy résidentiel se présente comme la connexion d'un utilisateur réel, ce qui permet à Cloudflare de servir la page. Lorsqu'un défi apparaît, faire correspondre l'empreinte du navigateur est aussi important que l'IP ; notre guide sur comment contourner Cloudflare en 2026 couvre où se situe la ligne.
Le raccourci : la verticale SERP des emplois
Si ce que vous voulez réellement, ce sont des données du marché du travail — pas spécifiquement le HTML d'Indeed — il y a un chemin plus simple. La verticale des emplois de Google agrège les annonces d'Indeed et de nombreux autres sites, et une API SERP renvoie cette verticale des emplois sous forme de JSON analysé : titre, entreprise, localisation, date de publication et source, pas de sélecteurs CSS à maintenir et pas de Cloudflare à combattre. Vous échangez un certain contrôle au niveau des champs pour un flux structuré stable à travers de nombreux sites à la fois, ce qui pour les analyses d'embauche agrégées est généralement la meilleure option. C'est le même raisonnement derrière la construction d'un agrégateur de sites d'emploi sur un flux SERP plutôt qu'un scraper par site.
Extraire la verticale des emplois sous forme de JSON propre
À quoi servent les données
Au-delà d'une recherche d'emploi, ces données alimentent une véritable analyse : l'étalonnage des salaires par rôle et par ville, le suivi de la demande pour des compétences spécifiques au fil du temps, les signaux d'embauche des concurrents (un rival qui recrute une nouvelle équipe est un indice stratégique), et l'enrichissement — associer les postes ouverts d'une entreprise avec des firmographics pour l'outbound. Associez-le avec les données salariales de Glassdoor et vous obtenez une image de compensation plus complète que chaque source seule.

Questions fréquemment posées
Pouvez-vous légalement extraire les offres d'emploi d'Indeed ?
Les offres d'emploi sont des données publiques, et collecter des annonces visibles publiquement est généralement défendable, mais les conditions d'Indeed restreignent l'accès automatisé et vous devriez éviter les données personnelles et respecter les limites de taux. De nombreuses équipes contournent la question des conditions en utilisant la verticale SERP des emplois agrégée au lieu d'extraire directement d'Indeed. Ceci est une information générale, pas un conseil juridique — examinez les conditions actuelles avant un grand projet.
Pourquoi mon scraper Indeed continue-t-il de casser ?
Deux raisons. Premièrement, Indeed fait tourner ses noms de classes CSS hachés, donc les sélecteurs ancrés sur eux échouent en quelques semaines — ancrez-vous plutôt sur les attributs data-testid et la clé d'emploi. Deuxièmement, Cloudflare commence à défier votre IP une fois qu'elle est signalée ; une sortie résidentielle et une empreinte de navigateur cohérente maintiennent la vraie page chargée. Corrigez les deux et le scraper se stabilise.
Comment puis-je extraire des emplois de plusieurs pays ?
Indeed sert chaque pays depuis son propre sous-domaine (www.indeed.com, uk.indeed.com, de.indeed.com, etc.). Interrogez le bon sous-domaine et passez par une sortie proxy dans ce pays pour que la requête soit géographiquement cohérente — sinon vous risquez d'obtenir des résultats incohérents ou redirigés. La verticale SERP des emplois accepte également un paramètre de pays si vous préférez ne pas gérer les sous-domaines.
La SERP des emplois de Google est-elle meilleure que l'extraction d'Indeed ?
Pour les analyses agrégées du marché du travail, généralement oui. La verticale des emplois renvoie les annonces d'Indeed et de nombreux autres sites sous forme de JSON structuré, sans sélecteurs rotatifs et sans défi Cloudflare à gérer. Vous perdez certains champs spécifiques à Indeed, mais vous gagnez un flux multi-source stable et beaucoup moins de maintenance. Extrayez directement d'Indeed uniquement lorsque vous avez besoin de champs qui se trouvent sur les pages d'Indeed.
Indeed récompense l'approche durable : ancrez-vous sur des attributs stables, dédupliquez par clé d'emploi, paginez par dizaines, et frappez avec une IP résidentielle pour que Cloudflare vous serve. Et lorsque vous avez seulement besoin du signal du marché du travail plutôt que du HTML exact d'Indeed, la verticale SERP des emplois vous le remet sous forme de JSON. Choisissez le chemin qui correspond à la quantité de contrôle des champs dont vous avez réellement besoin.