دليل DrissionPage الشامل: دمج بروكسيات ProxyHat لكشط الويب باحتراف

تعلم كيف تستخدم DrissionPage مع بروكسيات ProxyHat السكنية لدمج طلبات HTTP وتحكم Chromium في أداة واحدة، مع أمثلة كود عملية وأنماط إنتاج حقيقية.

DrissionPage Proxy Guide: One Python Tool for HTTP and Chromium Scraping
En este artículo

DrissionPage هو إطار عمل Python يجمع بين بساطة requests وقوة تحكم متصفح Chromium في أداة واحدة — وهذا بالضبط ما يحتاجه كل مطور يعاني من إدارة أداتين منفصلتين لكشط الويب. في هذا الدليل، سنغطي كيفية دمج drissionpage proxy مع بروكسيات ProxyHat السكنية، وكيفية استخدام SessionPage وChromiumPage وWebPage بشكل idiomatic، مع أمثلة كود قابلة للتشغيل وأنماط إنتاج حقيقية.

تنبيه قانوني وأخلاقي: هذا الدليل مخصص لكشف البيانات العامة المتاحة فقط. تأكد من الالتزام بـ قانون الاحتيال وإساءة استخدام الحاسوب (CFAA) واللائحة العامة لحماية البيانات (GDPR) في الاتحاد الأوروبي. احترم ملف robots.txt وشروط الخدمة وحدود المعدل لكل موقع، وفضّل واجهات API الرسمية عند توفرها.

ما هو DrissionPage ولماذا يهم مستخدمي البروكسيات؟

DrissionPage هو مشروع Python مفتوح المصدر (GitHub) يحلّ مشكلة شائعة: بعض الصفحات تحتاج فقط طلب HTTP بسيط، وبعضها يتطلب متصفحاً كاملاً لتنفيذ JavaScript. تقليدياً، يستخدم المطورون requests للأول وSelenium/Playwright للثاني — مع الحفاظ على جلستين منفصلتين، وكوكيز غير متزامنة، ومنطق مكرر.

يقدّم DrissionPage ثلاثة أنواع صفحات:

الصفحة الوصف متى تستخدمها التكلفة النسبية
SessionPage طلبات HTTP بأسلوب requests، خفيفة وسريعة صفحات HTML ثابتة، واجهات API، ملفات JSON منخفضة جداً
ChromiumPage تحكم كامل بمتصفح Chromium عبر CDP صفحات JavaScript معقدة، SPA، تفاعل بصري مرتفعة (RAM + CPU)
WebPage يبدّل بين الوضعين مع مشاركة الكوكيز والحالة عند عدم المعرفة المسبقة بنوع الصفحة متوسطة (تبدأ خفيفة وتترقّى)

بالنسبة لمستخدمي البروكسيات، هذا يعني أنك تستطيع تقليل استهلاك البروكسيات السكنية المكلفة بشكل كبير. بدلاً من تشغيل متصفح كامل يستهلك 200-400 ميجابايت RAM لكل جلسة لزيارة صفحة HTML بسيطة، تستخدم SessionPage الذي يكاد لا يستهلك موارد — وتلجأ إلى ChromiumPage فقط عند الحاجة الفعلية.

السياق التقني: لماذا توجد هذه المشكلة؟

المواقع الحديثة تنقسم إلى فئتين من حيث الكشط:

  • صفحات يخدمها الخادم مباشرة: HTML كامل يصل في الرد الأول، لا حاجة لتنفيذ JavaScript. مثل صفحات Wikipedia أو منتديات قديمة أو واجهات REST API.
  • تطبيقات صفحة واحدة (SPA): HTML فارغ تقريباً، المحتوى يُحمّل عبر XHR/Fetch بعد تنفيذ JavaScript. مثل React/Vue/Angular apps.

المشكلة أنك غالباً لا تعرف أي نوع تتعامل معه قبل الطلب. بعض المواقع تبدأ بـ HTML ثابت ثم تضيف تفاعلاً عبر JS. أخرى تكتشف الـ User-Agent وتعيد محتوى مختلفاً. وهذا يقودنا إلى نمط الترقية التصاعدية: ابدأ بـ HTTP، وإذا فشل، ارتقِ إلى المتصفح.

البروكسيات السكنية ضرورية هنا لأن المواقع المحمية (مثل منصات التجارة الإلكترونية الكبرى ومحركات البحث) تكتشف بروكسيات مراكز البيانات بسرعة عبر قواعد بيانات ASN مثل MaxMind. عنوان IP سكني يبدو كأنه مستخدم حقيقي، مما يقلل احتمال الحجب بنسبة قد تصل إلى 70-90% في بعض الحالات.

واجهة DrissionPage الـ idiomatic: ele() وeles() وlisten

محددات العناصر

DrissionPage يستخدم نظام محددات خاص به يجمع بين بساطة CSS وقوة XPath:

from DrissionPage import WebPage

page = WebPage()

# محددات نصية بسيطة
btn = page.ele('تسجيل الدخول')          # بحث بالنص
title = page.ele('tag:h1')              # حسب الوسم

# محددات بخصائص محددة
input = page.ele('@class=search-box')   # حسب class
link = page.ele('@href=https://example.com')

# CSS selectors التقليدية
items = page.eles('css:.product-card')

# XPath
price = page.ele('xpath://span[@class="price"]')

# eles() ترجع قائمة بكل العناصر المطابقة
all_links = page.eles('tag:a')

النقطة المهمة: ele() ترجع عنصراً واحداً، وeles() ترجع قائمة. المحدد @class=... هو اختصار DrissionPage لـ tag:x@class=... — أبسط من CSS selector في كثير من الحالات.

التقاط طلبات XHR الخلفية بـ listen

واحدة من أقوى ميزات DrissionPage هي listen — التقط طلبات الشبكة الخلفية دون الحاجة لتحليل DOM:

from DrissionPage import ChromiumPage

page = ChromiumPage()

# ابدأ الاستماع لطلبات تحتوي على 'api' في URL
page.listen.start('api/products')

page.get('https://shop.example.com/products')

# انتظر أول حزمة مطابقة
packet = page.listen.wait(timeout=10)

if packet:
    print(f'URL: {packet.url}')
    print(f'Status: {packet.response.status}')
    # البيانات غالباً JSON
    data = packet.response.body
    print(data)

page.listen.stop()

هذه الميزة تكتشف واجهات API المخفية التي تستخدمها SPA لتحميل البيانات. بدلاً من كشط DOM المُعرَض، تلتقط JSON الخام مباشرة — أسرع وأنظف وأقل عرضة للتكسّر عند تغيير التصميم.

إعداد DrissionPage Proxy مع ProxyHat

البروكسيات في SessionPage (وضع HTTP)

from DrissionPage import SessionPage

page = SessionPage()

# بروكسي HTTP عبر ProxyHat — بروكسيات سكنية
page.set.proxies('http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080')

page.get('https://httpbin.org/ip')
print(page.html)

البروكسيات في ChromiumPage (وضع المتصفح)

from DrissionPage import ChromiumPage, ChromiumOptions

co = ChromiumOptions()
co.set_proxy('http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080')

# إعدادات إضافية للإنتاج
co.headless(True)          # وضع headless للتوفير
co.set_argument('--no-sandbox')
co.set_argument('--disable-gpu')

page = ChromiumPage(co)
page.get('https://httpbin.org/ip')
print(page.ele('tag:pre').text)

لاحظ أن اسم المستخدم في ProxyHat يحمل معلومات الاستهداف الجغرافي والجلسة:

  • user-country-US — عنوان IP من الولايات المتحدة
  • user-country-DE-city-berlin — عنوان IP من برلين تحديداً
  • user-session-abc123 — جلسة لزجة تحافظ على نفس IP

يمكنك مزجها: user-country-US-session-abc123 يعطيك IP ثابت من الولايات المتحدة طوال عمر الجلسة. اطلّع على صفحة المواقع لقائمة الدول المتاحة.

مثال كامل: WebPage مع ترقية من HTTP إلى Chromium

الآن نطبّق النمط الكامل: نبدأ بـ HTTP لصفحة بسيطة، ثم نترقّى إلى Chromium عند الحاجة — مع بروكسيات سكنية من ProxyHat.

import time
import random
from DrissionPage import WebPage, ChromiumOptions

# --- بناء اسم مستخدم ProxyHat ديناميكياً ---
def build_proxy_username(country='US', session_id=None):
    """يبني اسم مستخدم ProxyHat مع استهداف جغرافي وجلسة لزجة."""
    parts = ['user', f'country-{country}']
    if session_id:
        parts.append(f'session-{session_id}')
    return '-'.join(parts)

PROXY_PASSWORD = 'your_password'

def make_proxy_url(country='US', session_id=None, protocol='http'):
    username = build_proxy_username(country, session_id)
    if protocol == 'socks5':
        return f'socks5://{username}:{PROXY_PASSWORD}@gate.proxyhat.com:1080'
    return f'http://{username}:{PROXY_PASSWORD}@gate.proxyhat.com:8080'

# --- بدء WebPage في وضع HTTP ---
page = WebPage(mode='s')  # 's' = SessionPage mode

# تعيين بروكسي سكني أمريكي مع جلسة لزجة
proxy_http = make_proxy_url(country='US', session_id='scrape-001')
page.set.proxies(proxy_http)

# الطلب الأول — HTTP خفيف
page.get('https://httpbin.org/ip')
print('وضع HTTP - IP:', page.ele('tag:pre').text)

# الآن نترقّى إلى وضع المتصفح للصفحة التالية
# الكوكيز والحالة تُنقل تلقائياً
page.change_mode()  # يتحول إلى ChromiumPage

# تعيين بروكسي للمتصفح أيضاً
co = ChromiumOptions()
co.set_proxy(proxy_http)
co.headless(True)
page.set.options(co)

page.get('https://quotes.toscrape.com/js/')

# التقاط البيانات بعد تنفيذ JavaScript
quotes = page.eles('css:.quote')
for q in quotes:
    text = q.ele('css:.text').text
    author = q.ele('css:.author').text
    print(f'{author}: {text[:60]}...')

# تأخير عشوائي احتراماً للخادم
time.sleep(random.uniform(1.5, 3.0))

page.close()

هذا النمط يحقق أفضل توازن بين التكلفة والموثوقية: الطلب الأول يكلفك تقريباً صفر موارد (HTTP فقط)، والثاني يستخدم المتصفح فقط لأن الصفحة تتطلب JavaScript.

أنماط الإنتاج: التزامن، إعادة المحاولة، وتثبيت البروكسيات

تثبيت البروكسيات لكل جلسة

عند كشط موقع يتطلب تسجيل دخول أو يحفظ حالة في الكوكيز، تحتاج نفس IP طوال الجلسة. استخدم session-ID ثابت:

import uuid

class ScraperSession:
    def __init__(self, country='US'):
        self.session_id = str(uuid.uuid4())[:8]
        self.proxy = make_proxy_url(country, self.session_id)
        self.page = WebPage(mode='s')
        self.page.set.proxies(self.proxy)
        self.retries = 3

    def fetch(self, url):
        for attempt in range(self.retries):
            try:
                resp = self.page.get(url, timeout=15)
                if resp.status_code == 200:
                    return resp
                elif resp.status_code == 403:
                    # حجب — غيّر IP بالجلسة التالية
                    self.session_id = str(uuid.uuid4())[:8]
                    self.proxy = make_proxy_url('US', self.session_id)
                    self.page.set.proxies(self.proxy)
                    time.sleep(random.uniform(2, 5))
                else:
                    time.sleep(2 ** attempt)  # backoff أُسي
            except Exception as e:
                print(f'محاولة {attempt+1} فشلت: {e}')
                time.sleep(2 ** attempt)
        return None

    def close(self):
        self.page.close()

اكتشاف واجهات API المخفية

كثير من المواقع تُحمّل بياناتها عبر XHR بعد تحميل الصفحة. بدلاً من كشط DOM، استخدم listen لالتقاط JSON مباشرة:

from DrissionPage import ChromiumPage, ChromiumOptions

def scrape_via_api(url, api_pattern, country='US'):
    proxy = make_proxy_url(country, session_id='api-cap-001')
    co = ChromiumOptions()
    co.set_proxy(proxy)
    co.headless(True)

    page = ChromiumPage(co)

    # ابدأ الاستماع قبل التصفح
    page.listen.start(api_pattern)

    page.get(url)

    # اجمع كل الحزم المطابقة خلال 15 ثانية
    packets = page.listen.wait(timeout=15, count=5, fit_count=False)

    results = []
    if packets:
        for pkt in packets:
            if pkt.response:
                results.append({
                    'url': pkt.url,
                    'status': pkt.response.status,
                    'body': pkt.response.body
                })

    page.listen.stop()
    page.close()
    return results

# مثال: التقاط بيانات المنتجات من SPA
api_data = scrape_via_api(
    'https://shop.example.com/category/electronics',
    'api/v2/products'
)
for item in api_data:
    print(f'API: {item["url"]} → {len(str(item["body"]))} bytes')

التحكم في التزامن

عند تشغيل عدة scraper متوازية، احترم حدود التزامن لكل من المتصفحات والبروكسيات:

  • المتصفحات: كل ChromiumPage يستهلك ~200-400 ميجابايت RAM. على جهاز بـ 8 جيجابايت، لا تتجاوز 15-20 متصفح متزامن.
  • البروكسيات: ProxyHat يدعم اتصالات متزامنة عالية، لكن توزيع الطلبات على جلسات مختلفة يقلل الضغط على IP واحد.
  • الحاويات: استخدم Docker لعزل كل scraper مع Chromium خاص به. كل حاوية تأخذ بروكسي مستقل.
import concurrent.futures
import threading

# قفل لتقييد التزامن
MAX_CONCURRENT = 10
semaphore = threading.Semaphore(MAX_CONCURRENT)

def scrape_task(url, country):
    with semaphore:
        session = ScraperSession(country=country)
        try:
            result = session.fetch(url)
            return result
        finally:
            session.close()

urls = [
    ('https://example.com/page1', 'US'),
    ('https://example.com/page2', 'DE'),
    ('https://example.com/page3', 'GB'),
]

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
    futures = [executor.submit(scrape_task, url, c) for url, c in urls]
    results = [f.result() for f in concurrent.futures.as_completed(futures)]

للتوسع أكثر، استخدم Celery أو asyncio مع تجمع عمليات. كل عامل يأخذ جلسة ProxyHat مستقلة بـ session ID فريد.

متى لا تترقّى إلى المتصفح؟

الترقية إلى Chromium ليست دائماً الحل الصحيح. إليك متى تبقى في وضع HTTP:

  • الصفحة تُعيد JSON مباشرة: إذا كان الرد application/json، لا داعي للمتصفح.
  • HTML الخادم يحتوي كل البيانات: تحقق من المصدر قبل الترقية — قد تجد البيانات في <script> tags أو JSON-LD.
  • الواجهة لها API رسمي: استخدم وثائق ProxyHat لإعداد بروكسي بسيط واطلب API مباشرة. أرخص وأسرع وأكثر استقراراً.
  • الموقع يحجب المتصفحات headless: بعض المواقع تكتشف navigator.webdriver وتحجب حتى مع بروكسي سكني. في هذه الحالة، SessionPage مع headers مخصصة قد يعمل بشكل أفضل.

القاعدة العامة: ابدأ بـ HTTP، اختبر، ثم ارتقِ فقط عند الفشل الموثّق. هذا يقلل تكلفة البنية التحتية بنسبة قد تصل إلى 60-80% مقارنة بتشغيل متصفح لكل طلب.

أخطاء شائعة وحالات حدّية

1. نسيان تعيين البروكسيات بعد change_mode()

عند التبديل من SessionPage إلى ChromiumPage عبر change_mode()، الكوكيز تُنقل لكن البروكسيات لا تُنقل تلقائياً. يجب إعادة تعيينها:

page = WebPage(mode='s')
page.set.proxies(proxy_url)
page.get('https://example.com')

page.change_mode()  # يتحول إلى Chromium
# ⚠️ أعد تعيين البروكسيات!
co = ChromiumOptions()
co.set_proxy(proxy_url)
page.set.options(co)

2. استخدام جلسة لزجة لفترة طويلة جداً

الجلسة اللزجة تحافظ على نفس IP، لكن إذا أرسلت 500+ طلب من نفس IP خلال ساعة، قد يحجبك الموقع. أدِر عمر الجلسة:

  • أعد إنشاء session ID كل 50-100 طلب.
  • أضف تأخيراً عشوائياً بين 1-5 ثوانٍ.
  • راقب معدل الاستجابات 403/429 وأعد التدوير فوراً.

3. تجاهل robots.txt

قبل كشط أي موقع، تحقق من robots.txt. بعض المواقع تسمح بكشط أقسام معينة وتمنع أخرى. احترام هذا الملف ليس فقط أخلاقياً — بل يحميك قانونياً في كثير من الولايات القضائية.

4. عدم معالجة CAPTCHA

حتى مع بروكسيات سكنية، قد تواجه CAPTCHA. DrissionPage لا يحل CAPTCHA تلقائياً. استراتيجيات التعامل:

  • تقليل معدل الطلبات لتجنب تفعيل CAPTCHA أصلاً.
  • تدوير session ID عند مواجهة CAPTCHA لمحاولة IP جديد.
  • استخدام خدمات حل CAPTCHA خارجية عند الضرورة (مع مراجعة الشروط القانونية).

إعداد ProxyHat: الخطوات العملية

للبدء مع ProxyHat وDrissionPage:

  1. سجّل في dashboard.proxyhat.com واحصل على بيانات الاعتماد.
  2. اطّلع على صفحة الأسعار لاختيار الخطة المناسبة (سكنية أو مراكز بيانات أو مختلطة).
  3. استخدم gate.proxyhat.com:8080 لـ HTTP وgate.proxyhat.com:1080 لـ SOCKS5.
  4. ابنِ أسماء المستخدمين بمعلمات الاستهداف: user-country-XX-session-YYY.
  5. راجع حالة استخدام كشط الويب وتتبع نتائج البحث لمزيد من الأنماط.

النقاط الرئيسية

  • DrissionPage يوحّد HTTP والمتصفح في أداة واحدة — استخدم SessionPage للطلبات الخفيفة وChromiumPage للصفحات الديناميكية.
  • WebPage يبدّل بين الوضعين مع مشاركة الكوكيز، لكن أعد تعيين البروكسيات بعد التبديل.
  • drissionpage proxy يُعدّ عبر set.proxies() للـ HTTP وChromiumOptions.set_proxy() للمتصفح.
  • listen.start() يلتقط طلبات XHR الخلفية — أداة قوية لكشف واجهات API المخفية.
  • البروكسيات السكنية من ProxyHat تقلل الحجب للأهداف المحمية، مع استهداف جغرافي وجلسات لزجة.
  • ابدأ بـ HTTP وارتقِ للمتصفح فقط عند الحاجة — يوفر 60-80% من التكلفة.
  • احترم robots.txt وCFAA وGDPR — الكشط الأخلاقي يحميك قانونياً وعملياً.

الأسئلة الشائعة

ما هو DrissionPage؟

DrissionPage هو إطار عمل Python مفتوح المصدر يوحّد بين طلبات HTTP بأسلوب requests وتحكم متصفح Chromium عبر بروتوكول CDP في أداة واحدة. يوفّر ثلاث صفحات رئيسية: SessionPage للطلبات السريعة، وChromiumPage للتحكم بالمتصفح، وWebPage الذي يبدّل بين الوضعين مع مشاركة الكوكيز والحالة.

لماذا يهم DrissionPage مستخدمي البروكسيات؟

لأن DrissionPage يسمح بتعيين بروكسي مختلف لكل جلسة HTTP أو متصفح، ويتيح التبديل بين وضع HTTP الاقتصادي ووضع المتصفح عند الحاجة فقط. هذا يقلّل استهلاك البروكسيات السكنية المكلفة ويقلل من معدل الحجب، إذ تستخدم طلبات HTTP الخفيفة للمواقع البسيطة وتلجأ للمتصفح فقط عند ظهور JavaScript أو CAPTCHA.

أي نوع بروكسي يعمل بشكل أفضل مع DrissionPage؟

البروكسيات السكنية تعمل بشكل أفضل للمواقع الصعبة لأنها تستخدم عناوين IP حقيقية من مزودي إنترنت فعليين، مما يجعلها أقل عرضة للحجب. أما بروكسيات مراكز البيانات فهي أرخص وأسرع ومناسبة للمواقع التي لا تطبّق حماية صارمة. يُنصح بمزج النوعين: سكني للأهداف المحمية ومراكز بيانات للمهام البسيطة.

كيف تتجنب الحجب عند استخدام DrissionPage؟

استخدم بروكسيات سكنية مع تدوير IP لكل طلب، ثبّت جلسات لزجة عند الحاجة للحفاظ على الكوكيز، احترم ملف robots.txt وحدود المعدل، أضف تأخيراً عشوائياً بين الطلبات، وابدأ بوضع HTTP قبل الترقية للمتصفح. استخدم ميزة listen.start() لالتقاط طلبات XHR الخلفية وكشف واجهات API المخفية بدلاً من تحميل الصفحات كاملة.

هل يدعم DrissionPage بروتوكول SOCKS5؟

نعم، يدعم DrissionPage بروكسيات SOCKS5 عبر تعيينها في ChromiumOptions أو إعدادات SessionPage. يمكنك استخدام صيغة socks5://user:pass@gate.proxyhat.com:1080 مع ProxyHat للاتصال عبر SOCKS5، وهو مفيد للتطبيقات التي تتطلب هذا البروتوكول تحديداً.

Preguntas frecuentes

ما هو DrissionPage؟

DrissionPage هو إطار عمل Python مفتوح المصدر يوحّد بين طلبات HTTP بأسلوب requests وتحكم متصفح Chromium عبر بروتوكول CDP في أداة واحدة. يوفّر ثلاث صفحات رئيسية: SessionPage للطلبات السريعة، وChromiumPage للتحكم بالمتصفح، وWebPage الذي يبدّل بين الوضعين مع مشاركة الكوكيز والحالة.

لماذا يهم DrissionPage مستخدمي البروكسيات؟

لأن DrissionPage يسمح بتعيين بروكسي مختلف لكل جلسة HTTP أو متصفح، ويتيح التبديل بين وضع HTTP الاقتصادي ووضع المتصفح عند الحاجة فقط. هذا يقلّل استهلاك البروكسيات السكنية المكلفة ويقلل من معدل الحجب، إذ تستخدم طلبات HTTP الخفيفة للمواقع البسيطة وتلجأ للمتصفح فقط عند ظهور JavaScript أو CAPTCHA.

أي نوع بروكسي يعمل بشكل أفضل مع DrissionPage؟

البروكسيات السكنية تعمل بشكل أفضل للمواقع الصعبة لأنها تستخدم عناوين IP حقيقية من مزودي إنترنت فعليين، مما يجعلها أقل عرضة للحجب. أما بروكسيات مراكز البيانات فهي أرخص وأسرع ومناسبة للمواقع التي لا تطبّق حماية صارمة. يُنصح بمزج النوعين: سكني للأهداف المحمية ومراكز بيانات للمهام البسيطة.

كيف تتجنب الحجب عند استخدام DrissionPage؟

استخدم بروكسيات سكنية مع تدوير IP لكل طلب، ثبّت جلسات لزجة عند الحاجة للحفاظ على الكوكيز، احترم ملف robots.txt وحدود المعدل، أضف تأخيراً عشوائياً بين الطلبات، وابدأ بوضع HTTP قبل الترقية للمتصفح. استخدم ميزة listen.start() لالتقاط طلبات XHR الخلفية وكشف واجهات API المخفية بدلاً من تحميل الصفحات كاملة.

هل يدعم DrissionPage بروتوكول SOCKS5؟

نعم، يدعم DrissionPage بروكسيات SOCKS5 عبر تعيينها في ChromiumOptions أو إعدادات SessionPage. يمكنك استخدام صيغة socks5://user:pass@gate.proxyhat.com:1080 مع ProxyHat للاتصال عبر SOCKS5، وهو مفيد للتطبيقات التي تتطلب هذا البروتوكول تحديداً.

¿Listo para empezar?

Proxies residenciales, ISP y móviles en más de 148 países. Creá una cuenta gratis.

Crear cuenta gratis
← Volver al Blog