Скрейпинг Glassdoor: отзывы и зарплаты компаний в 2026 году

Практическое руководство по сбору публичных отзывов и данных о зарплатах с Glassdoor через BFF GraphQL и residential-прокси ProxyHat. Обход DataDome, TLS-фингерпринтинг, пагинация и этические ограничения.

How to Scrape Glassdoor Company Reviews and Salaries in 2026 (BFF GraphQL, DataDome, and Proxies)

Важно: Эта статья посвящена сбору исключительно публичных данных с 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 как ChromeHTTP/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 критичны три фактора:

  1. ASN-репутация: residential IP от Comcast, AT&T, Vodafone не вызывают подозрений. Datacenter IP от OVH — мгновенный флаг.
  2. Географическое распределение: запросы из 10 разных городов выглядят естественнее, чем 1000 запросов из одного дата-центра.
  3. 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.

Готовы начать?

Доступ к более чем 50 млн резидентных IP в 148+ странах с AI-фильтрацией.

Смотреть ценыРезидентные прокси
← Вернуться в Блог