Jak scrapować opinie i dane o wynagrodzeniach Glassdoor w 2026 — BFF GraphQL, DataDome i proxy

Praktyczny przewodnik po scrapowaniu publicznych opinii i przeglądów firm z Glassdoor z użyciem proxy residentialnych — obejmuje endpointy BFF GraphQL, tokeny gd-csrf-token, rotację IP i strategie omijania DataDome.

How to Scrape Glassdoor Company Reviews and Salaries in 2026: BFF GraphQL, DataDome, and Proxy Workarounds
W tym artykule

Ważne zastrzeżenie prawne: Ten przewodnik dotyczy wyłącznie dostępu do publicznie dostępnych danych na Glassdoor. Scrapowanie treści objętych murem logowania (pełne profile wynagrodzeń, dane osobowe pracowników) może naruszać Warunki Korzystania Glassdoor, amerykańską ustawę CFAA (Computer Fraud and Abuse Act) oraz europejskie RODO/GDPR. Przed rozpoczęciem projektów scrapingowych skonsultuj się z prawnikiem i rozważ oficjalną licencję na dane od Glassdoor lub partnerów takich jak Glassdoor for Employers.

HR-analytics i inżynierowie danych rynku pracy coraz częściej potrzebują zagregowanych opinii o firmach i wskaźników satysfakcji pracowników. Jak scrapować opinie i dane o wynagrodzeniach Glassdoor w 2026 roku, gdy platforma chroni się warstwami DataDome i Cloudflare Bot Management? Odpowiedź leży w połączeniu TLS-impersonation, endpointów BFF GraphQL oraz rotacyjnych proxy residentialnych. W tym przewodniku pokazujemy krok po kroku, jak zbudować Glassdoor reviews scraper, który działa stabilnie i etycznie.

Jak scrapować opinie i dane o wynagrodzeniach Glassdoor: co jest publiczne, a co za murem logowania

Glassdoor dzieli swoje dane na dwie strefy dostępności. Zrozumienie tej granicy jest kluczowe, bo determinuje całą architekturę scrapera i ramy prawne projektu.

Dane dostępne bez logowania

Bez konta możesz przeglądać:

  • Strony przeglądów firm pod URL-em /Reviews/<company>-Reviews-E<id>.htm — pokazują ocenę ogólną, skrócone treści pros/cons, stanowiska i daty.
  • Podstawowe informacje o firmie: branża, wielkość, siedziba, strona WWW.
  • Truncated review nodes — zwykle 2–3 opinie na stronie z obciętym tekstem (często do ~200 znaków).
  • Wyniki wyszukiwania firm w katalogu publicznym.

Te dane są wystarczające do budowy zagregowanych wskaźników: średnia ocena, rozkład ratingOverall, trendy temporalne, liczba opinii w czasie.

Dane za murem logowania (auth-walled)

Po zalogowaniu (lub po podaniu własnej wynagrodzenia/opinii — model „give-to-get”) odblokowuje się:

  • Pełne profile wynagrodzeń z podziałem na stanowiska, lokalizacje i lata doświadczenia.
  • Pelne treści opinii (nieobcięte).
  • Szczegółowe oceny w podkategoriach (kultura, zarządzanie, work-life balance).
  • Pytania rekrutacyjne i raporty z rozmów kwalifikacyjnych.

Scrapowanie treści za murem logowania nie jest objęte tym przewodnikiem. Wymaga konta, co automatycznie podlega ToS Glassdoor i zwiększa ryzyko prawne. Zamiast tego skupiamy się na publicznych, truncated review nodes dostępnych przez endpointy GraphQL.

Stack anty-botowy Glassdoor: DataDome + Cloudflare Bot Management

Glassdoor korzysta z co najmniej dwóch warstw ochrony, które razem eliminują większość amatorskich scraperów:

  1. DataDome — system ochrony botów oparty na ML, analizujący sygnatury przeglądarki, zachowanie sesji i reputację IP. DataDome jest szczególnie agresywny wobec adresów IP z datacenterów (AWS, GCP, DigitalOcean) oraz wobec requestów z niespójnymi nagłówkami TLS.
  2. Cloudflare Bot Management — warstwa JS challenge i TLS fingerprinting, która sprawdza, czy klient potrafi wykonać JavaScript i czy jego handshake TLS pasuje do deklarowanego User-Agent.

Dlaczego zwykły requests lub curl nie działa? Problem leży w TLS fingerprintingu. Biblioteki Pythona domyślnie używają OpenSSL, którego sygnatura JA3/JA4 różni się od Chrome czy Firefox. Cloudflare i DataDome potrafią wykryć tę rozbieżność i zablokować request jeszcze przed sprawdzeniem treści.

Rozwiązaniem jest curl_cffi — biblioteka Pythona, która wykorzystuje zmodyfikowany silnik curl do impersonacji TLS handshake przeglądarki Chrome. Dzięki temu JA3 fingerprint zgadza się z deklarowanym User-Agent, a request przechodzi pierwszą warstwę weryfikacji.

Endpointy BFF GraphQL i nagłówek gd-csrf-token

Glassdoor nie udokumentuje ich publicznie, ale ruch sieciowy ujawnia dwa kluczowe endpointy zwracające ustrukturyzowane JSON-y:

  • https://www.glassdoor.com/bff/graphql — główny endpoint BFF (Backend-for-Frontend) przyjmujący zapytania GraphQL.
  • https://www.glassdoor.com/graph — alternatywny endpoint GraphQL (starszy, wciąż aktywny dla niektórych operacji).

Każdy request do tych endpointów wymaga:

  • Nagłówka gd-csrf-token — token CSRF pobierany z metatagu strony HTML lub z ciasteczka gdId.
  • Spójnych ciasteczek sesji DataDome (datadome), które muszą być ważne dla danego IP.
  • Poprawnego User-Agent zgodnego z impersonacją TLS curl_cffi.
  • Nagłówka Content-Type: application/json i body z operacją GraphQL.

Kluczowa insight: ciasteczka DataDome są powiązane z adresem IP, na którym zostały wydane. Jeśli zmienisz IP mid-session, DataDome unieważni ciasteczko i zwróci challenge. Dlatego rotacyjne proxy residentialne z opcją sesji sticky są niezbędne.

Proxy residentialne vs datacenter: dlaczego IP scoring decyduje

DataDome klasyfikuje adresy IP według ich reputacji. Adresy z datacenterów (np. AWS 54.x.x.x) mają niemal zerowy trust score — DataDome wie, że to nie jest realny użytkownik. Adresy residentialne, pochodzące od ISP, mają trust score zbliżony do organicznego ruchu.

Typ proxyTrust score DataDomeStabilność sesjiKoszt/GBZalecane dla Glassdoor
DatacenterBardzo niskiSłaba (częste blokady)$0,5–1,5Nie
Residential rotacyjneWysokiDobra (z sticky session)$2–8Tak
MobileBardzo wysokiŚwietna$8–20Tak (premium)

Dla scrapowania Glassdoor optymalny wybór to residential proxy z sesją sticky — pozwala utrzymać ciasteczka DataDome ważne przez całą sesję paginacji, a jednocześnie można przełączyć IP przy nowym batchu firm. Zobacz naszą listę lokalizacji proxy, aby wybrać geo-targeting odpowiedni dla Twojego rynku.

Praktyczna implementacja: Python + curl_cffi + ProxyHat

Poniżej znajduje się kompletny, działający przykład pobierania jednej opinii z endpointu BFF GraphQL przez ProxyHat. Kod używa residential proxy z sesją sticky, aby utrzymać ciasteczka DataDome.

Krok 1: Instalacja zależności

pip install curl_cffi

Krok 2: Pobranie tokenu CSRF i ciasteczek z strony firmy

from curl_cffi import requests
import re, json

# ProxyHat residential proxy z sesją sticky (30 min)
PROXY_URL = "http://user-session-glassdoor01:pass@gate.proxyhat.com:8080"

session = requests.Session(impersonate="chrome")
session.proxies = {"http": PROXY_URL, "https": PROXY_URL}

# Krok 1: pobierz stronę HTML firmy, aby zdobyć gd-csrf-token i ciasteczka
company_url = "https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm"
resp = session.get(company_url, timeout=30)
print(f"Status: {resp.status_code}, IP trust OK")

# Wyciągnij gd-csrf-token z metatagu lub z ciasteczka
csrf_match = re.search(r'gd-csrf-token[^>]*content="([^"]+)"', resp.text)
csrf_token = csrf_match.group(1) if csrf_match else session.cookies.get("gdId", "")
print(f"CSRF token: {csrf_token[:20]}...")

Krok 3: Zapytanie GraphQL do BFF endpointu

# Krok 2: wyślij zapytanie GraphQL do BFF
graphql_url = "https://www.glassdoor.com/bff/graphql"

query = """
query EmployerReviews($employerId: Long!, $page: Int, $limit: Int) {
  employer(employerId: $employerId) {
    reviews(page: $page, limit: $limit) {
      nodes {
        ratingOverall
        pros
        cons
        jobTitle { name }
        reviewDateTime
      }
      pageInfo { hasNextPage currentPage }
    }
  }
}
"""

variables = {"employerId": 9079, "page": 1, "limit": 10}

headers = {
    "Content-Type": "application/json",
    "gd-csrf-token": csrf_token,
    "Referer": company_url,
    "Origin": "https://www.glassdoor.com",
}

payload = {"query": query, "variables": variables}

resp = session.post(graphql_url, json=payload, headers=headers, timeout=30)
data = resp.json()

reviews = data.get("data", {}).get("employer", {}).get("reviews", {}).get("nodes", [])
for r in reviews[:3]:
    print(f"Ocena: {r.get('ratingOverall')}, Stanowisko: {r.get('jobTitle', {}).get('name')}")
    print(f"  Pros: {r.get('pros', '')[:100]}")
    print(f"  Cons: {r.get('cons', '')[:100]}")

Krok 4: Alternatywa w Node.js (z undici i ProxyAgent)

import { request } from "undici";
import { ProxyAgent } from "undici";

const proxyAgent = new ProxyAgent(
  "http://user-session-glassdoor01:pass@gate.proxyhat.com:8080"
);

const query = `
query EmployerReviews($employerId: Long!, $limit: Int) {
  employer(employerId: $employerId) {
    reviews(limit: $limit) {
      nodes { ratingOverall pros cons jobTitle { name } }
    }
  }
}`;

const res = await request("https://www.glassdoor.com/bff/graphql", {
  method: "POST",
  dispatcher: proxyAgent,
  headers: {
    "Content-Type": "application/json",
    "gd-csrf-token": process.env.GD_CSRF_TOKEN,
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
  },
  body: JSON.stringify({
    query,
    variables: { employerId: 9079, limit: 10 },
  }),
});

const data = await res.body.json();
console.log(data.data.employer.reviews.nodes[0]);

Pełną dokumentację konfiguracji proxy znajdziesz na docs.proxyhat.com. Cennik proxy residentialnych i opcji sesji sticky jest dostępny na stronie cennika ProxyHat.

Paginacja, sesje sticky i strategie pacing

Kursory paginacji i przełączanie stron

Endpoint BFF GraphQL wspiera paginację offsetową (page, limit) oraz kursorową (after cursor). Dla dużych firm (np. Amazon z 30 000+ opinii) kursorowa paginacja jest stabilniejsza — offsetowa powyżej ~500 opinii może zwracać błędy lub duplikaty.

# Paginacja kursorowa z retry logic
def fetch_all_reviews(employer_id, max_pages=50):
    all_reviews = []
    cursor = None
    for page in range(max_pages):
        variables = {"employerId": employer_id, "limit": 20, "after": cursor}
        payload = {"query": query, "variables": variables}
        
        for attempt in range(3):
            try:
                resp = session.post(graphql_url, json=payload, headers=headers, timeout=30)
                if resp.status_code == 403:
                    # DataDome challenge — przełącz IP i odśwież ciasteczka
                    rotate_session(session)
                    continue
                data = resp.json()
                reviews = data["data"]["employer"]["reviews"]["nodes"]
                all_reviews.extend(reviews)
                cursor = data["data"]["employer"]["reviews"]["pageInfo"].get("endCursor")
                break
            except Exception as e:
                print(f"Retry {attempt}: {e}")
                time.sleep(2 ** attempt)
        
        if not cursor:
            break
        time.sleep(2)  # pacing: 2s między requestami
    return all_reviews

Sesje sticky: dlaczego i jak długo

ProxyHat obsługuje sesje sticky przez flagę -session- w nazwie użytkownika:

# Sesja sticky na 30 minut
http://user-session-gd-batch01:pass@gate.proxyhat.com:8080

# Nowa sesja dla nowej firmy
http://user-session-gd-batch02:pass@gate.proxyhat.com:8080

Rekomendowany cykl życia sesji:

  • 1 firma = 1 sesja sticky — utrzymuje ciasteczka DataDome ważne przez całą paginację.
  • Limit: ~200–300 requestów na sesję — potem DataDome zaczyna podnosić trust threshold.
  • Pacing: 1–3 sekundy między requestami — im wolniej, tym stabilniej.
  • Rotacja geo: jeśli scrapujesz firmy w UE, użyj user-country-DE-session-xxx:pass, aby IP pasowało do lokalizacji firmy.

Challenge-retry logic

Gdy DataDome zwróci 403 lub challenge page, scraper powinien:

  1. Zapisac obecny stan (cursor, page number).
  2. Utworzyć nową sesję sticky z nowym IP.
  3. Ponownie pobrać stronę HTML firmy, aby odświeżyć gd-csrf-token i ciasteczka.
  4. Wznowić paginację od zapisanego cursora.
  5. Jeśli 3 próby z rzędu kończą się blokadą — pauzuj na 15 minut.

Najczęstsze błędy i edge case'y

1. Mismatch TLS vs User-Agent

Najczęstsza przyczyna blokad. Jeśli używasz impersonate="chrome" w curl_cffi, User-Agent MUSI pasować do Chrome (nie Firefox, nie Safari). Mismatch = natychmiastowy 403.

2. Wygasły gd-csrf-token

Token CSRF wygasa po ~60 minutach. Przy długich sesjach paginacji odświeżaj go co 30–40 minut, ponownie pobierając stronę HTML firmy.

3. Zbyt wysoka współbieżność

DataDome analizuje wzorce behawioralne. 100 concurrent requests z tego samego IP = natychmiastowa flaga. Utrzymuj max 3–5 concurrent connections na sesję sticky.

4. Ignorowanie robots.txt

Glassdoor robots.txt wyraźnie blokuje większość ścieżek. Sprawdź go przed rozpoczęciem projektu i uszanuj reguły dla ścieżek, które są objęte Disallow.

Etyczne scrapowanie i kiedy użyć oficjalnego API

Scrapowanie danych publicznych jest legalne w wielu jurysdykcjach, ale „legalne” nie znaczy „bezryzykowne”. Oto zasady, których przestrzegamy:

  • Scrapuj tylko zagregowane, nieosobowe dane. Oceny, rozkłady ratingOverall, trendy temporalne — tak. Imiona recenzentów, dokładne daty z możliwością identyfikacji — nie.
  • Nigdy nie scrapuj za murem logowania. Wymaga to konta i automatycznie podlega ToS Glassdoor, co może skutkować zawieszeniem konta lub działaniami cywilnymi.
  • RODO/GDPR dla danych UE. Jeśli scrapujesz opinie pracowników firm z siedzibą w UE, pamiętaj że dane osobowe (nawet pseudonimizowane stanowiska + lokalizacja + data) mogą podlegać GDPR. Zagreguj do poziomu, który uniemożliwia reidentyfikację.
  • Uszanuj ToS i robots.txt. Jeśli Glassdoor wyraźnie zabrania automated access, rozważ alternatywy.
  • Rate limiting: nie przeciążaj infrastruktury. 1–3 req/s to bezpieczny próg.

Kiedy oficjalna licencja na dane jest właściwym wyborem

Jeśli Twój projekt to produkt komercyjny (np. platforma HR-analytics SaaS), rozważ:

  • Glassdoor for Employers API — dostęp do własnych danych firmowych.
  • Partnerstwa data licensing — Glassdoor oferuje licencje na zagregowane dane rynkowe dla enterprise klientów.
  • Alternatywne źródła: LinkedIn Talent Insights, Levels.fyi API, Bureau of Labor Statistics dla danych makro.

Dla jednorazowych analiz konkurencji lub badań akademickich, publiczny scraping z etycznymi ograniczeniami jest często wystarczający. Zobacz też nasze przypadki użycia web scraping oraz SERP tracking, aby poznać inne wzorce zbierania danych.

Kluczowe wnioski

Podsumowanie: Scrapowanie publicznych opinii Glassdoor w 2026 wymaga trzech komponentów: (1) curl_cffi do impersonacji TLS Chrome, (2) endpointów BFF GraphQL z nagłówkiem gd-csrf-token, (3) residential proxy z sesją sticky dla utrzymania ciasteczek DataDome. Scrapuj tylko dane publiczne, zagregowane i nieosobowe — pełne dane wynagrodzeń za murem logowania wymagają oficjalnej licencji.

  • Publiczne strony /Reviews/ zawierają truncated reviews — wystarczające do agregacji.
  • Endpoint /bff/graphql zwraca ustrukturyzowane JSON-y, ale wymaga gd-csrf-token i ważnych ciasteczek DataDome.
  • curl_cffi z impersonate="chrome" rozwiązuje problem TLS fingerprinting.
  • Residential proxy z sesją sticky (flaga -session-) utrzymuje ciasteczka ważne przez całą paginację.
  • Pacing 1–3 req/s, max 200–300 requestów na sesję, rotacja IP przy challenge.
  • Etyka: agreguj, nie identyfikuj, nie scrapuj za loginem, rozważ licencję dla produktów komercyjnych.

Często zadawane pytania

Często zadawane pytania

Jak scrapować opinie Glassdoor bez logowania?

Publiczne strony /Reviews/-Reviews-E.htm są dostępne bez logowania i zawierają skrócone opinie (truncated reviews). Możesz pobrać stronę HTML z curl_cffi (impersonacja Chrome TLS) przez residential proxy, a następnie wysłać zapytanie GraphQL do endpointu /bff/graphql z nagłówkiem gd-csrf-token. Pełne treści opinii i dane wynagrodzeń są dostępne tylko po zalogowaniu i nie powinny być scrapowane.

Dlaczego zwykły requests lub curl nie działa na Glassdoor?

Glassdoor korzysta z DataDome i Cloudflare Bot Management, które sprawdzają TLS fingerprint (JA3/JA4). Standardowe biblioteki Pythona używają OpenSSL, którego sygnatura TLS różni się od Chrome, co skutkuje natychmiastowym 403. curl_cffi z opcją impersonate='chrome' replikuje handshake TLS Chrome, omijając tę weryfikację.

Który typ proxy jest najlepszy do scrapowania Glassdoor?

Residential proxy z sesją sticky są optymalne. DataDome przypisuje niski trust score adresom datacenter (AWS, GCP), co skutkuje blokadami. Residential IP od ISP mają trust score zbliżony do organicznego ruchu. Sesja sticky (flaga -session- w ProxyHat) utrzymuje ciasteczka DataDome ważne przez całą sesję paginacji — kluczowe, bo ciasteczka są powiązane z IP.

Jak unikać blokad DataDome przy scrapowaniu Glassdoor?

Stosuj residential proxy z sesją sticky (max 200–300 requestów na sesję), utrzymuj pacing 1–3 req/s, używaj curl_cffi do impersonacji TLS Chrome, odświeżaj gd-csrf-token co 30–40 minut, i zaimplementuj challenge-retry logic: przy 403 przełącz IP, pobierz nową stronę HTML dla świeżych ciasteczek, i wznow paginację od zapisanego cursora. Max 3–5 concurrent connections na sesję.

Czy scrapowanie danych wynagrodzeń z Glassdoor jest legalne?

Scrapowanie publicznych, zagregowanych danych (oceny, rozkłady) jest legalne w wielu jurysdykcjach, ale scrapowanie treści za murem logowania (pełne wynagrodzenia) narusza ToS Glassdoor i może podlegać CFAA (USA) oraz GDPR (UE). Dla produktów komercyjnych rozważ oficjalną licencję na dane od Glassdoor lub alternatywne źródła jak BLS czy LinkedIn Talent Insights.

Gotowy, aby zacząć?

Dostęp do ponad 50 mln rezydencjalnych IP w ponad 148 krajach z filtrowaniem AI.

Zobacz cenyProxy rezydencjalne
← Powrót do Bloga