تنبيه قانوني: يخضع استخدام بيانات Glassdoor لشروط الخدمة الخاصة بالمنصة. في الولايات المتحدة، قد يخضع الوصول غير المصرّح به أو تجاوز تدابير الحماية التقنية لقانون CFAA. في الاتحاد الأوروبي، تنطبق GDPR على أي بيانات شخصية للموظفين. هذا الدليل يغطّي الوصول إلى البيانات العامة المتاحة دون تسجيل دخول فقط، ولا يشجّع على استخراج البيانات خلف جدار المصادقة. راجع شروط الخدمة واستشر مستشارًا قانونيًا قبل أي مشروع استخراج بيانات.
إذا كنت تبني منصة تحليلات للموارد البشرية أو تتابع اتجاهات سوق العمل، فمن المحتمل أنك واجهت جدار Glassdoor المضاد للبوتات. المنصة تستخدم طبقات حماية متعددة تجعل استخراج التقييمات والرواتب أمرًا صعبًا للغاية. في هذا الدليل، سنشرح كيفية استخراج تقييمات ورواتب شركات Glassdoor في 2026 باستخدام نقاط GraphQL غير الموثقة، وأداة curl_cffi لمحاكاة بصمة TLS، وبروكسي ProxyHat السكني الدوار.
ما الذي يمكن استخراجه من Glassdoor دون تسجيل دخول؟
قبل أن نغوص في التفاصيل التقنية، من الضروري فهم حدود ما هو متاح علنًا. صفحات نظرة عامة على الشركة مثل /Reviews/<company>-Reviews-E<id>.htm متاحة دون مصادقة وتعرض:
- التقييم الإجمالي للشركة (مثل 4.2 من 5).
- مقتطفات مقطوعة من المراجعات (عادة 2–3 أسطر من pros وcons).
- عدد المراجعات الإجمالي وتوزيع النجوم.
- المسمى الوظيفي للمراجع وتاريخه التقريبي.
في المقابل، البيانات التي تتطلب تسجيل دخول تشمل:
- النص الكامل للمراجعات (بدون اقتطاع).
- تفصيل الرواتب حسب المسمى والموقع والمستوى.
- أسئلة وأجوبة المقابلات الكاملة.
- بيانات التعويضات والمزايا التفصيلية.
هذا الدليل يقتصر على البيانات العامة المتاحة دون تسجيل دخول. استخراج المحتوى خلف جدار المصادقة ينتهك شروط الخدمة ويحمل مخاطر قانونية كبيرة.
مكدس Glassdoor المضاد للبوتات: DataDome وCloudflare
يستخدم Glassdoor طبقتين رئيسيتين للحماية: DataDome وCloudflare Bot Management. الفهم العميق لكيفية عملهما هو مفتاح تجاوزهما بأخلاقية.
DataDome وتسجيل بصمة المتصفح
DataDome يعتمد على أكثر من مجرد فحص عنوان IP. يجمع بصمة شاملة تشمل: رؤوس HTTP، ترتيب الرؤوس، بصمة TLS (JA3/JA4)، خصائص Canvas وWebGL، سرعة التفاعل، ونمط الطلبات. إذا كان طلبك يأتي من مكتبة HTTP قياسية مثل requests في Python، فإن بصمة TLS الخاصة بـ OpenSSL تختلف جذريًا عن بصمة Chrome الحقيقية، مما يكشف البوت فورًا.
Cloudflare Bot Management واختبار JS
طبقة Cloudflare تضيف تحدي JavaScript يتطلب تنفيذ كود JS في متصفح حقيقي أو محاكاة دقيقة. كما تستخدم بصمة TLS للتمييز بين المتصفحات الحقيقية والمكتبات البرمجية. هذا يعني أن curl العادي أو requests سيفشلان قبل حتى الوصول إلى البيانات.
لماذا curl_cffi هو الحل؟
curl_cffi هي مكتبة Python تستخدم libcurl مع محرك BoringSSL (نفس مكتبة SSL في Chrome) لمحاكاة بصمة TLS بدقة. عند استخدام impersonate="chrome"، تُرسل المكتبة نفس رؤوس TLS ونفس ترتيبها الذي يرسله Chrome الحقيقي، مما يجعل الطلب يبدو أصليًا على مستوى الاتصال المشفّر.
| الأداة | بصمة TLS | تجاوز DataDome | سهولة الاستخدام |
|---|---|---|---|
| requests (Python) | OpenSSL — مكشوفة | لا | سهلة جدًا |
| curl_cffi | BoringSSL — محاكاة Chrome | نعم (مع بروكسي سكني) | سهلة |
| Playwright/Selenium | متصفح حقيقي | نعم | أبطع، استهلاك موارد أعلى |
| httpx (Python) | OpenSSL — مكشوفة | لا | سهلة |
نقاط GraphQL غير الموثقة في Glassdoor
Glassdoor يستخدم بنية BFF (Backend for Frontend) تعتمد على GraphQL. عند تصفّح صفحة المراجعات، يرسل المتصفح طلبات POST إلى نقاط نهاية مثل:
/bff/employer/graphql— لاستعلامات المراجعات والرواتب./graph— نقطة بديلة لبعض الاستعلامات.
هذه النقاط تعيد بيانات JSON منظمة بدلاً من HTML، مما يسهّل المعالجة بشكل كبير. لكنها تتطلب:
- رأس
gd-csrf-tokenصالح (يُستخرج من صفحة HTML الأولية أو من ملفات تعريف الارتباط). - رأس
Content-Type: application/json. - رؤوس
OriginوRefererمطابقة لمجال Glassdoor. - ملفات تعريف ارتباط DataDome صالحة (datadome cookie).
ميزة GraphQL أنك تحدد الحقول التي تريدها بالضبط — مثل ratingOverall وpros وcons وjobTitle — فتحصل على بيانات نظيفة دون تحليل HTML.
لماذا البروكسي السكني يتفوّق على DataDome
DataDome يطبّق نظام تسجيل نقاط (IP scoring) على كل عنوان IP. عناوين مراكز البيانات (Datacenter) تحصل على درجة منخفضة فورًا وتُحجب تلقائيًا. البروكسي السكني يستخدم عناوين IP حقيقية مخصّصة من مزودي إنترنت فعليين، مما يجعل الطلب يبدو وكأنه من مستخدم منزلي عادي.
مع ProxyHat، يمكنك توجيه الطلبات عبر مئات المواقع الجغرافية مع دوران عنوان IP لكل طلب أو جلسة لاصقة (sticky session) للحفاظ على ملفات تعريف الارتباط. هذا يقلّل من احتمالية الحجب بنسبة تتجاوز 90% مقارنة بالبروكسي الثابت.
مثال عملي: استخراج مراجعة واحدة عبر BFF GraphQL
إليك مثالًا كاملًا في Python يستخدم curl_cffi مع بروكسي ProxyHat السكني:
from curl_cffi import requests
import json
# بروكسي ProxyHat السكني مع استهداف جغرافي للولايات المتحدة وجلسة لاصقة
proxy = "http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080"
# رؤوس ضرورية
headers = {
"Content-Type": "application/json",
"gd-csrf-token": "YOUR_CSRF_TOKEN_HERE",
"Origin": "https://www.glassdoor.com",
"Referer": "https://www.glassdoor.com/Reviews/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/131.0.0.0 Safari/537.36",
}
# استعلام GraphQL لمراجعات الشركة
payload = {
"operationName": "EmployerReviews",
"variables": {
"employerId": 1234,
"cursor": None,
"limit": 10
},
"query": """query EmployerReviews($employerId: ID!, $cursor: String, $limit: Int) {
employer(id: $employerId) {
reviews(first: $limit, after: $cursor) {
nodes {
ratingOverall
pros
cons
jobTitle { title }
}
pageInfo { endCursor hasNextPage }
}
}
}"""
}
resp = requests.post(
"https://www.glassdoor.com/bff/employer/graphql",
headers=headers,
json=payload,
proxies={"http": proxy, "https": proxy},
impersonate="chrome"
)
data = resp.json()
reviews = data["data"]["employer"]["reviews"]["nodes"]
for review in reviews:
print(f"التقييم: {review['ratingOverall']}/5")
print(f"الإيجابيات: {review['pros'][:120]}")
print(f"السلبيات: {review['cons'][:120]}")
print(f"المسمى الوظيفي: {review['jobTitle']['title']}")
print("---")
ملاحظات مهمة:
- استبدل
PASSWORDبكلمة مرور ProxyHat وYOUR_CSRF_TOKEN_HEREبرمز CSRF المستخرج من الصفحة الأولية. - الجلسة اللاصقة
session-glassdoor01تحافظ على نفس عنوان IP وملفات تعريف الارتباط عبر الطلبات المتعددة. - إذا حصلت على خطأ 403، فهذا يعني أن DataDome حجب الطلب — جرّب تغيير الجلسة أو الانتظار.
مثال Node.js: استخراج المراجعات
const { request } = require('undici');
const proxyUrl = 'http://user-country-US-session-glassdoor02:PASSWORD@gate.proxyhat.com:8080';
async function scrapeReviews(employerId, csrfToken) {
const payload = {
operationName: 'EmployerReviews',
variables: { employerId, cursor: null, limit: 10 },
query: 'query EmployerReviews($employerId: ID!, $cursor: String, $limit: Int) { employer(id: $employerId) { reviews(first: $limit, after: $cursor) { nodes { ratingOverall pros cons jobTitle { title } } pageInfo { endCursor hasNextPage } } } }'
};
const res = await request('https://www.glassdoor.com/bff/employer/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'gd-csrf-token': csrfToken,
'Origin': 'https://www.glassdoor.com',
'Referer': 'https://www.glassdoor.com/Reviews/',
},
body: JSON.stringify(payload),
proxy: proxyUrl,
});
const data = await res.body.json();
return data.data.employer.reviews.nodes;
}
الترقيم (Pagination) وإدارة الجلسات
مؤشرات الترقيم (Cursors)
يستخدم GraphQL مؤشرات ترقيم قائمة على base64. بعد كل طلب، يُعيد الحقل pageInfo.endCursor المؤشر للصفحة التالية، وhasNextPage يخبرك إن كانت هناك المزيد من النتائج. مرّر endCursor كقيمة cursor في الطلب التالي.
cursor = None
all_reviews = []
while True:
payload["variables"]["cursor"] = cursor
resp = requests.post(
"https://www.glassdoor.com/bff/employer/graphql",
headers=headers,
json=payload,
proxies={"http": proxy, "https": proxy},
impersonate="chrome"
)
data = resp.json()
nodes = data["data"]["employer"]["reviews"]["nodes"]
all_reviews.extend(nodes)
page_info = data["data"]["employer"]["reviews"]["pageInfo"]
if not page_info["hasNextPage"]:
break
cursor = page_info["endCursor"]
time.sleep(2) # فاصل زمني بين الطلبات
الجلسات اللاصقة (Sticky Sessions)
عند استخدام DataDome، يجب الحفاظ على نفس عنوان IP لمدة الجلسة كاملة لأن ملف تعريف الارتباط datadome مرتبط بعنوان IP. إذا تغيّر IP بين الطلبات، ستفقد الجلسة مصداقيتها. استخدم علم session-xxx في اسم المستخدم لـ ProxyHat للحفاظ على نفس IP:
# نفس الجلسة لجميع طلبات الترقيم
proxy = "http://user-country-US-session-glassdoor01:PASSWORD@gate.proxyhat.com:8080"
إذا حصلت على خطأ 403، أنشئ جلسة جديدة بمعرّف مختلف:
# جلسة بديلة بعد الحجب
new_proxy = "http://user-country-US-session-glassdoor02:PASSWORD@gate.proxyhat.com:8080"
الوتيرة (Pacing) ومنطق إعادة المحاولة
الوتيرة المناسبة حرجة لتجنّب الحجب. نوصي بما يلي:
- فاصل 2–5 ثوانٍ بين كل طلب GraphQL.
- حد أقصى 100 طلب متزامن لكل جلسة.
- إعادة المحاولة مع تراجع أُسي (exponential backoff) عند 403 أو 429.
- تدوير الجلسة كل 50–100 طلب كإجراء وقائي.
import time, random
def fetch_with_retry(url, payload, proxy, headers, max_retries=3):
for attempt in range(max_retries):
resp = requests.post(
url, headers=headers, json=payload,
proxies={"http": proxy, "https": proxy},
impersonate="chrome"
)
if resp.status_code == 200:
return resp.json()
elif resp.status_code == 403:
# تدوير الجلسة
session_id = f"glassdoor{random.randint(10, 99)}"
proxy = f"http://user-country-US-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
time.sleep(10 * (attempt + 1))
else:
time.sleep(5 * (attempt + 1))
return None
أخطاء شائعة وحالات حدية
1. نسيان رأس gd-csrf-token
بدون هذا الرأس، تُعيد نقطة GraphQL خطأ 403 فورًا. استخرج الرمز من صفحة HTML الأولية أو من ملفات تعريف الارتباط بعد أول طلب ناجح.
2. استخدام بروكسي مركز بيانات
عناوين مراكز البيانات تُحجب بواسطة DataDome قبل حتى إرسال تحدي JS. استخدم دائمًا بروكسي سكني لاستخراج بيانات Glassdoor.
3. تغيير عنوان IP في منتصف الجلسة
إذا كنت تستخدم دوران IP لكل طلب، ستفقد ملف تعريف ارتباط DataDome. استخدم الجلسة اللاصقة طوال الترقيم، ثم بدّل الجلسة فقط عند الحاجة.
4. وتيرة عالية جدًا
إرسال 10 طلبات في الثانية سيؤدي إلى حجب فوري. حافظ على فاصل 2–5 ثوانٍ ومراقبة معدل النجاح.
5. تجاهل تغيّر نقاط النهاية
نقاط GraphQL غير الموثقة وقد تتغيّر دون إشعار. ابنِ منطقًا للتعامل مع تغيير المخطط (schema) واختبر بانتظام.
الاستخراج الأخلاقي ومتى تستخدم واجهات API الرسمية
الاستخراج الأخلاقي يعني احترام حدود المنصة وحقوق المستخدمين. إليك المبادئ التوجيهية:
- اجمع البيانات المجمّعة فقط: استخراج إحصاءات التقييم والتوزيع مقبول أكثر من استخراج نصوص المراجعات الفردية. اجمع متوسطات وتوزيعات بدلاً من المراجعات الخام.
- لا تستخرج خلف جدار المصادقة: البيانات التي تتطلب تسجيل دخول (الرواتب التفصيلية، المراجعات الكاملة) محمية بشروط الخدمة. لا تستخدم حسابات وهمية لتجاوز هذا.
- احترام GDPR: المراجعات قد تحتوي على بيانات شخصية (المسمى الوظيفي، الموقع، التاريخ). للبيانات من المستخدمين في الاتحاد الأوروبي، تأكد من إزالة المعرفات الشخصية أو عدم تخزينها.
- تجنّب الإفراط: لا ترسل آلاف الطلبات في الدقيقة. احترم الموارد.
متى تكون الترخيص الرسمي هو الخيار الصحيح؟
إذا كنت تحتاج بيانات Glassdoor على نطاق واسع وبشكل مستمر، فإن شراء ترخيص بيانات رسمي من Glassdoor قد يكون أكثر فعالية من حيث التكلفة. الترخيص يوفر:
- وصولاً موثوقًا دون مخاطر قانونية.
- بيانات منظمة ومحدّثة.
- دعمًا فنيًا وضمانات جودة.
- لا حاجة لإدارة بنية بروكسي ومنطق إعادة محاولة.
للحالات الأخرى — مثل البحث الأكاديمي المحدود أو تحليل شركة واحدة — قد يكون الاستخراج الأخلاقي للبيانات العامة كافيًا. قيّم احتياجاتك وميزانيتك ومستوى التحمل للمخاطر قبل الاختيار.
النقاط الرئيسية
خلاصة سريعة:
- البيانات العامة على Glassdoor محدودة — مقتطفات مراجعات وتقييمات إجمالية فقط دون تسجيل دخول.
- DataDome + Cloudflare يتطلبان محاكاة بصمة TLS باستخدام curl_cffi مع
impersonate="chrome".- نقاط GraphQL مثل
/bff/employer/graphqlتعيد بيانات JSON منظمة لكنها تتطلب رأسgd-csrf-token.- البروكسي السكني من ProxyHat مع الجلسات اللاصقة يتفوّق على تسجيل نقاط DataDome لعناوين IP.
- حافظ على فاصل 2–5 ثوانٍ بين الطلبات، وحد أقصى 100 جلسة متزامنة، وأعد المحاولة بتراجع أُسي.
- الاستخراج الأخلاقي يعني البيانات المجمّعة فقط، لا استخراج خلف المصادقة، واحترام GDPR.
إذا كنت جاهزًا للبدء، تحقق من أسعار ProxyHat أو استكشف حالات استخدام تتبع نتائج البحث أو راجع التوثيق الرسمي للتفاصيل التقنية.






