Важно: Эта статья посвящена сбору исключительно публичных данных с Glassdoor. Перед любым скрейпингом изучите Условия использования (Terms of Service) Glassdoor, а также применимые законы: Computer Fraud and Abuse Act (CFAA) в США и GDPR в ЕС. Сбор данных за стеной авторизации, персональных данных сотрудников или нарушение robots.txt может быть незаконным. Если вы не уверены — используйте официальное API или приобретите лицензию на данные.
Скрейпинг Glassdoor — задача, с которой сталкиваются HR-аналитики, исследователи рынка труда и data-driven рекрутеры. Платформа хранит миллионы отзывов сотрудников и оценок зарплат, но активно защищает контент с помощью DataDome и Cloudflare Bot Management. В этом руководстве мы разберём, как скрейпить Glassdoor легально и технически грамотно: что доступно без авторизации, как работать с BFF GraphQL-эндпоинтами и почему residential-прокси критически важны для обхода IP-скоринга.
Скрейпинг Glassdoor: что публично, а что за логином
Glassdoor разделяет контент на два уровня доступа. Понимание этой границы — первый шаг к легальному сбору данных.
Доступно без авторизации
- Обзор компании на странице
/Reviews/<company>-Reviews-E<id>.htm— рейтинг, количество отзывов, краткое описание. - Усечённые отзывы — первые ~2–3 предложения полей «Pros» и «Cons», заголовок должности, общая оценка (1–5 звёзд).
- Список отзывов с пагинацией — первые страницы доступны анонимно, но после ~10 страниц Glassdoor часто требует вход.
- Базовая информация о зарплатах — средние значения по должностям видны частично, но детальные разбивки (percentiles, base + bonus) закрыты.
За стеной авторизации
- Полный текст отзывов (после усечения).
- Детальные зарплатные разбивки по регионам, стажу и типу занятости.
- Расширенная фильтрация отзывов по дате, отделу, типу сотрудника.
- Вопросы с собеседований и ответы на них.
Ключевое правило: Не скрейпите данные за логином. Помимо нарушения ToS, это создаёт риски по CFAA (в США) и GDPR (в ЕС), если данные содержат персональную информацию. Ограничьтесь агрегированными, обезличенными отзывами.
Антибот-стек Glassdoor: DataDome + Cloudflare
Glassdoor использует двухуровневую защиту от ботов. Понимание того, как работают эти системы, определяет выбор инструментов.
DataDome
DataDome — это коммерческая антибот-система, которая анализирует поведенческие сигналы, TLS-фингерпринты, заголовки браузера и репутацию IP-адресов. Для скрейпинга Glassdoor критичны три аспекта DataDome:
- IP-скоринг: дата-центр IP-адреса сразу помечаются как高风险. Residential-прокси с реальными ASN значительно снижают риск блокировки.
- TLS-фингерпринтинг: DataDome проверяет JA3/JA4-хэш TLS-рукопожатия. Обычный
requestsв Python использует TLS-стек urllib3, который легко отличим от Chrome. Решение —curl_cffiс impersonate-режимом. - Cookie-валидация: DataDome выдаёт cookie
datadome, который нужно сохранять и переиспользовать в рамках сессии. Смена IP без обновления cookie триггерит повторный challenge.
Cloudflare Bot Management
Поверх DataDome Glassdoor использует Cloudflare Bot Management, который добавляет JavaScript-челленджи и управляемый challenge. Если Cloudflare пропускает запрос, он попадает к DataDome — и наоборот. Это означает, что ваш HTTP-клиент должен выглядеть как настоящий Chrome на всех уровнях: TLS, заголовки, порядок cookies.
Почему curl_cffi, а не requests
Библиотека curl_cffi использует libcurl с поддержкой BoringSSL и позволяет имперсонализировать TLS-стек Chrome 120+. Это критично: JA3-хэш requests отличается от Chrome, и DataDome блокирует запрос ещё до проверки заголовков.
| Инструмент | TLS-имперсонация | JA3 как Chrome | HTTP/2 | Рекомендация |
|---|---|---|---|---|
| requests | Нет | Нет | Нет | Не подходит |
| httpx | Нет | Нет | Да | Не подходит |
| curl_cffi | Да (Chrome 120+) | Да | Да | Рекомендуется |
| Playwright | Через браузер | Да | Да | Медленнее, но надёжнее |
BFF GraphQL-эндпоинты Glassdoor: структура и заголовки
Glassdoor использует внутренний BFF (Backend-for-Frontend) слой с GraphQL-эндпоинтами. Эти эндпоинты не задокументированы, но возвращают структурированный JSON вместо HTML — что значительно удобнее для парсинга.
Ключевые эндпоинты
/graph— основной GraphQL-эндпоинт для отзывов и оценок./bff/— BFF-прокси, добавляющий CSRF-токены и сессионные данные.
Обязательные заголовки
Для успешного запроса к BFF GraphQL нужны:
- gd-csrf-token — CSRF-токен, который Glassdoor генерирует на странице компании. Его нужно сначала извлечь из HTML или из cookie.
- Content-Type: application/json — строго JSON, не form-encoded.
- Cookie: gdId=...; datadome=... — сессионные cookie, включая DataDome.
- User-Agent — полный Chrome User-Agent, соответствующий TLS-имперсонации.
Пример GraphQL-запроса для отзывов:
{
"operationName": "EmployerReviews",
"variables": {
"employerId": 6056,
"page": 1,
"pageSize": 10,
"filter": {}
},
"query": "query EmployerReviews($employerId: ID!, $page: Int, $pageSize: Int) { employer(id: $employerId) { reviews(page: $page, pageSize: $pageSize) { nodes { id ratingOverall pros cons jobTitle } totalCount } } }"
}
Ответ приходит в виде структурированного JSON с полями ratingOverall (1–5), pros, cons, jobTitle — это именно те данные, которые видны в усечённом виде на публичной странице.
Почему residential-прокси превосходят datacenter при скрейпинге Glassdoor
DataDome присваивает каждому IP-адресу репутационный скор. Дата-центр IP-адреса (AWS, DigitalOcean, Hetzner) имеют репутацию «bot» почти по умолчанию. Residential-прокси используют IP-адреса реальных ISP, что снижает скор и вероятность challenge.
Для Glassdoor reviews scraper критичны три фактора:
- ASN-репутация: residential IP от Comcast, AT&T, Vodafone не вызывают подозрений. Datacenter IP от OVH — мгновенный флаг.
- Географическое распределение: запросы из 10 разных городов выглядят естественнее, чем 1000 запросов из одного дата-центра.
- Sticky-сессии: DataDome cookie привязаны к IP. Если IP меняется каждый запрос, cookie инвалидируются. Sticky-сессии на 10–30 минут решают эту проблему.
С ProxyHat вы можете комбинировать residential-прокси с geo-таргетингом и sticky-сессиями. Подробнее о тарифах — на странице цен ProxyHat. Полный список локаций доступен на странице локаций прокси.
Практический пример: Python + curl_cffi + ProxyHat
Ниже — рабочий пример скрейпинга отзывов Glassdoor через BFF GraphQL с использованием residential-прокси ProxyHat. Код извлекает один отзыв с полями ratingOverall, pros, cons и jobTitle.
import json
import re
from curl_cffi import requests as cffi_requests
# ProxyHat residential proxy with sticky session
PROXY_URL = "http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080"
HEADERS = {
"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",
"Accept": "application/json",
"Content-Type": "application/json",
"Referer": "https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm",
}
def get_csrf_token(session, employer_url):
"""Extract gd-csrf-token from the employer page HTML."""
resp = session.get(employer_url, proxies={"http": PROXY_URL, "https": PROXY_URL},
impersonate="chrome120", timeout=30)
match = re.search(r'gd-csrf-token["\s:]+([\w-]+)', resp.text)
if match:
return match.group(1)
# Fallback: check meta tags or script blocks
match = re.search(r'csrfToken["\s:]+"([\w-]+)"', resp.text)
return match.group(1) if match else None
def scrape_glassdoor_reviews(employer_id=9079, page=1, page_size=10):
"""Scrape one page of reviews via BFF GraphQL."""
session = cffi_requests.Session()
employer_url = f"https://www.glassdoor.com/Reviews/Google-Reviews-E{employer_id}.htm"
# Step 1: Visit employer page to get cookies + CSRF token
csrf = get_csrf_token(session, employer_url)
if not csrf:
raise Exception("Could not extract gd-csrf-token")
# Step 2: Post to GraphQL endpoint
graphql_url = "https://www.glassdoor.com/graph"
headers = HEADERS.copy()
headers["gd-csrf-token"] = csrf
payload = {
"operationName": "EmployerReviews",
"variables": {
"employerId": employer_id,
"page": page,
"pageSize": page_size,
"filter": {}
},
"query": """query EmployerReviews($employerId: ID!, $page: Int, $pageSize: Int) {
employer(id: $employerId) {
reviews(page: $page, pageSize: $pageSize) {
nodes { id ratingOverall pros cons jobTitle }
totalCount
}
}
}"""
}
resp = session.post(
graphql_url,
headers=headers,
json=payload,
proxies={"http": PROXY_URL, "https": PROXY_URL},
impersonate="chrome120",
timeout=30
)
data = resp.json()
reviews = data.get("data", {}).get("employer", {}).get("reviews", {})
nodes = reviews.get("nodes", [])
total = reviews.get("totalCount", 0)
# Parse one review node
if nodes:
r = nodes[0]
print(f"Rating: {r.get('ratingOverall')}")
print(f"Job Title: {r.get('jobTitle')}")
print(f"Pros: {r.get('pros', '')[:200]}")
print(f"Cons: {r.get('cons', '')[:200]}")
print(f"Total reviews available: {total}")
return nodes
if __name__ == "__main__":
reviews = scrape_glassdoor_reviews(employer_id=9079, page=1, page_size=10)
print(f"\nFetched {len(reviews)} reviews")
Node.js вариант с SOCKS5
Если вы предпочитаете Node.js, вот упрощённый пример через undici с SOCKS5-прокси ProxyHat:
import { SocksProxyAgent } from 'socks-proxy-agent';
import { fetch } from 'undici';
const proxyAgent = new SocksProxyAgent(
'socks5://user-country-US-session-glassdoor02:PASSWORD@gate.proxyhat.com:1080'
);
async function fetchReviews(employerId, csrfToken, cookies) {
const resp = await fetch('https://www.glassdoor.com/graph', {
method: 'POST',
dispatcher: proxyAgent,
headers: {
'Content-Type': 'application/json',
'gd-csrf-token': csrfToken,
'Cookie': cookies,
'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',
},
body: JSON.stringify({
operationName: 'EmployerReviews',
variables: { employerId, page: 1, pageSize: 10, filter: {} },
query: `query EmployerReviews($employerId: ID!, $page: Int, $pageSize: Int) {
employer(id: $employerId) {
reviews(page: $page, pageSize: $pageSize) {
nodes { id ratingOverall pros cons jobTitle }
totalCount
}
}
}`
})
});
return await resp.json();
}
Документация по параметрам прокси доступна на docs.proxyhat.com. Подробнее о применении прокси для веб-скрейпинга — в нашем use-case по веб-скрейпингу.
Пагинация, sticky-сессии и стратегия retry
Курсоры и пагинация
Glassdoor BFF GraphQL использует offset-based пагинацию (параметры page и pageSize), а не cursor-based. Однако после ~10 страниц без авторизации Glassdoor часто возвращает пустой результат или 403. Рекомендуемые практики:
- Запрашивайте
pageSize: 10— это естественный размер страницы для браузерного интерфейса. - Делайте паузу 3–5 секунд между запросами страниц.
- Если получили 403 или пустой результат — меняйте sticky-сессию и IP.
Sticky-сессии ProxyHat
Используйте флаг session- в username для привязки IP-адреса на 10–30 минут. Это сохраняет DataDome cookie валидными:
# Sticky session: same IP for ~30 minutes
PROXY_URL = "http://user-country-US-session-batch01:PASSWORD@gate.proxyhat.com:8080"
# Rotate session for new IP batch
PROXY_URL_2 = "http://user-country-US-session-batch02:PASSWORD@gate.proxyhat.com:8080"
Логика retry при challenge
import time
import random
def fetch_with_retry(scrape_func, max_retries=3, employer_id=9079):
for attempt in range(max_retries):
try:
result = scrape_func(employer_id=employer_id)
if result:
return result
except Exception as e:
print(f"Attempt {attempt+1} failed: {e}")
# Rotate session ID to get new IP
session_id = f"glassdoor-retry-{random.randint(1000, 9999)}"
# Update proxy URL with new session...
time.sleep(5 + random.uniform(2, 8)) # Jittered backoff
raise Exception(f"Failed after {max_retries} retries")
Рекомендуемый pacing
- Запросов в минуту на IP: не более 20 (3 сек между запросами).
- Параллельных сессий: 5–10 с разными sticky-session ID.
- Время между сменами IP: 30–60 минут на сессию.
- Общий объём: 500–1000 отзывов в час с 5 concurrent сессиями.
Glassdoor salary data: что доступно и как собирать
Glassdoor salary data — наиболее востребованный, но и наиболее защищённый тип данных. Без авторизации доступны:
- Средняя зарплата по должности (агрегированное число).
- Количество отчётов о зарплатах (для оценки выборки).
- Общий диапазон (min/max) в виде усечённых значений.
Детальные разбивки (percentiles, base + bonus + stock, фильтры по региону) — только за логином. Мы не рекомендуем собирать данные за авторизацией: это нарушает ToS Glassdoor и может подпадать под CFAA.
Для агрегированных зарплатных данных используйте тот же BFF GraphQL с другой операцией:
payload = {
"operationName": "EmployerSalaries",
"variables": {
"employerId": 9079,
"page": 1,
"pageSize": 20
},
"query": """query EmployerSalaries($employerId: ID!, $page: Int, $pageSize: Int) {
employer(id: $employerId) {
salaries(page: $page, pageSize: $pageSize) {
nodes { jobTitle medianSalary count }
totalCount
}
}
}"""
}
Типичные ошибки и edge cases
1. Игнорирование TLS-фингерпринта
Использование requests или httpx без имперсонации — самая частая ошибка. DataDome блокирует по JA3 ещё до проверки заголовков. Всегда используйте curl_cffi с impersonate="chrome120".
2. Смена IP без обновления cookies
Если вы меняете IP, но не обновляете DataDome cookie, новый IP получит challenge. Решение: sticky-сессии ProxyHat с одним session-ID на всю пагинационную цепочку.
3. Слишком высокая частота запросов
Более 30 запросов в минуту с одного IP — почти гарантированный блок. DataDome анализирует не только частоту, но и паттерн (равномерные интервалы = бот). Используйте jittered delays.
4. Отсутствие Referer-заголовка
GraphQL-запрос без Referer, указывающего на страницу компании, выглядит подозрительно. Всегда устанавливайте Referer на URL страницы работодателя.
5. Парсинг HTML вместо GraphQL
Парсинг HTML-страниц через BeautifulSoup работает, но хрупок: Glassdoor часто меняет вёрстку. BFF GraphQL возвращает стабильный JSON, который меняется реже.
Этический скрейпинг: когда остановиться
Сбор данных с Glassdoor находится в серой зоне. Вот несколько принципов, которые помогут остаться на легальной стороне:
Собирайте только агрегированные, обезличенные данные
Отзывы сотрудников могут содержать косвенно идентифицирующую информацию (комбинация должности + отдела + даты). Не сохраняйте поля, которые могут привести к деанонимизации. Агрегируйте на уровне компании и должности, а не на уровне отдельного отзыва.
Соблюдайте robots.txt и ToS
Проверьте robots.txt Glassdoor перед скрейпингом. Условия использования платформы прямо ограничивают автоматизированный сбор данных. Если ваш use-case требует больших объёмов — рассмотрите официальную лицензию на данные от Glassdoor.
GDPR для данных сотрудников в ЕС
Отзывы сотрудников из ЕС могут содержать персональные данные в смысле GDPR, даже если они опубликованы анонимно. Если вы собираете данные о компаниях с сотрудниками в ЕС:
- Не храните текст отзывов целиком — только агрегированные метрики (средний рейтинг, количество отзывов).
- Не пытайтесь сопоставить анонимные отзывы с реальными сотрудниками.
- Учитывайте право на забвение: если сотрудник удаляет отзыв, ваши данные устаревают.
Когда использовать официальное API или лицензию
Для коммерческих продуктов (HR-аналитика, конкурентная разведка зарплат, платформы сравнения работодателей) единственный надёжный путь — официальная лицензия на данные Glassdoor. Это снимает юридические риски и обеспечивает стабильный доступ без необходимости обхода антибот-систем.
Для исследовательских и некоммерческих целей сбор публичных агрегированных данных через прокси приемлем, если вы соблюдаете частоту запросов, не храните персональные данные и уважаете ToS.
Ключевые выводы
- Скрейпинг Glassdoor технически возможен для публичных данных: усечённых отзывов, общих оценок и агрегированных зарплат.
- Используйте curl_cffi с Chrome TLS-имперсонацией — без этого DataDome блокирует по JA3-фингерпринту.
- BFF GraphQL-эндпоинты (
/graph) возвращают структурированный JSON. Необходим заголовокgd-csrf-token.- Residential-прокси ProxyHat с sticky-сессиями (
session-) сохраняют DataDome cookie валидными и снижают IP-скоринг.- Не скрейпите данные за логином — это нарушает ToS и может подпадать под CFAA и GDPR.
- Для коммерческих продуктов рассмотрите официальную лицензию на данные Glassdoor.
Готовы начать? Изучите тарифы ProxyHat для residential-прокси или прочитайте наш use-case по SERP-трекингу для смежных задач. Документация по подключению — на docs.proxyhat.com.






