Aviso legal: Este artículo cubre únicamente el acceso a datos públicos de Glassdoor. Debes respetar los Términos de Servicio de Glassdoor y las leyes aplicables, incluyendo la Computer Fraud and Abuse Act (CFAA) en EE.UU. y el GDPR en la UE. No recomendamos ni cubrimos el scraping detrás de muros de autenticación. Consulta con un abogado antes de desplegar cualquier pipeline de scraping a escala.
Si construyes pipelines de analítica de RR.HH. o datos de mercado laboral, probablemente te has preguntado cómo scrapear Glassdoor de forma fiable. Glassdoor aloja millones de reseñas de empleados, datos salariales y valoraciones de empresas, pero su infraestructura anti-bot —DataDome combinado con Cloudflare— hace que el scraping naïf con requests falle en minutos. Esta guía explica qué datos son públicos, cómo funciona el stack anti-bot de Glassdoor, y cómo usar proxies residenciales rotativos con el endpoint GraphQL BFF para construir un Glassdoor reviews scraper robusto en 2026.
Cómo scrapear reseñas y salarios de Glassdoor en 2026: el panorama
Glassdoor protege activamente sus datos con múltiples capas de defensa. En 2026, el stack incluye DataDome para scoring de IP y comportamiento, Cloudflare Bot Management para challenges de JavaScript, y fingerprinting TLS para distinguir navegadores reales de scripts. Un scraper que funcione necesita tres piezas: proxies residenciales de alta confianza, impersonación TLS de navegador, y conocimiento de los endpoints GraphQL internos que devuelven JSON estructurado en lugar de HTML.
Qué es accesible sin login vs. detrás de autenticación
Antes de escribir código, es crítico entender la frontera de datos:
| Tipo de dato | Acceso sin login | Requiere login |
|---|---|---|
| Descripción general de empresa | Sí | — |
| Reseñas truncadas (pros, contras, rating) | Sí (parcial) | Reseña completa |
| Rating general (ratingOverall) | Sí | — |
| Desglose salarial completo | No | Sí |
| Detalles de entrevistas | Parcial | Sí |
| Fotos de oficinas | Sí | — |
Las URLs públicas siguen el patrón /Reviews/<empresa>-Reviews-E<id>.htm. En estas páginas puedes ver reseñas truncadas con el título del puesto, rating general, y fragmentos de pros/contras. Los datos salariales de Glassdoor completos —desglose por cargo, ubicación, antigüedad— están detrás de un muro de autenticación. Esta guía se limita exclusivamente a datos públicos accesibles sin login.
El stack anti-bot de Glassdoor: DataDome + Cloudflare
Glassdoor delega su defensa a dos sistemas complementarios:
- DataDome: analiza la reputación de IP, patrones de comportamiento, headers HTTP y fingerprints del navegador. Asigna un score a cada visita; si el score supera un umbral, devuelve un challenge o bloquea directamente. Según la documentación de DataDome, su sistema procesa decisiones en menos de 50ms usando machine learning en tiempo real.
- Cloudflare Bot Management: añade challenges de JavaScript, fingerprinting TLS (JA3/JA4) y análisis de reputación de IP. Puedes leer más sobre su enfoque en la página oficial de Cloudflare Bot Management.
El resultado: un curl simple o requests.get() recibe un 403 o un challenge HTML en lugar de los datos. El fingerprint TLS de librerías HTTP estándar (Python requests, Node.js axios) no coincide con ningún navegador real, y DataDome lo detecta al instante.
Por qué necesitas curl_cffi
La solución es curl_cffi, una librería Python que usa curl-impersonate para reproducir el handshake TLS exacto de Chrome o Firefox. Esto significa que el JA3/JA4 fingerprint de tu petición es indistinguible del de un navegador Chrome real. Sin esto, DataDome bloqueará tus requests sin importar cuántos proxies uses.
pip install curl_cffi
El endpoint GraphQL BFF de Glassdoor
Glassdoor usa una arquitectura BFF (Backend-for-Frontend) con endpoints GraphQL que devuelven JSON estructurado. Los endpoints relevantes son:
https://www.glassdoor.com/bff/graphql— endpoint principal para reseñas y datos de empresa.https://www.glassdoor.com/graph— endpoint GraphQL alternativo para ciertas queries.
Estos endpoints no están documentados públicamente. Para descubrir las operaciones disponibles, puedes inspeccionar el tráfico de red en las DevTools del navegador (pestaña Network, filtrar por "graphql"). Las peticiones incluyen un header gd-csrf-token que se genera en el cliente y debe acompañar cada request.
Las ventajas del endpoint GraphQL sobre el HTML scraping son significativas:
- JSON estructurado en lugar de parsear HTML frágil.
- Campos como
ratingOverall,pros,cons,jobTitlevienen tipados. - Paginación mediante cursores en lugar de extraer URLs de "siguiente página".
- Menos ancho de banda: pides solo los campos que necesitas.
Por qué los proxies residenciales rotativos vencen a DataDome
DataDome asigna scores de confianza por IP. Las IPs de datacenters (AWS, DigitalOcean, OVH) tienen scores bajísimos porque DataDome las marca como Known Bot Networks. Las IPs residenciales, en cambio, provienen de ISP reales (Comcast, AT&T, Movistar) y tienen scores de confianza altos porque DataDome las trata como usuarios legítimos.
Al rotar IPs residenciales en cada petición o sesión, distribuyes el load y evitas que una sola IP acumule suficientes requests para disparar un alerta de comportamiento. ProxyHat ofrece ubicaciones en más de 190 países con IPs residenciales reales, ideales para este caso de uso.
Implementación: scrapear reseñas con Python y ProxyHat
A continuación, un ejemplo completo en Python que consulta el endpoint BFF GraphQL de Glassdoor a través de un proxy residencial ProxyHat con impersonación TLS de Chrome.
from curl_cffi import requests
import json
import time
# Proxy residencial ProxyHat con sesión sticky y geo-targeting US
proxy_url = "http://user-country-US-session-rev001:PASSWORD@gate.proxyhat.com:8080"
headers = {
"gd-csrf-token": "TU_CSRF_TOKEN",
"content-type": "application/json",
"accept": "application/json",
"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",
"referer": "https://www.glassdoor.com/Reviews/",
}
payload = {
"operationName": "EmployerReviews",
"variables": {
"employerId": 12345,
"limit": 10,
"cursor": None
},
"query": """
query EmployerReviews($employerId: Int!, $limit: Int, $cursor: String) {
employer(id: $employerId) {
reviews(limit: $limit, cursor: $cursor) {
nodes {
id
ratingOverall
pros
cons
jobTitle
date
}
pageInfo {
nextCursor
hasNextPage
}
}
}
}
"""
}
def fetch_reviews(employer_id, max_pages=20):
cursor = None
all_reviews = []
for page in range(max_pages):
payload["variables"]["cursor"] = cursor
payload["variables"]["employerId"] = employer_id
try:
r = requests.post(
"https://www.glassdoor.com/bff/graphql",
json=payload,
headers=headers,
proxies={"http": proxy_url, "https": proxy_url},
impersonate="chrome",
timeout=30,
)
if r.status_code == 403:
print(f"Bloqueado en página {page}. Rotando IP...")
# Nueva sesión = nueva IP residencial
time.sleep(5)
continue
data = r.json()
reviews = data["data"]["employer"]["reviews"]
for node in reviews["nodes"]:
all_reviews.append({
"id": node["id"],
"rating": node["ratingOverall"],
"pros": node["pros"],
"cons": node["cons"],
"jobTitle": node["jobTitle"],
"date": node["date"],
})
if not reviews["pageInfo"]["hasNextPage"]:
break
cursor = reviews["pageInfo"]["nextCursor"]
time.sleep(2) # Pacing: 1 request cada 2 segundos
except Exception as e:
print(f"Error en página {page}: {e}")
time.sleep(10)
return all_reviews
reviews = fetch_reviews(employer_id=12345, max_pages=20)
print(f"Total reseñas extraídas: {len(reviews)}")
print(json.dumps(reviews[0], indent=2, ensure_ascii=False))
Este script extrae reseñas truncadas públicas (rating, pros, cons, jobTitle) sin necesidad de login. La sesión sticky (session-rev001) mantiene la misma IP durante toda la paginación, preservando las cookies de DataDome. Si una petición recibe 403, el script espera y reintenta con la misma sesión o puedes cambiar el identificador de sesión para obtener una IP nueva.
Ejemplo en Node.js
Para equipos de JavaScript, aquí hay un equivalente usando undici con ProxyAgent:
const { request, ProxyAgent } = require('undici');
const proxyUrl = 'http://user-country-US-session-rev001:PASSWORD@gate.proxyhat.com:8080';
const agent = new ProxyAgent(proxyUrl);
async function fetchReviews(employerId, cursor = null) {
const payload = {
operationName: 'EmployerReviews',
variables: { employerId, limit: 10, cursor },
query: `query EmployerReviews($employerId: Int!, $limit: Int, $cursor: String) {
employer(id: $employerId) {
reviews(limit: $limit, cursor: $cursor) {
nodes { id ratingOverall pros cons jobTitle date }
pageInfo { nextCursor hasNextPage }
}
}
}`
};
const res = await request('https://www.glassdoor.com/bff/graphql', {
method: 'POST',
headers: {
'gd-csrf-token': 'TU_CSRF_TOKEN',
'content-type': 'application/json',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
},
body: JSON.stringify(payload),
dispatcher: agent
});
const data = await res.body.json();
return data.data.employer.reviews;
}
fetchReviews(12345).then(reviews => {
console.log(`Reseñas obtenidas: ${reviews.nodes.length}`);
console.log(reviews.nodes[0]);
});
Nota: Node.js no tiene una librería equivalente a curl_cffi tan madura. Para producción en Node.js, considera usar la documentación de ProxyHat junto con una librería de impersonación TLS como node-tls-client.
Paginación, sesiones sticky y pacing
Cursores de paginación
El endpoint GraphQL usa paginación por cursor. Cada respuesta incluye pageInfo.nextCursor y pageInfo.hasNextPage. Pasa el cursor en la siguiente petición para avanzar. No intentes paginar con offsets numéricos; los cursores son opacos y deben tratarse como strings no modificables.
Sesiones sticky para mantener cookies de DataDome
DataDome emite cookies de sesión que se asocian a una IP. Si rotas IP en cada request, DataDome ve una cookie de una IP previa en una IP nueva y puede desafiar. La solución es usar sesiones sticky: el mismo identificador de sesión en el username de ProxyHat mantiene la misma IP residencial durante un período configurable.
# Sesión sticky: misma IP durante toda la sesión
proxy_url = "http://user-country-US-session-mi-sesion-001:PASSWORD@gate.proxyhat.com:8080"
Cuando necesites rotar (por ejemplo, tras un 403), cambia el identificador de sesión:
# Nueva sesión = nueva IP residencial
proxy_url = "http://user-country-US-session-mi-sesion-002:PASSWORD@gate.proxyhat.com:8080"
Pacing y rate limiting
El pacing es crítico. Recomendaciones basadas en experiencia:
- 1-2 requests por segundo por sesión/IP.
- 5-10 segundos de pausa entre páginas de resultados.
- Backoff exponencial tras errores 429 o 403: empieza en 10s, duplica hasta 120s.
- Concurrencia limitada: no más de 5-10 sesiones simultáneas desde IPs diferentes.
- Jitter aleatorio: añade ±0.5s a cada pausa para evitar patrones detectables.
Lógica de reintento ante challenges
import random
def retry_with_backoff(func, max_retries=5):
for attempt in range(max_retries):
try:
result = func()
if result and result.status_code != 403:
return result
except Exception:
pass
wait_time = min(10 * (2 ** attempt), 120) + random.uniform(0, 1)
print(f"Reintento {attempt + 1}: esperando {wait_time:.1f}s")
time.sleep(wait_time)
return None
Errores comunes y casos límite
- Usar proxies de datacenter: DataDome los bloquea en segundos. Usa residenciales.
- Olvidar el header gd-csrf-token: el endpoint GraphQL devuelve 403 sin él. Inspecciona el tráfico de red para obtener uno válido.
- No impersonar TLS: sin curl_cffi o equivalente, el JA3 fingerprint delata tu script.
- Rotar IP en cada request dentro de una sesión: rompe las cookies de DataDome. Usa sesiones sticky.
- Scrapear a alta velocidad: 10+ requests/segundo garantiza un bloqueo. Limita a 1-2/segundo.
- Ignorar el robots.txt: revisa siempre
https://www.glassdoor.com/robots.txtantes de empezar. - No manejar respuestas vacías: Glassdoor a veces devuelve JSON válido pero con nodos vacíos. Valida
hasNextPageantes de continuar.
Configuración de ProxyHat
ProxyHat proporciona proxies residenciales rotativos accesibles vía gateway único. La configuración para Glassdoor:
| Parámetro | Valor recomendado |
|---|---|
| Tipo de proxy | Residencial rotativo |
| Gateway | gate.proxyhat.com:8080 (HTTP) |
| SOCKS5 | gate.proxyhat.com:1080 |
| Geo-targeting | US (mayoría de empresas en Glassdoor) |
| Sesión | Sticky por empresa scrapeada |
| Rotación | Al detectar 403 o tras N requests |
| Concurrencia | 5-10 sesiones simultáneas |
Consulta las opciones de pricing de ProxyHat para elegir el plan adecuado según tu volumen. Para casos de uso de web scraping a escala, revisa nuestra página de uso de web scraping y para tracking de SERPs, la guía de SERP tracking.
Scraping ético y cuándo usar APIs oficiales
El scraping de Glassdoor plantea consideraciones éticas y legales serias:
Principios éticos
- Solo datos públicos: limita tu scraping a información accesible sin login. No extraigas datos detrás de autenticación.
- Agrega, no individualices: para analítica de mercado laboral, agrega reseñas por empresa, sector o región. No publiques datos que identifiquen a individuos.
- Respeta robots.txt: si Glassdoor prohíbe una ruta en su robots.txt, no la scrapees.
- Limita la velocidad: tu scraper no debe degradar la experiencia de otros usuarios del sitio.
- GDPR para datos de la UE: las reseñas de empleados pueden contener datos personales indirectamente identificables. Si procesas datos de empresas europeas, necesitas una base legal bajo el GDPR y debes evaluar si los datos constituyen información personal.
Cuándo una licencia de datos oficial es la opción correcta
Si tu caso de uso es comercial, a gran escala, o requiere datos salariales completos (que están detrás de login), una licencia de datos oficial de Glassdoor es la opción apropiada. Glassdoor ofrece programas de partnerships de datos para empresas. Las ventajas incluyen:
- Acceso legal y conforme a los ToS.
- Datos completos, incluyendo salarios y detalles de entrevistas.
- Soporte y SLAs de disponibilidad.
- Sin riesgo de bloqueos o litigios.
El scraping con proxies es ideal para prototipado, investigación, y analítica de datos públicos a escala moderada. Para producción comercial a escala, evalúa la licencia oficial.
Puntos clave
Datos públicos únicamente: Las reseñas truncadas y ratings generales son accesibles sin login en /Reviews/. Los datos salariales completos requieren autenticación y no deben extraerse vía scraping.
Stack anti-bot: DataDome + Cloudflare Bot Management usan scoring de IP, fingerprinting TLS y challenges de JS. Necesitas proxies residenciales + curl_cffi para impersonación TLS.
Endpoint GraphQL BFF:
/bff/graphqldevuelve JSON estructurado. Requiere headergd-csrf-token. Descubre las operaciones inspeccionando el tráfico de red.Sesiones sticky: Mantén la misma IP durante la paginación para preservar cookies de DataDome. Rota solo tras bloqueos.
Pacing: 1-2 requests/segundo, backoff exponencial tras 403, jitter aleatorio. La paciencia vence a DataDome.
Ética: Agrega datos, no identifiques individuos, respeta robots.txt, y considera una licencia oficial para uso comercial a escala.
Conclusión
Scrapear Glassdoor en 2026 es factible si combinas las herramientas correctas: proxies residenciales rotativos de ProxyHat, impersonación TLS con curl_cffi, y el endpoint GraphQL BFF no documentado. La clave está en comportarte como un usuario real: IP residencial, fingerprint de navegador, pacing humano y sesiones persistentes. Para datos públicos de reseñas, este enfoque funciona de forma fiable. Para datos salariales completos o uso comercial a escala, la opción ética y legal es una licencia de datos oficial.
Si estás listo para empezar, explora los planes de ProxyHat y configura tu primer scraper residencial hoy. Para más guías técnicas, visita nuestra documentación completa.






