إذا كنت تعمل في استخراج البيانات من المتاجر الإلكترونية، أو مراقبة أسعار المنافسين، أو جمع البيانات من المواقع، فأنت تعرف المشكلة: المواقع تحظر عناوين IP، وتطلب كابتشا، أو تُرجع صفحات فارغة. يمكن أن يصل معدل الحظر (نسبة الطلبات المحظورة) إلى 70-90%، مما يجعل الاستخراج مستحيلاً. في هذا المقال سنستعرض طرقاً محددة ستساعد في تقليل معدل الحظر إلى 5-10% وجمع البيانات بشكل مستقر.
سننظر في الحلول التقنية (تدوير البروكسي، رؤوس HTTP، fingerprinting) والأنماط السلوكية (التأخيرات، محاكاة تصرفات المستخدم). جميع الطرق مختبرة عملياً عند استخراج البيانات من Wildberries وOzon وAvito والمنصات الأجنبية.
لماذا تحظر المواقع أدوات الاستخراج: المحفزات الرئيسية
قبل استعراض طرق الحماية، من المهم فهم كيف تحدد المواقع الزيارات الآلية. أنظمة مكافحة الروبوتات الحديثة (Cloudflare وAkamai وDataDome وImperva) تحلل عشرات المعاملات لكل طلب. إليك المحفزات الرئيسية للحظر:
محفزات على مستوى الشبكة:
- عدد كبير جداً من الطلبات من عنوان IP واحد (مثلاً، أكثر من 100 طلب في الدقيقة)
- عنوان IP من نطاقات مراكز البيانات المعروفة (AWS وGoogle Cloud وHetzner)
- عدم التطابق الجغرافي: عنوان IP من روسيا يطلب النسخة الإنجليزية من الموقع
- عدم وجود سجل DNS عكسي لعنوان IP
محفزات على مستوى HTTP:
- عدم وجود أو رؤوس HTTP غير صحيحة (User-Agent وAccept-Language وReferer)
- ترتيب الرؤوس يختلف عن المعتاد للمتصفح
- إصدار TLS/SSL لا يتطابق مع المتصفح المعلن
- عدم وجود كوكيز أو استخدامها بشكل غير صحيح
محفزات على مستوى المتصفح (JavaScript):
- عدم تنفيذ JavaScript (إذا كنت تستخدم عميل HTTP بسيط)
- بصمة المتصفح: Canvas وWebGL وAudioContext والخطوط المثبتة
- عدم وجود حركة الماوس أو التمرير أو النقرات
- حجم نافذة المتصفح (المتصفحات بدون واجهة غالباً ما يكون لها أحجام غير قياسية)
- وجود الأتمتة: خصائص navigator.webdriver وwindow.chrome
محفزات سلوكية:
- التنقل السريع جداً بين الصفحات (أقل من ثانية واحدة)
- فترات متساوية بين الطلبات (مثلاً، كل ثانيتين بالضبط)
- تصفح متسلسل للصفحات (1، 2، 3، 4...) بدون تخطي
- عدم وجود إجراءات نموذجية للمستخدم: البحث، الفلاتر، عرض الصور
على سبيل المثال، عند استخراج البيانات من Wildberries، الخطأ النموذجي هو إرسال الطلبات كل 0.5 ثانية من عنوان IP واحد. سيحدد نظام Cloudflare لمكافحة الروبوتات النمط فوراً ويحظر عنوان IP لمدة 24 ساعة. المستخدم الحقيقي يقضي 5-15 ثانية في عرض بطاقة المنتج، ويمرر الصفحة، وينقر على الصور.
تدوير البروكسي: كيفية تغيير عناوين IP بشكل صحيح
استخدام البروكسي هو الطريقة الأساسية لتقليل معدل الحظر. لكن من المهم ليس فقط شراء البروكسي، بل إعداد التدوير بشكل صحيح. إليك الاستراتيجيات المجربة:
اختيار نوع البروكسي للاستخراج
| نوع البروكسي | معدل الحظر | السرعة | متى تستخدمه |
|---|---|---|---|
| بروكسي مراكز البيانات | مرتفع (40-60%) | عالية جداً | مواقع بسيطة بدون حماية، استخراج جماعي مع مجموعة كبيرة من IP |
| بروكسي سكنية | منخفض (5-15%) | متوسطة | المتاجر الإلكترونية (Wildberries وOzon)، مواقع مع Cloudflare، الشبكات الاجتماعية |
| بروكسي محمولة | منخفض جداً (2-8%) | منخفضة | مواقع ذات حماية قوية، النسخ المحمولة من التطبيقات |
لاستخراج البيانات من المتاجر الإلكترونية (Wildberries وOzon وAvito) يُنصح باستخدام البروكسي السكنية — لديها عناوين IP لمستخدمين منزليين حقيقيين، يصعب تمييزها عن الزيارات العادية. بروكسي مراكز البيانات مناسبة للمواقع الأقل حماية أو عندما تحتاج إلى أقصى سرعة مع حجم كبير من البيانات.
استراتيجيات تدوير عناوين IP
الاستراتيجية 1: التدوير حسب الوقت
غيّر عنوان IP كل 5-10 دقائق. هذا توازن مثالي: طويل بما يكفي لعدم إثارة الشكوك بالتغيير المتكرر، لكن متكرر بما يكفي لعدم تراكم سجل الطلبات على عنوان IP واحد.
مثال: عند استخراج كتالوج من 1000 منتج بفاصل 3 ثوانٍ بين الطلبات، سيكون عنوان IP واحد نشطاً لحوالي 100 طلب، ثم يحدث التغيير.
الاستراتيجية 2: التدوير حسب عدد الطلبات
غيّر عنوان IP بعد 50-150 طلب. هذا يساعد على تجنب تراكم النشاط المشبوه على عنوان واحد. أضف عشوائية: ليس 100 طلب بالضبط، بل من 80 إلى 120.
مثال: اضبط السكريبت بحيث يحدث تدوير البروكسي من المجموعة بعد عدد عشوائي من الطلبات (80-120).
الاستراتيجية 3: الجلسات الثابتة (Sticky sessions)
للمواقع التي تتطلب تسجيل دخول أو تعمل مع سلة التسوق، استخدم sticky sessions — تثبيت عنوان IP لمدة الجلسة (10-30 دقيقة). هذا يسمح بالحفاظ على الكوكيز وعدم إثارة الشكوك عند تغيير IP داخل جلسة واحدة.
مثال: عند استخراج البيانات من الحساب الشخصي على Ozon، استخدم عنوان IP واحد لتسجيل الدخول وجميع الطلبات اللاحقة ضمن جلسة مدتها 15 دقيقة.
مهم: لا تستخدم نفس عنوان IP لمهام مختلفة. إذا تم حظر عنوان IP عند استخراج البيانات من موقع واحد، لا تستخدمه فوراً لموقع آخر — انتظر 24-48 ساعة.
حجم مجموعة البروكسي
الحد الأدنى لحجم المجموعة يعتمد على كثافة الاستخراج:
- كثافة منخفضة (حتى 10,000 طلب في اليوم): 10-20 بروكسي
- كثافة متوسطة (10,000 - 100,000 طلب في اليوم): 50-100 بروكسي
- كثافة عالية (أكثر من 100,000 طلب في اليوم): 200+ بروكسي أو سكنية مع تدوير تلقائي
للبروكسي السكنية مع التدوير على كل طلب (rotating proxies)، يمكن أن يكون حجم المجموعة أصغر، حيث يقوم المزود تلقائياً بإدراج عنوان IP جديد من مجموعته التي تضم ملايين العناوين.
User-Agent ورؤوس HTTP: محاكاة المتصفح الحقيقي
حتى مع بروكسي جيدة، يمكن حظرك إذا بدت رؤوس HTTP مشبوهة. تحلل المواقع ليس فقط User-Agent، بل أيضاً ترتيب الرؤوس وقيمها وتطابقها مع بعضها البعض.
User-Agent الصحيح
لا تستخدم نفس User-Agent لجميع الطلبات. أنشئ قائمة بالمتصفحات الشائعة واختر منها عشوائياً:
user_agents = [
# Chrome على Windows
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
# Chrome على macOS
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
# Firefox على Windows
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
# Safari على macOS
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15",
# Edge على Windows
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
]
خطأ: استخدام إصدارات قديمة من المتصفحات (مثلاً، Chrome 80) — سيثير هذا الشكوك فوراً. حدّث قائمة User-Agent كل 2-3 أشهر، بتتبع الإصدارات الحالية على موقع whatismybrowser.com.
مجموعة كاملة من رؤوس HTTP
المتصفحات الحديثة ترسل 15-20 رأساً. إليك المجموعة الدنيا الضرورية لمحاكاة Chrome:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"DNT": "1",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Cache-Control": "max-age=0",
"sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"'
}
لاحظ رؤوس Sec-Fetch-* وsec-ch-ua-* — ظهرت في الإصدارات الجديدة من Chrome وغيابها قد يكشف الأتمتة.
ترتيب الرؤوس مهم
المتصفحات ترسل الرؤوس بترتيب معين. على سبيل المثال، Chrome دائماً يضع Host أولاً، ثم Connection وUser-Agent وهكذا. إذا كنت تستخدم مكتبة requests في Python، قد يكون الترتيب أبجدياً، مما يكشف الأتمتة.
الحل: استخدم مكتبات تشكل الرؤوس بشكل صحيح (curl_cffi لـ Python وgot لـ Node.js) أو متصفحات بدون واجهة (Puppeteer وPlaywright وSelenium) التي تولد الرؤوس كمتصفح حقيقي.
التأخير بين الطلبات: الفترات المثلى
واحدة من أبسط الطرق لكنها فعالة لتقليل معدل الحظر — التأخيرات الصحيحة بين الطلبات. المستخدم الحقيقي لا يمكنه فتح 10 صفحات في الثانية، لذلك الطلبات السريعة جداً تسبب الحظر فوراً.
تأخيرات عشوائية بدلاً من ثابتة
لا تستخدم تأخيراً ثابتاً (مثلاً، ثانيتين بالضبط بين الطلبات). أنظمة مكافحة الروبوتات تحدد هذا النمط بسهولة. استخدم فاصلاً عشوائياً:
import random
import time
# بدلاً من التأخير الثابت
time.sleep(2) # ❌ سيء
# استخدم فاصلاً عشوائياً
delay = random.uniform(2.5, 5.5) # ✅ جيد
time.sleep(delay)
الفترات الموصى بها لمواقع مختلفة
| نوع الموقع | الحد الأدنى للتأخير | التأخير الموصى به | أمثلة |
|---|---|---|---|
| متاجر إلكترونية محمية | 3-5 ثوانٍ | 5-10 ثوانٍ | Wildberries وOzon وLamoda |
| لوحات الإعلانات | 2-4 ثوانٍ | 4-8 ثوانٍ | Avito وYula وCIAN |
| مواقع إخبارية | 1-2 ثانية | 2-4 ثوانٍ | RBC وKommersant وVedomosti |
| API بدون قيود | 0.5-1 ثانية | 1-2 ثانية | APIs مفتوحة، موجزات RSS |
تأخيرات تكيفية بناءً على استجابات الخادم
النهج المتقدم — تغيير التأخيرات ديناميكياً اعتماداً على استجابات الخادم:
base_delay = 3.0 # التأخير الأساسي
delay_multiplier = 1.0
response = requests.get(url, headers=headers, proxies=proxies)
# إذا حصلنا على كابتشا أو 429 — نزيد التأخير
if response.status_code == 429 or 'captcha' in response.text.lower():
delay_multiplier *= 1.5
print(f"تم اكتشاف حماية، نزيد التأخير إلى {base_delay * delay_multiplier}ث")
# إذا كان كل شيء على ما يرام — يمكننا التسريع قليلاً
elif response.status_code == 200:
delay_multiplier = max(1.0, delay_multiplier * 0.95)
time.sleep(random.uniform(base_delay * delay_multiplier, base_delay * delay_multiplier * 1.5))
يسمح هذا النهج بالتباطؤ تلقائياً عند اكتشاف الحماية والتسريع عندما لا يُظهر الموقع عدوانية.
الحماية من fingerprinting: Canvas وWebGL والخطوط
إذا كان الموقع يستخدم JavaScript للتحقق، فإن رؤوس HTTP البسيطة ليست كافية. أنظمة مكافحة الروبوتات الحديثة تنشئ "بصمة" المتصفح (fingerprint) بناءً على عشرات المعاملات: Canvas وWebGL والخطوط المثبتة والمنطقة الزمنية ودقة الشاشة وغيرها.
المعاملات الأساسية لـ fingerprinting
Canvas fingerprinting
يرسم الموقع صورة غير مرئية في Canvas ويقرأها. المتصفحات وأنظمة التشغيل المختلفة تعرض الصورة بشكل مختلف، مما ينشئ بصمة فريدة. المتصفحات بدون واجهة غالباً ما تولد Canvas متطابقاً، مما يكشف الأتمتة.
WebGL fingerprinting
مشابه لـ Canvas، لكن يستخدم العرض ثلاثي الأبعاد. تُقرأ معلومات عن بطاقة الفيديو والتعريفات والإضافات المدعومة. المتصفحات بدون واجهة غالباً ما تُظهر عرضاً برمجياً (SwiftShader) بدلاً من GPU حقيقي.
الخطوط المثبتة
يمكن لـ JavaScript تحديد قائمة الخطوط المثبتة. المتصفحات بدون واجهة عادة لديها مجموعة دنيا من خطوط النظام، مما يختلف عن المستخدم الحقيقي الذي لديه Microsoft Office وAdobe وبرامج أخرى مثبتة.
خصائص Navigator
خصائص navigator.webdriver وnavigator.plugins وnavigator.languages تكشف الأتمتة. على سبيل المثال، في Selenium navigator.webdriver === true، مما تحدده أنظمة مكافحة الروبوتات فوراً.
أدوات لتجاوز fingerprinting
لتجاوز fingerprinting استخدم أدوات متخصصة:
- Undetected ChromeDriver (Python) — نسخة معدلة من Selenium تخفي علامات الأتمتة
- Puppeteer Stealth (Node.js) — إضافة لـ Puppeteer تستبدل معاملات fingerprint
- Playwright مع stealth — مشابه لـ Puppeteer، لكن مع دعم أفضل لمتصفحات مختلفة
- متصفحات مكافحة الكشف (Dolphin Anty وAdsPower وMultilogin) — لمن لا يريد كتابة الكود، هذه المتصفحات تستبدل fingerprint تلقائياً
مثال على استخدام undetected-chromedriver في Python:
import undetected_chromedriver as uc
# ننشئ متصفحاً مع حماية من الكشف
options = uc.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
driver = uc.Chrome(options=options)
driver.get('https://example.com')
# نتحقق من أن navigator.webdriver === undefined
webdriver_status = driver.execute_script("return navigator.webdriver")
print(f"navigator.webdriver: {webdriver_status}") # يجب أن يكون None/undefined
إدارة الكوكيز والجلسات
العديد من المواقع تستخدم الكوكيز لتتبع سلوك المستخدمين. الإدارة الصحيحة للكوكيز تساعد على تجنب الحظر والظهور كمستخدم حقيقي.
حفظ وإعادة استخدام الكوكيز
بدلاً من إنشاء جلسة جديدة لكل طلب، احفظ الكوكيز واستخدمها مرة أخرى. هذا يحاكي سلوك المستخدم الحقيقي الذي يعود إلى الموقع:
import requests
import pickle
session = requests.Session()
# الزيارة الأولى — نحصل على الكوكيز
response = session.get('https://example.com')
# نحفظ الكوكيز في ملف
with open('cookies.pkl', 'wb') as f:
pickle.dump(session.cookies, f)
# لاحقاً نحمّل الكوكيز
with open('cookies.pkl', 'rb') as f:
session.cookies.update(pickle.load(f))
# الآن الطلبات تبدو من مستخدم عائد
response = session.get('https://example.com/catalog')
تسخين الجلسة قبل الاستخراج
لا تبدأ الاستخراج مباشرة من الصفحات المستهدفة. حاكِ سلوك المستخدم الحقيقي:
- افتح الصفحة الرئيسية للموقع
- انتظر 2-5 ثوانٍ
- افتح صفحة فئة أو قسم
- انتظر 3-7 ثوانٍ
- فقط بعد ذلك ابدأ باستخراج الصفحات المستهدفة
هذا ينشئ سجل نشاط في الكوكيز ويقلل احتمالية الحظر.
معالجة كوكيز الجلسة والرموز
بعض المواقع تولد رموزاً فريدة عند الزيارة الأولى وتتحقق منها في الطلبات اللاحقة. على سبيل المثال، Wildberries يستخدم رمزاً في رأس x-requested-with. احفظ دائماً هذه الرموز من الاستجابة الأولى وأرسلها في الطلبات اللاحقة.
عرض JavaScript: متى يكون ضرورياً
العديد من المواقع الحديثة تحمّل المحتوى عبر JavaScript. إذا كنت تستخدم عميل HTTP بسيط (requests في Python وaxios في Node.js)، ستحصل على صفحة فارغة أو نائب. في هذه الحالات يكون عرض JavaScript ضرورياً.
متى يكون عرض JavaScript ضرورياً
- الموقع يستخدم React أو Vue أو Angular — المحتوى يُحمّل بعد التحميل الأولي للصفحة
- البيانات تُحمّل عبر طلبات AJAX/Fetch
- الموقع يتطلب تنفيذ JavaScript لتوليد الرموز أو الكوكيز
- وجود حماية من الروبوتات تتطلب تنفيذ كود JS (مثلاً، Cloudflare Challenge)
أدوات لعرض JavaScript
| الأداة | اللغة | السرعة | تجاوز الحماية |
|---|---|---|---|
| Selenium | Python وJava وC# | بطيئة | متوسط (مع undetected-chromedriver) |
| Puppeteer | Node.js | متوسطة | جيد (مع puppeteer-extra-plugin-stealth) |
| Playwright | Python وNode.js وJava | سريعة | ممتاز |
| Splash | HTTP API | متوسطة | ضعيف |
لمعظم المهام يُنصح بـ Playwright — أسرع من Selenium، ويتجاوز الحماية بشكل أفضل، ولديه API أكثر ملاءمة.
البديل: اعتراض طلبات API
غالباً يمكن تجنب عرض JavaScript إذا وجدت طلبات API التي يستخدمها الموقع لتحميل البيانات. افتح DevTools (F12) ← تبويب Network ← فلتر XHR/Fetch وانظر ما هي الطلبات التي يرسلها الموقع. ثم كرر هذه الطلبات مباشرة عبر عميل HTTP.
مثال: Wildberries يحمّل بيانات المنتجات عبر API https://catalog.wb.ru/catalog/.... بدلاً من عرض الصفحة بأكملها يمكن طلب هذا API مباشرة، وهو أسرع 10-20 مرة.
تجاوز الكابتشا: الحلول التلقائية
حتى مع البروكسي والرؤوس الصحيحة قد تواجه كابتشا. هناك عدة مناهج لحلها:
أنواع الكابتشا وطرق الحل
reCAPTCHA v2 (علامة "أنا لست روبوت")
تُحل عبر خدمات التعرف: 2Captcha وAnti-Captcha وCapMonster. التكلفة: $1-3 لكل 1000 حل. وقت الحل: 10-30 ثانية.
reCAPTCHA v3 (غير مرئية، قائمة على النقاط)
أكثر تعقيداً. تحلل سلوك المستخدم وتعطي نقاطاً من 0 إلى 1. التجاوز: استخدام متصفحات بدون واجهة مع fingerprint صحيح + محاكاة تصرفات المستخدم (حركة الماوس، النقرات).
hCaptcha
مشابه لـ reCAPTCHA، يُستخدم في العديد من المواقع. يُحل عبر نفس خدمات التعرف. التكلفة: $0.5-2 لكل 1000 حل.
Cloudflare Challenge
تحدي JavaScript يتحقق من المتصفح. التجاوز: استخدام مكتبات متخصصة (cloudscraper لـ Python وcloudflare-scraper لـ Node.js) أو خدمات (FlareSolverr).
دمج خدمة التعرف على الكابتشا
مثال على دمج 2Captcha في Python:
from twocaptcha import TwoCaptcha
solver = TwoCaptcha('YOUR_API_KEY')
try:
# نحل reCAPTCHA v2
result = solver.recaptcha(
sitekey='6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
url='https://example.com'
)
# نحصل على رمز الحل
captcha_token = result['code']
# نرسل النموذج مع الرمز
response = requests.post('https://example.com/submit', data={
'g-recaptcha-response': captcha_token
})
except Exception as e:
print(f"خطأ في حل الكابتشا: {e}")
مهم: حل الكابتشا يبطئ الاستخراج 10-30 مرة ويزيد التكلفة. استخدمه فقط عندما لا تعمل الطرق الأخرى. جرب أولاً تحسين البروكسي وfingerprint والتأخيرات.
تحديد المعدل: كيفية عدم تجاوز حدود الموقع
العديد من المواقع لديها حدود صريحة أو ضمنية على عدد الطلبات. تجاوز هذه الحدود يؤدي إلى حظر مؤقت أو دائم لعنوان IP.
تحديد حدود الموقع
انتبه لرؤوس HTTP في استجابات الخادم:
X-RateLimit-Limit— الحد الأقصى لعدد الطلبات في الفترةX-RateLimit-Remaining— كم طلباً متبقياًX-RateLimit-Reset— متى سيتم إعادة تعيين الحد (Unix timestamp)Retry-After— بعد كم ثانية يمكن تكرار الطلب
إذا حصلت على رمز الحالة 429 (Too Many Requests)، فهذا يعني تجاوز الحد. اقرأ رأس Retry-After وانتظر الوقت المحدد قبل الطلب التالي.
تنفيذ محدد المعدل
أنشئ آلية للتحكم في سرعة الطلبات: