Aviso legal: Este artigo aborda apenas o acesso a dados públicos que não exigem login. Raspar conteúdo atrás de autenticação pode violar os Termos de Serviço do Glassdoor e leis como o CFAA (EUA) e o GDPR (UE). Consulte sempre os ToS da plataforma e procure aconselhamento jurídico antes de coletar dados em escala. O Glassdoor oferece programas de parceria de dados e licenciamento para uso comercial.
Se você trabalha com analytics de mercado de trabalho, já sabe a frustração: o Glassdoor contém milhões de reviews de funcionários e dados salariais, mas sua infraestrutura anti-bot — composta por DataDome, Cloudflare Bot Management e fingerprinting de TLS — torna a coleta automatizada um desafio sério. Neste guia, vamos mostrar como raspar reviews e salários de empresas no Glassdoor em 2026 usando o endpoint BFF GraphQL não documentado, proxies residenciais rotativos via ProxyHat e técnicas de impersonação de TLS com curl_cffi.
O que é alcançável sem login vs. conteúdo protegido
O Glassdoor divide seu conteúdo em duas camadas de acessibilidade. Entender essa divisão é essencial para qualquer scraper de reviews Glassdoor que queira permanecer dentro dos limites legais e técnicos.
Dados públicos (sem login)
- Página de reviews da empresa: URL no formato
/Reviews/<company>-Reviews-E<id>.htm— exibe avaliações truncadas comratingOverall,pros,consejobTitle. - Visão geral da empresa: nome, setor, tamanho, fundação, localização da sede.
- Resumo de salários: médias agregadas por cargo visíveis parcialmente, sem detalhamento por região ou senioridade.
Dados protegidos (atrás de login)
- Salários detalhados: breakdown completo por cargo, região, anos de experiência e gênero.
- Reviews completas: texto integral de pros e contras (a versão pública mostra apenas trechos truncados).
- Entrevistas e fotos da empresa: conteúdo submetido por usuários que exige conta ativa.
Recomendação: Limite seu scraper a dados públicos agregados. Raspar conteúdo atrás de login não apenas viola os ToS do Glassdoor, mas também levanta questões sérias sob o GDPR para dados de funcionários na UE. Para dados salariais Glassdoor detalhados, considere o programa oficial de licenciamento de dados do Glassdoor.
O stack anti-bot do Glassdoor: DataDome + Cloudflare
O Glassdoor emprega uma arquitetura de defesa em camadas que combina dois dos sistemas anti-bot mais agressivos do mercado. Segundo a documentação pública da DataDome, a plataforma analisa mais de 40 sinais em tempo real, incluindo fingerprint de browser, padrões de navegação e reputação de IP. O Cloudflare Bot Management adiciona desafios de JavaScript e fingerprinting de TLS.
Por que requests puro falha
A biblioteca requests do Python usa a stack TLS do OpenSSL, que produz um fingerprint de ClientHello completamente diferente do Chrome ou Firefox. O DataDome detecta essa discrepância em milissegundos e retorna um desafio JavaScript ou um erro 403. A solução é usar curl_cffi, que empacota o libcurl-impersonate e replica o handshake TLS exato do Chrome 120+.
from curl_cffi import requests as cffi_requests
# Impersonação Chrome 120 — necessário para passar no fingerprint TLS do DataDome
session = cffi_requests.Session(impersonate="chrome120")
Fingerprinting de TLS: o que seu scraper precisa replicar
O fingerprinting de TLS examina a ordem e os valores das extensões no ClientHello, incluindo ALPN, supported_groups e signature_algorithms. Bibliotecas HTTP padrão não controlam esses campos. O curl_cffi resolve isso mapeando perfis de browser reais:
- chrome120 — Chrome 120 no Windows (mais compatível com DataDome).
- safari17_0 — Safari 17 no macOS (útil para rotação de fingerprints).
- firefox110 — Firefox 110 (alternativa para diversificação).
Endpoints GraphQL não documentados do Glassdoor
Embora a página HTML de reviews seja pública, o Glassdoor carrega os dados via chamadas JSON a endpoints GraphQL internos. Esses endpoints retornam dados estruturados — muito mais fáceis de parsear que HTML — mas exigem headers específicos.
O endpoint BFF GraphQL
O endpoint principal é https://www.glassdoor.com/bff/graphql, que aceita POST com payload JSON. Ele requer:
- Header
gd-csrf-token: token CSRF extraído da página HTML inicial via regex ou parser. - Header
Content-Type: application/json. - Cookies de sessão do DataDome: definidos no primeiro GET à página de reviews.
import re
from curl_cffi import requests as cffi_requests
session = cffi_requests.Session(impersonate="chrome120")
# 1. GET à página pública para obter cookies e CSRF token
resp = session.get("https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm")
csrf_match = re.search(r'"csrfToken":"([^"]+)"', resp.text)
csrf_token = csrf_match.group(1) if csrf_match else None
# 2. POST ao BFF GraphQL
query = """
query EmployerReviews($employerId: Long!, $page: Int!, $limit: Int!) {
employerReviews(employerId: $employerId, page: $page, limit: $limit) {
reviews {
ratingOverall
pros
cons
jobTitle
date
}
totalCount
hasNextPage
endCursor
}
}
"""
payload = {
"query": query,
"variables": {
"employerId": 9079,
"page": 1,
"limit": 10
}
}
headers = {
"Content-Type": "application/json",
"gd-csrf-token": csrf_token,
"Referer": "https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm"
}
graph_resp = session.post(
"https://www.glassdoor.com/bff/graphql",
json=payload,
headers=headers
)
data = graph_resp.json()
print(data["data"]["employerReviews"]["reviews"][0])
Por que proxies residenciais superam o IP scoring do DataDome
O DataDome atribui uma pontuação de risco a cada IP. Datacenters têm pontuação alta por padrão (frequentemente bloqueados em 1-2 requisições). IPs residenciais, por outro lado, pertencem a ISPs reais e têm pontuação baixa. Rotar IPs residenciais a cada requisição distribui o tráfego de forma que nenhum IP individual ultrapasse o limite de taxa do DataDome, que é tipicamente de 30-60 requisições por IP por janela de 5 minutos.
Exemplo prático: Python + ProxyHat SDK
Agora vamos integrar tudo: impersonação de TLS, extração de CSRF, chamada ao BFF GraphQL e rotação de proxies residenciais via ProxyHat.
import re
import time
import json
from curl_cffi import requests as cffi_requests
# ProxyHat residential proxy — rotação automática por requisição
proxy_url = "http://user-country-US-session-glassdoor1:pass@gate.proxyhat.com:8080"
session = cffi_requests.Session(impersonate="chrome120")
session.proxies = {"http": proxy_url, "https": proxy_url}
EMPLOYER_ID = 9079 # Google
REVIEWS_URL = f"https://www.glassdoor.com/Reviews/Google-Reviews-E{EMPLOYER_ID}.htm"
BFF_URL = "https://www.glassdoor.com/bff/graphql"
def fetch_csrf_and_cookies():
resp = session.get(REVIEWS_URL, timeout=30)
if resp.status_code != 200:
raise Exception(f"Falha ao carregar página: {resp.status_code}")
match = re.search(r'"csrfToken":"([^"]+)"', resp.text)
if not match:
raise Exception("CSRF token não encontrado")
return match.group(1)
def fetch_reviews(csrf_token, cursor=None, limit=10):
query = """
query EmployerReviews($employerId: Long!, $limit: Int!, $cursor: String) {
employerReviews(employerId: $employerId, limit: $limit, cursor: $cursor) {
reviews {
ratingOverall
pros
cons
jobTitle
date
}
totalCount
hasNextPage
endCursor
}
}
"""
payload = {
"query": query,
"variables": {
"employerId": EMPLOYER_ID,
"limit": limit,
"cursor": cursor
}
}
headers = {
"Content-Type": "application/json",
"gd-csrf-token": csrf_token,
"Referer": REVIEWS_URL
}
resp = session.post(BFF_URL, json=payload, headers=headers, timeout=30)
if resp.status_code == 403:
raise Exception("Bloqueado pelo DataDome — rotacione IP")
return resp.json()
def scrape_all_reviews(max_pages=50):
csrf = fetch_csrf_and_cookies()
all_reviews = []
cursor = None
for page in range(max_pages):
try:
data = fetch_reviews(csrf, cursor)
reviews = data["data"]["employerReviews"]["reviews"]
all_reviews.extend(reviews)
print(f"Página {page+1}: {len(reviews)} reviews coletadas")
if not data["data"]["employerReviews"]["hasNextPage"]:
break
cursor = data["data"]["employerReviews"]["endCursor"]
time.sleep(3) # Pacing: 3s entre requisições
except Exception as e:
print(f"Erro na página {page+1}: {e}")
# Trocar sessão de proxy em caso de bloqueio
break
return all_reviews
reviews = scrape_all_reviews()
print(f"Total: {len(reviews)} reviews")
for r in reviews[:3]:
print(f" {r['jobTitle']} — nota {r['ratingOverall']}")
print(f" Pros: {r['pros'][:80]}...")
print(f" Cons: {r['cons'][:80]}...")
Exemplo em Node.js com curl-impersonate
const { CurlImpersonate } = require('curl-impersonate');
const proxyUrl = 'http://user-country-US-session-glassdoor1:pass@gate.proxyhat.com:8080';
const client = new CurlImpersonate({
impersonate: 'chrome120',
proxy: proxyUrl
});
async function scrapeGlassdoor() {
const pageResp = await client.get('https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm');
const csrfMatch = pageResp.body.match(/"csrfToken":"([^"]+)"/);
const csrf = csrfMatch[1];
const graphResp = await client.post('https://www.glassdoor.com/bff/graphql', {
headers: {
'Content-Type': 'application/json',
'gd-csrf-token': csrf,
'Referer': 'https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm'
},
body: JSON.stringify({
query: `query EmployerReviews($employerId: Long!, $limit: Int!) {
employerReviews(employerId: $employerId, limit: $limit) {
reviews { ratingOverall pros cons jobTitle date }
totalCount hasNextPage endCursor
}
}`,
variables: { employerId: 9079, limit: 10 }
})
});
const data = JSON.parse(graphResp.body);
console.log(data.data.employerReviews.reviews[0]);
}
scrapeGlassdoor();
Paginação, sessões sticky e lógica de retry
Cursores de paginação
O BFF GraphQL usa paginação baseada em cursor (padrão Relay-style). O campo endCursor deve ser passado como variável cursor na próxima requisição. Não tente usar paginação por offset — o endpoint não suporta offset e retornará erro de validação.
Sessões sticky do ProxyHat
Os cookies do DataDome são vinculados ao IP que os recebeu. Se você rotar o IP a cada requisição, os cookies serão invalidados e você receberá um desafio. A solução é usar sessões sticky do ProxyHat, mantendo o mesmo IP por um lógico de sessão:
# Sessão sticky — mantém o mesmo IP residencial
proxy_url = "http://user-country-US-session-glassdoor-abc123:pass@gate.proxyhat.com:8080"
# Para rotar após N requisições, mude o ID da sessão
# user-country-US-session-glassdoor-abc124:pass@gate.proxyhat.com:8080
Recomendamos manter uma sessão por 20-30 requisições, depois rotar para um novo ID de sessão. Isso equilibra a necessidade de cookies válidos com a rotação de IP para evitar limites de taxa.
Pacing e lógica de retry
| Estratégia | Configuração recomendada | Justificativa |
|---|---|---|
| Delay entre requisições | 3-5 segundos | Evita disparar alertas de taxa do DataDome |
| Requisições por sessão sticky | 20-30 | Mantém cookies válidos sem sobrecarregar um IP |
| Retry em 403/429 | 3 tentativas com backoff exponencial | 1s → 2s → 4s antes de desistir |
| Jitter aleatório | ±1s sobre o delay base | Evita padrões detectáveis de tráfego |
| Concorrência máxima | 5 threads | Limita risco de bloqueio em escala |
import random
import time
def fetch_with_retry(csrf, cursor, max_retries=3):
for attempt in range(max_retries):
try:
data = fetch_reviews(csrf, cursor)
jitter = random.uniform(2, 5)
time.sleep(jitter)
return data
except Exception as e:
if attempt == max_retries - 1:
raise
backoff = (2 ** attempt) + random.uniform(0, 1)
print(f"Retry {attempt+1} em {backoff:.1f}s: {e}")
time.sleep(backoff)
# Rotacionar sessão de proxy
new_session = f"glassdoor-{random.randint(1000, 9999)}"
session.proxies = {
"http": f"http://user-country-US-session-{new_session}:pass@gate.proxyhat.com:8080",
"https": f"http://user-country-US-session-{new_session}:pass@gate.proxyhat.com:8080"
}
Configuração específica do ProxyHat
O ProxyHat oferece proxies residenciais, móveis e de datacenter. Para raspar o Glassdoor, os residenciais são a melhor escolha por sua baixa pontuação de risco no DataDome. Veja nossas opções de preços e localizações disponíveis.
Formatos de conexão
# HTTP — porta 8080
http://USERNAME:PASSWORD@gate.proxyhat.com:8080
# SOCKS5 — porta 1080
socks5://USERNAME:PASSWORD@gate.proxyhat.com:1080
# Geo-targeting por país
http://user-country-US:pass@gate.proxyhat.com:8080
# Geo-targeting por cidade
http://user-country-US-city-san-francisco:pass@gate.proxyhat.com:8080
# Sessão sticky
http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080
Por que não usar proxies de datacenter
Proxies de datacenter têm taxa de sucesso abaixo de 10% contra o DataDome, pois seus ranges de IP são bem conhecidos e pré-classificados como automatizados. Proxies residenciais rotativos do ProxyHat alcançam taxas de sucesso de 85-95% quando combinados com impersonação de TLS adequada. Para mais detalhes sobre casos de uso de web scraping, consulte nossa página dedicada.
Para monitorar resultados de SERP que referenciam empresas do Glassdoor, confira também nosso caso de uso de rastreamento de SERP. A documentação técnica completa do ProxyHat está disponível em docs.proxyhat.com.
Erros comuns e casos de borda
1. Esquecer o header gd-csrf-token
O BFF GraphQL retorna 401 Unauthorized sem o token CSRF. Extraia sempre o token da página HTML inicial e inclua-o em toda requisição POST.
2. Rotar IP sem renovar cookies
Se você troca o IP mas reutiliza cookies antigos, o DataDome detecta a inconsistância e bloqueia. Sempre faça um GET inicial para cada nova sessão de proxy.
3. Usar requests em vez de curl_cffi
O fingerprint TLS do requests é detectado em 100% das tentativas. Sempre use curl_cffi com impersonate="chrome120".
4. Ignorar o robots.txt
O Glassdoor publica um arquivo robots.txt que deve ser respeitado. Verifique-o antes de iniciar qualquer coleta. O respeito ao robots.txt é uma boa prática reconhecida pela W3C e por tribunais em jurisdições dos EUA.
5. Não implementar jitter
Requisições em intervalos perfeitamente regulares são um sinal clássico de automação. Adicione jitter aleatório de pelo menos ±50% sobre o delay base.
Principais conclusões (Key Takeaways)
- Dados públicos apenas: Reviews truncadas e visão geral da empresa são acessíveis sem login; salários detalhados exigem autenticação — não raspe conteúdo protegido.
- Impersonação de TLS é obrigatória: Use
curl_cfficomimpersonate="chrome120";requestspuro é detectado em 100% das tentativas.- BFF GraphQL é o caminho: O endpoint
/bff/graphqlretorna JSON estruturado, exigindo apenas o headergd-csrf-token.- Sessões sticky preservam cookies: Mantenha o mesmo IP por 20-30 requisições para evitar invalidação de cookies do DataDome.
- Proxies residenciais > datacenter: Taxa de sucesso de 85-95% vs. menos de 10% para IPs de datacenter contra o DataDome.
- Pacing importa: 3-5 segundos entre requisições com jitter aleatório é o sweet spot para evitar limites de taxa.
Scraping ético e quando usar APIs oficiais
Raspar dados de reviews de funcionários levanta questões éticas sérias, especialmente sob o GDPR. Reviews no Glassdoor são conteúdo gerado por usuários que podem conter dados pessoais — nomes, cargos, localizações — que se enquadram no escopo do GDPR para usuários na UE. A Agência de Proteção de Dados da Irlanda (DPC) já multou plataformas por processamento inadequado de dados pessoais, e o regulador francês CNIL publicou orientações específicas sobre web scraping que exigem base legal para coleta.
Princípios para scraping ético do Glassdoor
- Agregue, não individualize: Colete médias e distribuições de ratings, não reviews individuais identificáveis.
- Anonimize cargos: Agrupe por categoria ("Engenheiro de Software" em vez de "Engenheiro de Software Sênior, Equipe de Pagamentos, Dublin").
- Respeite o
robots.txt: Verifique as diretivas antes de qualquer coleta. - Não raspe atrás de login: Conteúdo protegido por autenticação está claramente fora dos limites.
- Considere a licença oficial: O Glassdoor oferece um programa de parceria de dados para uso comercial em escala.
Quando uma API oficial é a escolha certa
Se seu caso de uso envolve análise competitiva de salários em escala nacional, relatórios de benchmark de RH ou produtos SaaS que dependem de dados do Glassdoor, uma licença de dados oficial é mais segura, mais confiável e mais escalável que scraping. O custo de uma licença é tipicamente menor que o custo de infraestrutura de proxies, manutenção de scrapers e risco legal. Para protótipos e PoVs com dados públicos agregados, o abordagem descrita neste artigo é suficiente.
Próximo passo: Configure sua conta no ProxyHat, escolha proxies residenciais com geo-targeting dos EUA (onde a maioria das reviews do Glassdoor está concentrada) e comece com 100 requisições de teste. Ajuste o pacing conforme seus resultados.






