Come estrarre recensioni e stipendi da Glassdoor nel 2026
Se lavori nell'HR analytics o nell'analisi del mercato del lavoro, probabilmente hai bisogno di dati strutturati da Glassdoor: valutazioni aziendali, recensioni dei dipendenti, range salariali. Ma nel 2026, estrarre recensioni e stipendi da Glassdoor è diventato significativamente più complesso. Il sito combina DataDome, Cloudflare Bot Management e fingerprinting TLS per bloccare l'accesso automatizzato. Questa guida mostra come accedere ai dati pubblici in modo legittimo, usando proxy residenziali e tecniche di impersonazione del browser.
Avviso legale: Questo articolo copre esclusivamente l'accesso a dati pubblici su Glassdoor, senza richiedere login. Devi rispettare i Termini di Servizio di Glassdoor, il Computer Fraud and Abuse Act (CFAA) negli Stati Uniti e il GDPR nell'UE per quanto riguarda i dati personali dei dipendenti. L'estrazione di dati dietro login o l'uso di credenziali rubate è illegale e non è trattata qui. Quando in dubbio, richiedi una licenza dati ufficiale.
Cosa è accessibile senza login e cosa è protetto
Glassdoor divide i suoi contenuti in due categorie: pagine pubbliche indicizzate dai motori di ricerca e dati gated dietro autenticazione. Comprendere questa distinzione è il primo passo per qualsiasi pipeline di estrazione legittima.
Dati pubblici (senza login)
Le pagine /Reviews/<company>-Reviews-E<id>.htm sono accessibili pubblicamente e mostrano:
- Valutazione generale dell'azienda (es. 3.8/5)
- Recensioni troncate (prime 2-3 righe di pros e cons)
- Titolo di lavoro del recensore
- Data della recensione
- Panoramica aziendale (settore, dimensioni, sede)
Questi dati sono sufficienti per analisi aggregate di sentiment aziendale, benchmarking di mercato e ricerca accademica. Una singola pagina aziendale può contenere da poche decine a oltre 10.000 recensioni, ma Glassdoor mostra solo le prime 10 per pagina con paginazione.
Dati gated (dietro login)
Le sezioni seguenti richiedono un account Glassdoor gratuito:
- Recensioni complete (testo integrale di pros e cons)
- Stipendi dettagliati per ruolo e località
- Interviste e domande di colloquio
- Foto degli uffici
Non tentare di estrarre dati dietro login con proxy o credenziali automatizzate. Questo viola i Termini di Servizio di Glassdoor e potenzialmente il CFAA. Se hai bisogno di dati salariali completi, considera l'API partner di Glassdoor o una licenza dati commerciale.
Lo stack anti-bot di Glassdoor: DataDome, Cloudflare e fingerprinting TLS
Glassdoor utilizza una difesa a più livelli che rende l'estrazione con strumenti tradizionali come requests o BeautifulSoup quasi impossibile. Ecco i componenti principali:
DataDome
DataDome è una soluzione anti-bot che analizza il comportamento dell'utente, il fingerprint del browser e la reputazione dell'IP. Assegna un punteggio di rischio a ogni richiesta e blocca quelle che superano una soglia configurata. DataDome è particolarmente aggressivo su:
- Richieste con TLS fingerprint non standard (es. Python requests)
- IP datacenter con storico di abuso
- Pattern di navigazione troppo regolari (stesso intervallo tra le richieste)
- Assenza di cookie di sessione validi
Cloudflare Bot Management
Sopra DataDome, Glassdoor usa Cloudflare Bot Management che aggiunge un ulteriore livello di sfida JavaScript. Quando Cloudflare rileva traffico sospetto, serve una pagina di challenge che richiede l'esecuzione di JavaScript per generare un token di clearance. I client HTTP semplici non possono eseguire questo JavaScript.
Fingerprinting TLS
Il problema più subdolo è il fingerprinting TLS (JA3/JA4). Ogni client HTTP ha una firma univoca nel modo in cui negozia la connessione TLS — l'ordine dei cipher suite, le estensioni supportate, i parametri della curva ellittica. Python requests ha una firma completamente diversa da Chrome, e DataDome lo rileva immediatamente.
Per questo motivo è necessario usare curl_cffi, una libreria Python che impersona il fingerprint TLS di Chrome a livello di libreria C. Questo significa che la connessione TLS appare identica a quella di un browser Chrome reale, aggirando il rilevamento JA3.
Endpoint BFF GraphQL: dati strutturati senza parsing HTML
Anziché fare scraping del HTML delle pagine di recensioni — fragile e soggetto a rotture ad ogni redesign — è preferibile usare gli endpoint JSON interni di Glassdoor. Il sito utilizza un'architettura BFF (Backend for Frontend) con GraphQL:
https://www.glassdoor.com/bff/graphql— endpoint GraphQL principale per recensionihttps://www.glassdoor.com/graph— endpoint GraphQL alternativo per dati aziendali
Questi endpoint restituiscono JSON strutturato con campi come ratingOverall, pros, cons, jobTitle, ratingCeo e metadata di paginazione. Per usarli serve:
- Un gd-csrf-token valido nell'header — ottenibile ispezionando le richieste di rete nella DevTools del browser su una pagina pubblica di Glassdoor
- Cookie di sessione DataDome validi (ottenuti dalla prima richiesta con impersonazione browser)
- Un fingerprint TLS coerente con Chrome (via curl_cffi)
- Un IP residenziale con buona reputazione
Il token CSRF ha una durata limitata (tipicamente 30-60 minuti) e va rigenerato periodicamente facendo una richiesta GET iniziale alla pagina aziendale.
Implementazione pratica in Python con proxy residenziali ProxyHat
Ecco un esempio completo che estrae recensioni pubbliche da Glassdoor usando l'endpoint BFF GraphQL attraverso un proxy residenziale ProxyHat con impersonazione Chrome TLS.
Setup ambiente
pip install curl_cffiScript Python completo
from curl_cffi import requests
import json
import time
import random
# ProxyHat residential proxy — US geo, sticky session
PROXY = "http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080"
# GraphQL query for public reviews
REVIEW_QUERY = """
query getReviews($employerId: Int!, $cursor: String) {
reviews(employerId: $employerId, after: $cursor, first: 10) {
edges {
node {
ratingOverall
pros
cons
jobTitle
reviewDateTime
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
"""
def fetch_csrf_token(employer_slug, employer_id):
"""Fetch the initial page to obtain gd-csrf-token and DataDome cookies."""
url = f"https://www.glassdoor.com/Reviews/{employer_slug}-Reviews-E{employer_id}.htm"
resp = requests.get(
url,
proxies={"https": PROXY, "http": PROXY},
impersonate="chrome120",
timeout=30
)
# Extract CSRF token from the HTML or response headers
csrf_token = resp.headers.get("gd-csrf-token", "")
if not csrf_token:
# Fallback: parse from HTML meta tag
import re
match = re.search(r'gd-csrf-token"\s*content="([^"]+)"', resp.text)
csrf_token = match.group(1) if match else ""
return csrf_token, resp.cookies
def fetch_reviews(employer_id, csrf_token, cookies, cursor=None):
"""Fetch a page of reviews via BFF GraphQL."""
headers = {
"Content-Type": "application/json",
"gd-csrf-token": csrf_token,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36",
}
payload = {
"query": REVIEW_QUERY,
"variables": {"employerId": employer_id, "cursor": cursor}
}
resp = requests.post(
"https://www.glassdoor.com/bff/graphql",
json=payload,
headers=headers,
cookies=cookies,
proxies={"https": PROXY, "http": PROXY},
impersonate="chrome120",
timeout=30
)
if resp.status_code == 403:
raise Exception("Blocked by DataDome — rotate IP or slow down")
return resp.json()
def scrape_all_reviews(employer_slug, employer_id, max_pages=50):
csrf_token, cookies = fetch_csrf_token(employer_slug, employer_id)
if not csrf_token:
raise Exception("Could not obtain CSRF token")
all_reviews = []
cursor = None
for page in range(max_pages):
try:
data = fetch_reviews(employer_id, csrf_token, cookies, cursor)
except Exception as e:
print(f"Error on page {page}: {e}")
# Rotate session on block
time.sleep(random.uniform(10, 20))
csrf_token, cookies = fetch_csrf_token(employer_slug, employer_id)
continue
reviews = data.get("data", {}).get("reviews", {})
edges = reviews.get("edges", [])
if not edges:
break
for edge in edges:
node = edge["node"]
all_reviews.append({
"rating": node.get("ratingOverall"),
"job_title": node.get("jobTitle"),
"pros": node.get("pros", "")[:200],
"cons": node.get("cons", "")[:200],
})
page_info = reviews.get("pageInfo", {})
if not page_info.get("hasNextPage"):
break
cursor = page_info.get("endCursor")
# Pace requests: 1 request every 3-5 seconds
time.sleep(random.uniform(3, 5))
return all_reviews
# Example usage
reviews = scrape_all_reviews("Google", 9079, max_pages=10)
print(f"Extracted {len(reviews)} reviews")
for r in reviews[:3]:
print(f"Rating: {r['rating']} | Title: {r['job_title']}")
print(f"Pros: {r['pros'][:80]}...")
print(f"Cons: {r['cons'][:80]}...")
Esempio curl
curl -x "http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080" \
-H "Content-Type: application/json" \
-H "gd-csrf-token: YOUR_CSRF_TOKEN" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
-d '{"query":"query { reviews(employerId: 9079, first: 10) { edges { node { ratingOverall pros cons jobTitle } } } }"}' \
"https://www.glassdoor.com/bff/graphql"Esempio Node.js
const { ProxyAgent } = require('undici');
const { request } = require('undici');
const proxyUrl = 'http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080';
const agent = new ProxyAgent(proxyUrl);
async function fetchReviews(employerId, csrfToken, cursor = null) {
const query = `
query getReviews($employerId: Int!, $cursor: String) {
reviews(employerId: $employerId, after: $cursor, first: 10) {
edges { node { ratingOverall pros cons jobTitle } }
pageInfo { endCursor hasNextPage }
}
}
`;
const resp = await request('https://www.glassdoor.com/bff/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'gd-csrf-token': csrfToken,
},
body: JSON.stringify({
query,
variables: { employerId, cursor }
}),
dispatcher: agent,
});
if (resp.statusCode === 403) {
throw new Error('Blocked by DataDome — rotate IP');
}
return resp.body.json();
}
module.exports = { fetchReviews };
Strategie di paginazione, sessioni sticky e retry
Cursor-based pagination
Il BFF GraphQL usa paginazione basata su cursor (Relay-style). Ogni risposta include pageInfo.endCursor e pageInfo.hasNextPage. Passa il cursore nella variabile after della richiesta successiva. Non usare offset numerici — Glassdoor non li supporta e restituiscono dati duplicati o vuoti.
Sessioni sticky per mantenere i cookie DataDome
DataDome associa i cookie di sessione all'IP che li ha generati. Se ruoti l'IP ad ogni richiesta, i cookie diventano invalidi e ricevi un 403. Usa la funzionalità di sessione sticky di ProxyHat per mantenere lo stesso IP per tutta la durata di una sessione di scraping:
# Sticky session per 30 minuti
PROXY = "http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080"Quando ricevi un 403, genera un nuovo identificatore di sessione per ottenere un IP fresco e rifai il flusso di fetch del CSRF token.
Pacing e rate limiting
Il fattore più critico per evitare blocchi è il ritardo tra le richieste. Raccomandazioni pratiche:
- 1 richiesta ogni 3-5 secondi per l'endpoint GraphQL
- Jitter casuale di ±1-2 secondi per evitare pattern regolari
- Max 200 richieste per sessione prima di ruotare IP
- Pausa di 10-20 secondi dopo un 403 prima di riprovare con nuovo IP
Logica di challenge-retry
def scrape_with_retry(employer_slug, employer_id, max_retries=5):
for attempt in range(max_retries):
try:
session_id = f"glassdoor-{attempt}"
proxy = f"http://user-country-US-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
csrf_token, cookies = fetch_csrf_token(employer_slug, employer_id)
reviews = fetch_reviews(employer_id, csrf_token, cookies)
return reviews
except Exception as e:
print(f"Attempt {attempt} failed: {e}")
time.sleep(random.uniform(15, 30))
raise Exception("Max retries exceeded")
Proxy residenziali vs datacenter vs mobile per Glassdoor
La scelta del tipo di proxy è cruciale per il successo con Glassdoor. DataDome assegna un punteggio di rischio all'IP basandosi sulla sua categoria ASN.
| Tipo di proxy | Success rate stimato | Latenza media | Costo relativo | Idoneità per Glassdoor |
|---|---|---|---|---|
| Residenziali | 90-95% | 200-500ms | Medio | Ottima — IP da ISP reali, basso punteggio DataDome |
| Datacenter | 10-30% | 50-100ms | Basso | Pessima — ASN datacenter immediatamente flaggato |
| Mobile | 95-98% | 500-1500ms | Alto | Eccellente ma costosa per volumi alti |
I proxy residenziali offrono il miglior compromesso tra costo e successo per Glassdoor. Esplora le opzioni di pricing di ProxyHat per trovare il piano adatto al tuo volume. Verifica la copertura geografica per assicurarti che le località target siano disponibili.
Errori comuni e casi limite
1. Usare requests senza impersonazione TLS
Il primo errore è usare requests standard. Il fingerprint TLS di Python è immediatamente riconosciuto da DataDome. Usa sempre curl_cffi con impersonate="chrome120".
2. Dimenticare l'header gd-csrf-token
L'endpoint BFF GraphQL restituisce un 403 generico senza il token CSRF. Non c'è un messaggio di errore chiaro — sembra un blocco DataDome ma in realtà è un problema di autenticazione. Verifica sempre che il token sia presente e valido.
3. Ruotare IP ad ogni richiesta
Con DataDome, i cookie di sessione sono legati all'IP. Se ottieni un cookie con IP A e poi fai la richiesta GraphQL con IP B, il cookie viene invalidato. Usa sessioni sticky per mantenere coerenza tra IP e cookie.
4. Estrarre dati personali identificabili
Le recensioni Glassdoor possono contenere dettagli che, combinati, identificano un individuo (titolo di lavoro specifico + sede + data). Per conformità GDPR nell'UE, aggrega i dati e rimuovi campi che permettono re-identificazione.
5. Ignorare robots.txt
Controlla sempre https://www.glassdoor.com/robots.txt prima di iniziare. Anche se non legalmente vincolante in tutte le giurisdizioni, rispettarlo è una best practice etica e riduce il rischio di dispute legali.
Considerazioni etiche e quando usare API ufficiali
L'estrazione di dati web esiste in un'area grigia legale. Ecco i principi guida per un approccio etico:
Principio 1: Solo dati pubblici, senza login
Non usare credenziali automatizzate, non aggirare paywall o login wall. Se un dato richiede login, non estrarlo. I dati salariali dettagliati su Glassdoor sono dietro login per una ragione — l'azienda li considera proprietari.
Principio 2: Aggrega, non identificare
Per analisi di mercato, aggrega le recensioni a livello aziendale o di ruolo. Non estrarre singole recensioni con lo scopo di identificare chi le ha scritte. Il GDPR considera i dati dei dipendenti come dati personali se combinabili per identificare un individuo.
Principio 3: Rispetta rate limit ragionevoli
Un rate di 1 richiesta ogni 3-5 secondi è ragionevole. 100 richieste al secondo non lo è, e non solo viola i ToS ma degrada il servizio per gli utenti legittimi.
Principio 4: Quando usare l'API ufficiale
Se il tuo caso d'uso è commerciale (es. costruisci un prodotto SaaS che vende dati salariali), l'estrazione non è appropriata. In questi casi:
- Richiedi una licenza API partner di Glassdoor
- Usa dataset commerciali come quelli di Levels.fyi o aggregatori con licenza
- Considera dataset pubblici governativi (es. BLS Occupational Employment Statistics negli Stati Uniti)
Per approfondire le best practice di scraping etico, consulta la nostra guida ai casi d'uso di web scraping e la documentazione su docs.proxyhat.com.
Punti chiave
- Dati pubblici vs gated: Le recensioni troncate e le valutazioni generali sono pubbliche su
/Reviews/. Gli stipendi completi e le recensioni integrali sono dietro login — non estrarli. - Stack anti-bot: DataDome + Cloudflare Bot Management + fingerprinting TLS richiedono curl_cffi con impersonazione Chrome e proxy residenziali.
- Endpoint BFF GraphQL:
/bff/graphqlrestituisce JSON strutturato ma richiedegd-csrf-tokene cookie DataDome validi. - Sessioni sticky: Mantieni lo stesso IP per tutta la durata di una sessione per preservare i cookie DataDome. Usa
user-session-XYZnel username ProxyHat. - Pacing: 1 richiesta ogni 3-5 secondi con jitter casuale. Max 200 richieste per sessione prima di ruotare IP.
- Etica: Solo dati pubblici, aggrega per evitare re-identificazione, rispetta robots.txt, usa API ufficiali per uso commerciale.
Pronto per iniziare? Configura i tuoi proxy residenziali ProxyHat e prova lo script sopra con un'azienda pubblica. Per scenari avanzati come SERP tracking o monitoraggio di prezzi su e-commerce, la stessa infrastruttura di proxy e sessioni sticky si applica. Consulta la pagina pricing per scegliere il piano adeguato al tuo volume di richieste.






