Comment construire un agrégateur de sites d'emploi : sources, déduplication et fraîcheur
Un bon agrégateur d'offres d'emploi repose sur trois problèmes d'ingénierie : où trouver les annonces, comment les dédupliquer et comment les garder à jour. Résolvez ces problèmes et le scraping devient la partie facile — voici le plan.
Un agrégateur de sites d'emploi est un moteur de recherche pour les annonces d'emploi : il récupère les annonces de nombreuses sources et les affiche en un seul endroit. Les parties difficiles ne sont pas les requêtes HTTP — elles consistent à choisir les bonnes sources, à dédupliquer la même annonce qui apparaît sur cinq sites, et à garder tout à jour pour ne pas montrer des postes déjà pourvus le mois dernier. Si vous réussissez ces trois points, vous avez un produit défendable ; si vous échouez, vous avez un flux obsolète et rempli de doublons qui érode la confiance. Ce guide est le plan d'ingénierie : mélange des sources, déduplication canonique, fraîcheur, le vertical SERP des emplois, et les lignes légales à respecter. C'est informatif, pas un conseil juridique.
Source de niveau 1 : points d'accès publics ATS
Les données d'emploi les plus propres sur Internet ne se trouvent pas sur les sites d'emploi — elles se trouvent sur les pages de carrière des entreprises alimentées par des systèmes de suivi des candidatures, dont la plupart exposent des JSON structurés. Greenhouse, Lever, Ashby, BambooHR, iCIMS, Paylocity et Workday proposent tous des annonces que vous pouvez demander directement, sans analyse HTML. Un agrégateur open-source qui tire de ces sept sources les récupère en parallèle et ajuste le nombre de travailleurs aux limites de taux de chaque plateforme — environ 50 en simultané pour Workday, 30 pour Greenhouse/Lever/iCIMS, 10 pour BambooHR, et 5 pour les plus restrictifs. Ce niveau vous donne des titres canoniques, des emplacements, des fourchettes salariales et des URL d'application directement de l'employeur, ce qui en fait l'épine dorsale de tout agrégateur sérieux.
import httpx
# Greenhouse exposes a public board JSON endpoint per company slug
def fetch_greenhouse(slug: str) -> list[dict]:
url = f"https://boards-api.greenhouse.io/v1/boards/{slug}/jobs?content=true"
r = httpx.get(url, timeout=20)
r.raise_for_status()
jobs = r.json().get("jobs", [])
return [{
"source": "greenhouse",
"external_id": str(j["id"]),
"title": j["title"],
"company": slug,
"location": (j.get("location") or {}).get("name"),
"apply_url": j["absolute_url"],
"updated_at": j.get("updated_at"),
} for j in jobs]
rows = fetch_greenhouse("examplecompany")
print(len(rows), "roles")
Pour trouver les entreprises à interroger, récoltez les slugs ATS à grande échelle à partir d'un index web plutôt qu'à la main — scanner les archives d'URL de Common Crawl pour les motifs de domaine ATS peut révéler des dizaines de milliers d'identifiants d'entreprises. Cette exploration de découverte est elle-même un travail de scraping ; dirigez-la à travers un pool de proxy de centre de données puisque l'index est indulgent et que la vitesse compte plus que la réputation IP ici.
Source de niveau 2 : le vertical SERP des emplois
Les flux ATS manquent tout ce qui est posté uniquement sur les sites d'agrégateurs, les sites régionaux ou l'expérience d'emploi propre à Google. La manière efficace de couvrir cette longue traîne sans scrapper une douzaine de sites individuellement est le vertical SERP des emplois — une requête structurée qui renvoie les emplois que Google met en avant pour un rôle et un lieu, déjà normalisés. Notre API SERP expose un vertical des emplois aux côtés des actualités, des images et des achats, vous permettant de récupérer les annonces par mot-clé et géo en JSON et de les intégrer dans le même pipeline :
import httpx
def fetch_jobs_serp(query: str, location: str) -> list[dict]:
r = httpx.get(
"https://api.quantumproxies.io/serp",
params={"engine": "google_jobs", "q": query,
"location": location, "api_key": "QP_API_KEY"},
timeout=30,
)
jobs = r.json().get("jobs", [])
return [{
"source": "jobs_serp",
"external_id": j.get("job_id"),
"title": j.get("title"),
"company": j.get("company_name"),
"location": j.get("location"),
"apply_url": (j.get("apply_options") or [{}])[0].get("link"),
} for j in jobs]
serp_rows = fetch_jobs_serp("react developer", "Austin, TX")
Exécutez la même requête sur vos villes cibles selon un calendrier et vous aurez une couverture géographique qu'aucun flux ATS unique ne fournit. Parce que les résultats SERP varient selon la localisation, ciblez géographiquement chaque requête — notre article sur comment fonctionne le scraping SERP en 2026 couvre les mécanismes géographiques et de pagination.
Récupérez le vertical des emplois depuis l'API SERP

Dédupliquez par clé canonique
Le même emploi apparaît régulièrement sur le site de l'entreprise, deux agrégateurs et une carte d'emploi Google. Le montrer quatre fois est le moyen le plus rapide de paraître défaillant. La solution standard est une clé canonique : normalisez et hachez la combinaison du titre de l'emploi, de l'entreprise, du lieu et — lorsque disponible — de l'ID d'emploi externe de la source. Mettez en minuscule, supprimez la ponctuation et réduisez les espaces avant de hacher pour que "Ingénieur logiciel Sr." et "ingénieur logiciel senior" se regroupent ensemble.
import re, hashlib
def canonical_key(job: dict) -> str:
def norm(s):
return re.sub(r"[^a-z0-9]+", " ", (s or "").lower()).strip()
basis = "|".join([
norm(job.get("title")),
norm(job.get("company")),
norm(job.get("location")),
(job.get("external_id") or ""),
])
return hashlib.sha1(basis.encode()).hexdigest()
def dedupe(rows: list[dict]) -> list[dict]:
seen, out = set(), []
for job in rows:
k = canonical_key(job)
if k not in seen:
seen.add(k)
out.append(job)
return out
La fraîcheur est une caractéristique, pas une réflexion après coup
La crédibilité d'un site d'emploi repose sur sa fraîcheur. Deux mécanismes la maintiennent : re-tirez chaque source selon un calendrier (toutes les heures pour les flux ATS à fort volume, quotidiennement pour la longue traîne), et éliminez tout ce que vous n'avez pas revu dans une fenêtre glissante — 30 jours est un défaut raisonnable, plus court pour les marchés à évolution rapide. Suivez un horodatage de dernière vue par source et un décompte quotidien pour repérer quand une source se casse silencieusement ; un agrégateur qui surveille son propre volume peut ouvrir une alerte dès que les chiffres d'une plateforme chutent brutalement. Notre note sur l'exécution de scrapers en tant que logiciel de production couvre la planification, la détection de dérive et l'alerte.
Les lignes légales à respecter
Les données d'emploi sont là où la législation sur le scraping devient sérieuse, car les annonces peuvent contenir des données personnelles (noms de recruteurs, coordonnées) et des descriptions détaillées sont protégées par le droit d'auteur. L'autorité française de protection des données a infligé une amende de 240 000 € à l'entreprise KASPR pour avoir scrappé des données de contact LinkedIn sans consentement approprié ; les pénalités RGPD peuvent atteindre 20 millions d'euros ou 4 % du chiffre d'affaires mondial, et les dommages pour violation de droits d'auteur ont atteint 150 000 $ par œuvre dans des affaires américaines. La posture la plus sûre est structurelle : préférez les flux ATS autorisés et le SERP des emplois plutôt que de forcer les murs de connexion, stockez les champs factuels (titre, entreprise, lieu) plutôt que de republier des descriptions complètes protégées par le droit d'auteur, et supprimez les données personnelles dont vous n'avez pas besoin. Notre aperçu de la légalité du scraping web en 2026 et la saga de conformité LinkedIn vont plus loin.

Où les proxies s'intègrent-ils
Le niveau ATS nécessite rarement des IP résidentielles, mais l'exploration de découverte, le vertical SERP et tout scraping direct de site le font — Google et les plus grands sites limitent le taux par IP et varient géographiquement leurs résultats. Dirigez-les à travers des proxies résidentiels rotatifs avec rotation par requête et ciblage géographique pour que chaque requête de ville provienne d'un emplacement correspondant. Gardez les niveaux séparés : centre de données bon marché pour l'index indulgent, résidentiel pour les cibles sensibles.
Questions fréquemment posées
Qu'est-ce qu'un agrégateur de sites d'emploi ?
C'est un moteur de recherche pour les annonces d'emploi qui collecte des annonces de nombreuses sources — pages de carrière d'entreprise, plateformes ATS, autres sites et le SERP des emplois — les normalise en un seul schéma, supprime les doublons, et les présente aux chercheurs d'emploi en un seul endroit consultable. Le travail d'ingénierie réside dans la recherche de sources, la déduplication et la fraîcheur, pas seulement dans le scraping.
Comment dédupliquez-vous les annonces d'emploi de plusieurs sources ?
Construisez une clé canonique en normalisant et en hachant le titre de l'emploi, l'entreprise, le lieu et l'ID d'emploi externe de la source. Mettez en minuscule, supprimez la ponctuation et réduisez les espaces d'abord pour que les variantes d'orthographe se regroupent ensemble. Conservez la première occurrence et supprimez les correspondances. Cela attrape le même rôle apparaissant sur le site de l'employeur, les agrégateurs et Google jobs.
Le scraping de sites d'emploi est-il légal ?
Cela dépend de la source, des données et de votre juridiction. Les champs d'annonces factuels publics présentent un risque moindre que les données personnelles ou les descriptions complètes protégées par le droit d'auteur, et contourner les murs de connexion augmente l'exposition de type CFAA. Les flux ATS autorisés et le SERP des emplois sont les voies les plus propres. Les entreprises ont été lourdement sanctionnées pour avoir scrappé des données personnelles — obtenez des conseils juridiques pour un usage commercial.
À quel point les données d'emploi agrégées doivent-elles être fraîches ?
Re-tirez les sources à fort volume comme les flux ATS toutes les heures et la longue traîne quotidiennement, puis éliminez toute annonce que vous n'avez pas revue dans une fenêtre glissante — 30 jours est un défaut commun. Suivez un horodatage de dernière vue par emploi et surveillez le volume par source pour détecter une source cassée avant que les utilisateurs ne voient des rôles obsolètes.
Traitez l'agrégation comme trois problèmes — sources, déduplication, fraîcheur — et le scraping devient un détail de soutien. Commencez par des flux ATS propres et le vertical SERP des emplois, dédupliquez sur une clé canonique, élaguez agressivement, et gardez les explorations sensibles sur des IP résidentielles rotatives. C'est la différence entre un produit de confiance et un cimetière de liens morts.