Glassdoor est l'une des plus grandes plateformes de recherche d'emploi et d'entreprises sur le web ouvert, et ses pages de listes publiques portent un signal structuré abondant : intitulés de poste, entreprises qui recrutent, lieux des postes et notes en étoiles que les employés attribuent à ces entreprises. Les recruteurs la suivent pour évaluer la demande, les analystes l'utilisent pour étudier les tendances d'embauche entre secteurs, et les candidats comparent côte à côte les offres et les notes des employeurs. Tout cela figure sur la page publique de résultats de recherche dans une mise en page prévisible.
Ce guide vous montre comment scraper Glassdoor avec JavaScript et Node.js à l'aide de Cheerio. Vous construisez un petit scraper exécutable qui récupère une page publique de recherche d'emploi Glassdoor via la Crawling API, analyse l'intitulé du poste, l'entreprise, la localisation, la note de l'entreprise, l'estimation de salaire et le lien pour chaque annonce, gère la pagination et exporte le résultat en JSON et CSV. L'ensemble du guide reste limité aux données de listes publiques d'emplois et d'entreprises, et la section sur la légalité vers la fin n'est pas un texte standard, alors lisez-la avant de pointer ceci sur un volume réel.
Ce que vous allez construire
Un script Node.js qui prend une URL publique de recherche d'emploi Glassdoor, récupère le HTML rendu via la Crawling API et extrait un enregistrement structuré pour chaque carte d'emploi de la page de résultats. Nous prenons une recherche d'emplois de développeur comme exemple courant et extrayons ces champs par annonce :
- Titre l'intitulé du poste affiché sur la carte, par exemple "React Native Developer".
- Entreprise le nom de l'employeur qui recrute.
- Note la note en étoiles publique de l'entreprise, lorsque Glassdoor en affiche une pour cet employeur.
- Localisation la ville et la région où se situe le poste.
- Salaire la fourchette de salaire estimée lorsqu'elle est présente sur la carte.
- Date de publication depuis combien de temps l'annonce est en ligne, comme "30d+".
- Lien l'URL vers l'annonce d'emploi individuelle.
Pourquoi une simple requête échoue sur Glassdoor
Si vous demandez une URL de recherche Glassdoor avec un client HTTP nu, vous récupérez rarement les cartes d'emploi. Deux choses jouent contre vous. D'abord, Glassdoor rend la liste de résultats dans le navigateur avec JavaScript, si bien que le HTML initial est une coquille quasi vide tant que les scripts de la page ne s'exécutent pas. Ensuite, Glassdoor signale agressivement le trafic automatisé : les IP de centres de données et les schémas de requêtes qui ne ressemblent pas à un vrai navigateur sont défiés par un CAPTCHA, limités en débit ou bloqués avant même d'atteindre les listes rendues.
Un scraper Glassdoor fonctionnel a donc besoin de deux choses dans une seule requête : un navigateur qui rend réellement la page, et une IP que la plateforme interprète comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur headless plus un pool de proxys résidentiels rotatifs, mais les coudre ensemble et les maintenir en bonne santé représente l'essentiel du travail. La Crawling API regroupe les deux en un seul appel : vous lui envoyez l'URL, elle rend la page derrière une IP de confiance, et elle renvoie un HTML fini que vous analysez avec Cheerio.
La Crawling API vous donne deux tokens : un normal et un JavaScript. Glassdoor a besoin que la page soit rendue dans un vrai navigateur, alors utilisez votre token JavaScript pour chaque requête de ce guide. Le token normal renvoie la coquille non rendue et vos sélecteurs reviendront vides.
Prérequis
Il vous faut quelques éléments en place avant d'écrire le moindre code. Aucun ne prend longtemps.
JavaScript et Node.js de base. Vous devez être à l'aise pour écrire et lancer un script Node et installer des paquets avec npm. Si vous débutez avec Node, la documentation officielle et n'importe quel cours pour débutants vous amèneront au niveau que ce tutoriel suppose. Pour un guide plus complet, notre tutoriel sur la construction d'un web scraper avec Node.js couvre les bases.
Node.js 16 ou ultérieur. Vérifiez votre version avec node --version. Si vous ne l'avez pas, installez-le depuis le site de Node.js ou via un gestionnaire de versions comme nvm.
Un compte Crawlbase et un token. Inscrivez-vous, ouvrez votre dashboard et copiez votre token JavaScript depuis la page de documentation du compte. Le palier gratuit vous donne jusqu'à 5 000 requêtes sans carte, et vous ne payez que pour les requêtes réussies. Traitez le token comme un mot de passe : il authentifie vos requêtes, alors gardez-le hors du contrôle de version.
Mettre en place le projet
Créez un dossier de projet, initialisez-le et installez les deux bibliothèques dont le scraper a besoin.
node --version mkdir glassdoor-scraper && cd glassdoor-scraper npm init -y npm install crawlbase cheerio
Deux dépendances font le travail : crawlbase est le client Node officiel de la Crawling API, et cheerio analyse le HTML renvoyé avec une API de style jQuery pour que vous puissiez extraire les champs individuels par sélecteur CSS. Créez un fichier nommé scraper.js dans ce dossier et ajoutez le code des étapes ci-dessous.
Étape 1 : Récupérer la page de recherche rendue
Commencez par obtenir la page finie. Importez la classe CrawlingAPI, initialisez-la avec votre token JavaScript et demandez une URL publique de recherche Glassdoor. Vérifier le code de statut avant d'analyser garde les échecs bruyants plutôt que silencieux.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const glassdoorPageURL = 'https://www.glassdoor.com/Job/new-york-ny-react-native-developer-jobs-SRCH_IL.0,11_IC1132348_KO12,34.htm'; api .get(glassdoorPageURL) .then((response) => { if (response.statusCode === 200) { console.log(response.body.slice(0, 500)); } }) .catch((error) => console.error('API request error:', error));
Lancez le script avec node scraper.js et vous devriez voir un véritable balisage d'emplois Glassdoor en haut du corps, et non une coquille dépouillée. Cela confirme que le rendu fonctionne avant d'écrire le moindre sélecteur. La Crawling API utilise le token JavaScript que vous avez fourni pour rendre la page dans un vrai navigateur, donc les cartes d'emploi sont présentes dans le HTML que vous récupérez.
Cette première requête vient de renvoyer une page de recherche Glassdoor entièrement rendue sans navigateur headless ni proxy de votre côté. La Crawling API exécute la page dans un vrai navigateur, fait tourner des IP résidentielles côté serveur et gère les CAPTCHAs que Glassdoor lance aux scrapers, si bien que vous obtenez un HTML fini à partir d'un seul appel. Pointez-la d'abord vers une recherche d'emploi publique sur le palier gratuit, puis ajoutez votre parseur.
Étape 2 : Analyser chaque carte d'emploi avec Cheerio
Avec le HTML rendu en main, chargez-le dans Cheerio et parcourez les cartes d'emploi. Glassdoor liste les résultats dans un conteneur "Jobs List", chaque annonce dans sa propre carte, alors vous sélectionnez chaque carte, puis vous lisez le titre, l'entreprise, la note, la localisation, le salaire, la date de publication et le lien à l'intérieur. Lire chaque champ de façon défensive empêche une valeur manquante de faire planter l'exécution.
const cheerio = require('cheerio'); function parseDataFromHTML(html) { const $ = cheerio.load(html); const searchResults = { resultInfo: '', jobs: [], }; // Result summary (for example "1,200 React Native Developer Jobs") searchResults.resultInfo = $('.SearchResultsHeader_jobCount__12dWB') .text() .trim(); // One record per job card $('ul[aria-label="Jobs List"] .jobCard').each((_, element) => { const card = $(element); const title = card.find('.JobCard_seoLink__WdqHZ').text().trim(); const company = card .find('.EmployerProfile_employerName__Xemli') .text() .trim(); const rating = card .find('.EmployerProfile_ratingContainer__N4hxE') .text() .trim(); const location = card.find('.JobCard_location__N_iYE').text().trim(); const postDate = card .find('.JobCard_listingAge__KuaxZ') .text() .trim(); const salary = card .find('.JobCard_salaryEstimate___m9kY') .text() .trim(); let link = card.find('.JobCard_seoLink__WdqHZ').attr('href'); if (link && link.startsWith('/')) { link = new URL(link, 'https://www.glassdoor.com').href; } if (title) { searchResults.jobs.push({ title, company, rating: rating || 'Rating not available', location, salary, postDate, link: link || '', }); } }); return searchResults; }
Quelques détails gardent ceci fidèle à la page. Le résumé des résultats provient de .SearchResultsHeader_jobCount__12dWB, et chaque annonce réside dans une .jobCard à l'intérieur du conteneur ul[aria-label="Jobs List"]. Dans une carte, le titre et son lien proviennent tous deux de l'ancre .JobCard_seoLink__WdqHZ, l'entreprise de .EmployerProfile_employerName__Xemli, la note publique de l'entreprise de .EmployerProfile_ratingContainer__N4hxE, la localisation de .JobCard_location__N_iYE, la date de publication de .JobCard_listingAge__KuaxZ et l'estimation de salaire de .JobCard_salaryEstimate___m9kY. Le lien est lu depuis l'attribut href de l'ancre et résolu en URL absolue pour qu'il fonctionne en dehors de la page.
Les noms de classes de Glassdoor (les suffixes JobCard_* et EmployerProfile_* ci-dessus) sont générés et changent sans préavis. Traitez les sélecteurs comme un modèle de départ, pas comme un contrat. Quand un champ revient vide, ré-inspectez la page en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. La maintenance périodique des sélecteurs est normale pour tout scraper en production, et non le signe que quelque chose est cassé.
Étape 3 : Assembler le script complet avec export JSON et CSV
Reliez maintenant la récupération et l'analyse en un seul script exécutable, puis écrivez les enregistrements sur le disque à la fois en JSON et en CSV. Le guide historique utilisait un endpoint Express pour déclencher le crawl, mais un simple script réduit le nombre de pièces mobiles ; vous pourrez l'envelopper dans un endpoint plus tard si vous en voulez un.
const fs = require('fs'); const { CrawlingAPI } = require('crawlbase'); const cheerio = require('cheerio'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); async function crawl(pageUrl) { const response = await api.get(pageUrl); if (response.statusCode === 200) return response.body; console.error(`Request failed: ${response.statusCode}`); return null; } function toCsv(rows) { const headers = [ 'title', 'company', 'rating', 'location', 'salary', 'postDate', 'link', ]; const escape = (value) => `"${String(value).replace(/"/g, '""')}"`; const lines = [headers.join(',')]; for (const row of rows) { lines.push(headers.map((h) => escape(row[h])).join(',')); } return lines.join('\n'); } async function main() { const url = 'https://www.glassdoor.com/Job/new-york-ny-react-native-developer-jobs-SRCH_IL.0,11_IC1132348_KO12,34.htm'; const html = await crawl(url); if (!html) return; const data = parseDataFromHTML(html); fs.writeFileSync('glassdoor.json', JSON.stringify(data, null, 2)); fs.writeFileSync('glassdoor.csv', toCsv(data.jobs)); console.log(`Saved ${data.jobs.length} jobs to JSON and CSV`); } main();
Collez la fonction parseDataFromHTML de l'Étape 2 dans le même fichier pour que main puisse l'appeler. Lancez-le avec node scraper.js et vous obtenez deux fichiers : glassdoor.json avec les enregistrements structurés complets et glassdoor.csv prêt à ouvrir dans un tableur. L'utilitaire toCsv entoure chaque champ de guillemets et double tout guillemet intégré, ce qui compte ici car les intitulés de poste et les localisations contiennent fréquemment des virgules.
À quoi ressemble la sortie
Le fichier JSON contient le résumé des résultats plus un objet par emploi, chacun avec le titre, l'entreprise, la note publique, la localisation, l'estimation de salaire, la date de publication et le lien.
{ "resultInfo": "React Native Developer Jobs in New York, NY", "jobs": [ { "title": "React Native Developer", "company": "Example Tech Inc", "rating": "4.1", "location": "New York, NY", "salary": "$110K - $140K (Employer est.)", "postDate": "30d+", "link": "https://www.glassdoor.com/job-listing/react-native-developer" }, { "title": "Senior Mobile Engineer", "company": "Acme Software", "rating": "3.8", "location": "Remote", "salary": "$130K - $160K (Glassdoor est.)", "postDate": "5d", "link": "https://www.glassdoor.com/job-listing/senior-mobile-engineer" } ] }
Le CSV reflète les mêmes lignes d'emploi avec une ligne d'en-tête, donc il se glisse directement dans Excel, Google Sheets ou tout pipeline de données qui lit des fichiers délimités.
title,company,rating,location,salary,postDate,link "React Native Developer","Example Tech Inc","4.1","New York, NY","$110K - $140K (Employer est.)","30d+","https://www.glassdoor.com/job-listing/react-native-developer" "Senior Mobile Engineer","Acme Software","3.8","Remote","$130K - $160K (Glassdoor est.)","5d","https://www.glassdoor.com/job-listing/senior-mobile-engineer"
Gérer la pagination
Une seule page de recherche est une démo ; un vrai travail extrait chaque page de résultats. Glassdoor pagine ses URL de recherche en ajoutant un segment de page, vous pouvez donc boucler sur les numéros de page, récupérer chacun via la Crawling API, l'analyser avec la même fonction et vous arrêter quand une page ne renvoie aucune carte. Comme chaque page de résultats partage la même structure de carte, le parseur que vous avez déjà écrit fonctionne sur toutes sans modification.
async function scrapeAllPages(baseUrl, maxPages) { const allJobs = []; for (let page = 1; page <= maxPages; page++) { // Glassdoor adds the page number before the .htm extension const pageUrl = baseUrl.replace('.htm', `_IP${page}.htm`); const html = await crawl(pageUrl); if (!html) break; const { jobs } = parseDataFromHTML(html); if (jobs.length === 0) break; // no more results allJobs.push(...jobs); console.log(`Page ${page}: ${jobs.length} jobs`); // Pace requests so you stay under the rate limit await new Promise((r) => setTimeout(r, 2000)); } return allJobs; }
Le token exact de pagination dans l'URL peut changer, alors vérifiez quelques vrais liens "page suivante" dans votre navigateur et faites correspondre le motif. Les habitudes importantes se transposent à n'importe quelle cible : bouclez jusqu'à épuisement des résultats, et mettez un court délai entre les requêtes pour ne pas marteler le site. Pour en savoir plus sur les pages rendues et chargées en JavaScript comme celle-ci, consultez notre guide sur le crawl des sites JavaScript.
Rester débloqué
Même avec le rendu géré, Glassdoor surveille le trafic en forme de scraper. Quelques habitudes gardent une exécution saine, et elles s'appliquent à toute cible commerciale difficile.
- Rythmez vos requêtes. Introduisez un délai entre les récupérations de pages plutôt que de marteler la recherche dans une boucle serrée. Étaler les requêtes est le facteur le plus déterminant pour rester sous les limites de débit de Glassdoor.
- Appuyez-vous sur la rotation. Un pool d'IP résidentielles répartit les requêtes sur de nombreuses adresses de vrais utilisateurs pour qu'aucune seule ne déclenche une limite ou un CAPTCHA. La Crawling API s'en charge pour vous ; si vous montez votre propre pile, c'est la partie à bien faire.
- Lisez les codes de statut. Une exécution qui se met à renvoyer des défis ou des réponses non-200 vous dit que le rythme actuel ou le palier d'IP ne suffit plus. Traitez cela comme un signal pour réduire la cadence, pas comme un bruit à ignorer.
Pour le guide plus large, voyez comment scraper des sites web sans se faire bloquer. Si vous voulez des données d'emploi similaires sur une autre plateforme, le même schéma récupérer-puis-analyser se transpose directement au scraping des annonces d'emploi Indeed et au scraping des emplois Monster avec Python.
Est-il légal de scraper Glassdoor ?
Que le scraping de Glassdoor soit autorisé ou non dépend des conditions d'utilisation de Glassdoor, de votre juridiction et de ce que vous faites des données. Les conditions de Glassdoor restreignent l'accès automatisé, donc le scraping peut aller à l'encontre de ces conditions quel que soit le soin apporté à votre outillage. Rien dans le code ici n'y change quoi que ce soit ; cela ne fait que faire fonctionner la partie technique. Lisez les conditions d'utilisation de Glassdoor et son robots.txt, respectez les attentes de débit qu'ils énoncent, et traitez les deux comme la limite de ce que vous collectez.
Ce guide est délibérément limité aux données de listes publiques d'emplois et d'entreprises : l'intitulé du poste, l'entreprise qui recrute, la localisation, l'estimation de salaire, la date de publication, le lien et la note publique en étoiles de l'entreprise que n'importe qui peut voir sur une page de recherche sans se connecter. C'est différent des données personnelles de la plateforme. Les avis individuels d'employés, les comptes-rendus d'entretien et les personnes qui les ont rédigés sont des données personnelles. Traitez les notes d'entreprise comme un signal agrégé sur un employeur, ne constituez jamais de profils d'évaluateurs individuels, et ne republiez pas l'avis d'une personne lié à son identité. Tout ce qui est derrière une connexion, scrapé à grande échelle ou impliquant des individus identifiables fait intervenir le droit de la vie privée comme le RGPD et le CCPA, et cela est carrément hors du périmètre ici.
Si votre projet a besoin de plus que des listes publiques, la bonne voie est une voie autorisée, pas un scraper plus astucieux. Glassdoor et sa maison mère exploitent des programmes officiels de partenariat et d'API qui exposent les données d'employeurs et d'annonces avec des conditions d'utilisation claires, des règles d'attribution et des droits commerciaux. Ce sont les bons outils lorsque vous avez besoin de gros volumes, d'une structure garantie ou du droit de réutiliser les données commercialement. Lorsque vous n'êtes pas sûr qu'un usage soit autorisé, obtenez une permission ou un accord de données plutôt que de supposer que le silence vaut consentement.
Points clés
- Glassdoor rend les listes côté client et bloque fort. Une simple requête renvoie une coquille vide ou un CAPTCHA, vous devez donc rendre la page derrière une IP de confiance, avec le token JavaScript, avant de l'analyser.
- La Crawling API fait les deux en un seul appel. Elle rend la page dans un vrai navigateur, fait tourner des IP résidentielles et gère les CAPTCHAs, en renvoyant un HTML fini que vous analysez avec Cheerio.
-
Cheerio extrait les champs. Sélectionnez chaque
.jobCarddans la Jobs List, puis lisez titre, entreprise, note, localisation, salaire, date de publication et lien, et attendez-vous à ce que les noms de classes générés dérivent. - Paginez et exportez. Bouclez sur les segments de page de Glassdoor jusqu'à épuisement des résultats, rythmez vos requêtes et écrivez les enregistrements structurés à la fois en JSON et en CSV.
- Restez sur les données publiques. Ne collectez que les listes publiques d'emplois et d'entreprises, traitez les avis individuels et leurs auteurs comme des données personnelles, respectez les CGU et le robots.txt, et préférez l'API officielle de Glassdoor ou son programme de partenariat pour le volume ou l'usage commercial.
Foire aux questions
Puis-je construire un scraper Glassdoor dans un langage autre que JavaScript ?
Oui. Ce guide utilise JavaScript avec Cheerio, mais la même approche fonctionne dans n'importe quel langage. La Crawling API dispose de bibliothèques et de SDK pour plusieurs langages, donc vous récupérez le HTML rendu de la même façon et l'analysez avec l'analyseur HTML que votre pile préfère, comme BeautifulSoup en Python. Les sélecteurs et les champs restent les mêmes ; seule la syntaxe d'analyse change.
Pourquoi une simple requête renvoie-t-elle des données incomplètes de Glassdoor ?
Parce que Glassdoor rend sa liste d'emplois côté client avec JavaScript et défie le trafic automatisé avec des CAPTCHAs. Une requête HTTP brute depuis une IP de centre de données renvoie généralement une coquille vide ou une page de blocage plutôt que les cartes d'emploi. Pour obtenir une page complète, vous devez la rendre derrière une IP de confiance, ce que la Crawling API gère pour vous lorsque vous utilisez le token JavaScript.
Mes sélecteurs renvoient des valeurs vides. Qu'est-ce qui a changé ?
Presque à coup sûr le balisage de Glassdoor. Ses noms de classes générés comme JobCard_seoLink__WdqHZ changent sans préavis, donc des sélecteurs qui fonctionnaient le mois dernier peuvent casser. Ré-inspectez une page en direct dans les outils de développement de votre navigateur, mettez à jour les sélecteurs dans parseDataFromHTML, et vous êtes de nouveau opérationnel. La maintenance périodique des sélecteurs est normale pour tout scraper en production.
Vais-je me faire bloquer en scrapant Glassdoor ?
Cela peut arriver si vous envoyez trop de requêtes trop vite depuis une seule adresse. La Crawling API réduit ce risque en faisant tourner des IP résidentielles et en gérant les CAPTCHAs pour vous, mais vous devriez tout de même rythmer vos requêtes, ajouter des délais entre les pages et surveiller les codes de statut pour pouvoir réduire la cadence lorsque des défis apparaissent. Ces habitudes comptent sur toute cible commerciale difficile.
Puis-je scraper les avis individuels d'employés et les noms des évaluateurs ?
C'est hors du périmètre de ce guide, et pour de bonnes raisons. Les avis individuels et les personnes qui les ont rédigés sont des données personnelles, ce qui fait intervenir le droit de la vie privée comme le RGPD et le CCPA. Utilisez la note publique de l'entreprise comme un signal agrégé sur un employeur, ne construisez pas de profils d'évaluateurs individuels, et ne republiez pas l'avis d'une personne lié à son identité. Pour tout ce qui dépasse les listes publiques, utilisez l'API officielle de Glassdoor ou son programme de partenariat.
Glassdoor a-t-il une API officielle ?
Glassdoor et sa maison mère exploitent des programmes officiels de partenariat et d'API qui exposent les données d'employeurs et d'annonces sous des conditions claires, avec des règles d'attribution et des droits commerciaux définis. Si vous avez besoin de gros volumes, d'une structure garantie ou du droit de réutiliser les données commercialement, cette voie autorisée est la bonne. Ce scraper de données publiques convient mieux à la recherche, au prototypage et à l'analyse à plus petite échelle lorsqu'un accord officiel n'est pas justifié.
Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.
Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.

