التكاملات

عزل ملفات تعريف المتصفح ودمجها مع CaptchaAI

عزل ملفات تعريف المتصفح يمنح كل جلسة اختبار بيئتها المستقلة، ودمجه مع CaptchaAI يعني أن حل reCAPTCHA يجري داخل نفس تلك الجلسة بدل أن يقفز إلى سياق منفصل. هذا هو الفرق الذي يجعل نتائج اختبار النماذج قابلة للتكرار عندما تدير فرق QA عدة حسابات مملوكة في وقت واحد.

أدوات مثل Multilogin وGoLogin وDolphin Anty تفتح لكل سيناريو ملف تعريف مستقلًا بإعداداته وملفات تعريف الارتباط الخاصة به. يبقى دور CaptchaAI ثابتًا في جميع هذه الأدوات: فهو لا يعتمد على المتصفح، ويكفيه مفتاح الموقع وعنوان الصفحة ليعيد الرمز المحلول داخل نفس الجلسة المصرّح باختبارها.

ما ستضبطه عمليًا في هذا الدليل:

  • تشغيل ملفات تعريف معزولة عبر Multilogin وGoLogin وDolphin Anty والتحكم بها من كود Python.
  • حقن الرمز المحلول من CaptchaAI داخل الجلسة نفسها التي فتحها كل ملف تعريف.
  • توزيع سيناريوهات QA المتوازية على عدد الـ threads المتاح في خطتك دون تجاوز حد المعدل.

لماذا يهم عزل ملفات تعريف المتصفح في بيئات الاختبار المصرّح بها

حين تختبر عدة حسابات مملوكة في وقت واحد، يمنع العزل تسرّب حالة جلسة إلى أخرى، فتبقى كل نتيجة منسوبة إلى سيناريوها وحده. الفرق الجوهري يظهر في ثلاثة محاور:

الجانب Chrome عادي ملف تعريف متصفح معزول
بصمة الجلسة مشتركة بين كل الجلسات مستقلة لكل ملف تعريف
ملفات تعريف الارتباط مشتركة افتراضيًا معزولة لكل ملف تعريف
تداخل الجلسات أثناء الاختبار مرتفع منخفض

كيف يجري حل CAPTCHA داخل كل ملف تعريف

يبقى دور CaptchaAI واحدًا مهما اختلفت أداة العزل، ويمكن تلخيص المسار في أربع خطوات متسلسلة:

  1. يفتح ملف التعريف المعزول الصفحة المملوكة، فتلتقط أداة الأتمتة مفتاح الموقع من عنصر [data-sitekey].
  2. يرسل الكود مفتاح الموقع وعنوان الصفحة إلى CaptchaAI عبر نقطة النهاية in.php ويستلم معرّف المهمة.
  3. يستطلع الكود نقطة res.php دوريًا حتى تكتمل المعالجة ويعود الرمز المحلول.
  4. يُحقن الرمز في حقل g-recaptcha-response داخل الجلسة نفسها، ثم يُرسل النموذج.

Multilogin + CaptchaAI

يدير Multilogin ملفات التعريف عبر واجهة محلية على المنفذ 35000، ويتصل Selenium بالملف المفتوح ليقود المتصفح مباشرة.

تشغيل ملف تعريف عبر واجهة API

تبدأ الأداة ملف التعريف عبر واجهتها المحلية، ثم يتصل Selenium بالمتصفح المفتوح عبر منفذ التصحيح. بعد ذلك يتولّى CaptchaAI حل reCAPTCHA داخل الجلسة نفسها قبل إرسال النموذج.

import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

MULTILOGIN_TOKEN = "your_multilogin_token"
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def start_multilogin_profile(profile_id):
    """Start a Multilogin browser profile and return WebDriver."""
    # Start profile via Multilogin API
    resp = requests.get(
        f"http://127.0.0.1:35000/api/v1/profile/start"
        f"?automation=true&profileId={profile_id}",
        headers={"Authorization": f"Bearer {MULTILOGIN_TOKEN}"},
    )

    data = resp.json()
    port = data["value"]

    # Connect Selenium to the running profile
    options = webdriver.ChromeOptions()
    options.debugger_address = f"127.0.0.1:{port}"

    driver = webdriver.Chrome(options=options)
    return driver


def solve_recaptcha(site_url, sitekey):
    """Solve via CaptchaAI API."""
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": site_url,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        resp = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        })
        data = resp.json()
        if data["request"] == "CAPCHA_NOT_READY":
            continue
        if data["status"] == 1:
            return data["request"]

    raise TimeoutError("Solve timeout")


def run_with_multilogin(profile_id, target_url):
    driver = start_multilogin_profile(profile_id)

    try:
        driver.get(target_url)
        time.sleep(3)

        # Detect sitekey
        sitekey = driver.execute_script(
            "return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
        )

        if sitekey:
            # Solve CAPTCHA
            token = solve_recaptcha(target_url, sitekey)

            # Inject token
            driver.execute_script(f"""
                document.querySelector('#g-recaptcha-response').value = '{token}';
                document.querySelectorAll('[name="g-recaptcha-response"]')
                    .forEach(el => {{ el.value = '{token}'; }});
            """)

            # Submit form
            driver.find_element(By.CSS_SELECTOR, "form").submit()
            time.sleep(3)

        return driver.page_source

    finally:
        driver.quit()


# Run across multiple profiles
profile_ids = [
    "profile-uuid-1",
    "profile-uuid-2",
    "profile-uuid-3",
]

for pid in profile_ids:
    result = run_with_multilogin(pid, "https://target-site.com/form")
    print(f"Profile {pid}: done")

GoLogin + CaptchaAI

يوفّر GoLogin واجهة سحابية لإدارة دورة حياة ملف التعريف كاملة: الإنشاء والتشغيل والإيقاف، وكلها قابلة للاستدعاء برمجيًا ضمن سير عمل الاختبار.

إنشاء ملفات التعريف وإدارتها

يتيح GoLogin إنشاء ملف التعريف وضبط إعداداته برمجيًا ثم تشغيله وإيقافه عبر واجهة API. الدالة التالية تنشئ ملفًا جديدًا، تشغّله، تحل اختبار reCAPTCHA، ثم توقفه في نهاية الدورة.

import requests
import time
import subprocess
from selenium import webdriver


GOLOGIN_TOKEN = "your_gologin_token"
GOLOGIN_API = "https://api.gologin.com/browser"
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def create_gologin_profile():
    """Create a new GoLogin profile with controlled browser settings."""
    resp = requests.post(
        GOLOGIN_API,
        headers={"Authorization": f"Bearer {GOLOGIN_TOKEN}"},
        json={
            "name": f"captcha-profile-{int(time.time())}",
            "os": "win",
            "navigator": {
                "userAgent": "random",
                "resolution": "1920x1080",
                "language": "en-US",
            },
            "proxy": {
                "mode": "none",
            },
        },
    )
    return resp.json()["id"]


def start_gologin_profile(profile_id):
    """Start GoLogin profile and connect WebDriver."""
    resp = requests.get(
        f"{GOLOGIN_API}/{profile_id}/start",
        headers={"Authorization": f"Bearer {GOLOGIN_TOKEN}"},
    )

    data = resp.json()
    debug_port = data.get("debugPort", 0)
    ws_url = data.get("wsUrl", "")

    options = webdriver.ChromeOptions()
    options.debugger_address = f"127.0.0.1:{debug_port}"

    driver = webdriver.Chrome(options=options)
    return driver


def stop_gologin_profile(profile_id):
    requests.get(
        f"{GOLOGIN_API}/{profile_id}/stop",
        headers={"Authorization": f"Bearer {GOLOGIN_TOKEN}"},
    )


def solve_and_submit(driver, url):
    """Navigate, solve CAPTCHA, submit form."""
    driver.get(url)
    time.sleep(3)

    sitekey = driver.execute_script(
        "return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
    )

    if not sitekey:
        return {"status": "no_captcha"}

    # Solve via CaptchaAI
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": url,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        resp = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = resp.json()
        if data["request"] != "CAPCHA_NOT_READY":
            break

    token = data["request"]

    driver.execute_script(f"""
        document.querySelector('#g-recaptcha-response').value = '{token}';
    """)

    return {"status": "solved", "token": token[:30] + "..."}


# Full pipeline
profile_id = create_gologin_profile()
driver = start_gologin_profile(profile_id)

try:
    result = solve_and_submit(driver, "https://target-site.com/register")
    print(result)
finally:
    driver.quit()
    stop_gologin_profile(profile_id)

Dolphin Anty + CaptchaAI

يعمل Dolphin Anty بالنمط نفسه: تشغّل ملف التعريف عبر واجهته المحلية على المنفذ 3001، فتحصل على منفذ الأتمتة الذي يتصل به Selenium، ويبقى استدعاء CaptchaAI مطابقًا لما سبق.

import requests
import time
from selenium import webdriver

DOLPHIN_API = "http://localhost:3001/v1.0"
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def start_dolphin_profile(profile_id):
    """Start a Dolphin Anty profile."""
    resp = requests.get(
        f"{DOLPHIN_API}/browser_profiles/{profile_id}/start"
        f"?automation=1"
    )
    data = resp.json()

    port = data["automation"]["port"]
    options = webdriver.ChromeOptions()
    options.debugger_address = f"127.0.0.1:{port}"

    return webdriver.Chrome(options=options)


def stop_dolphin_profile(profile_id):
    requests.get(f"{DOLPHIN_API}/browser_profiles/{profile_id}/stop")


def captcha_workflow(driver, url, captchaai_key):
    driver.get(url)
    time.sleep(3)

    sitekey = driver.execute_script(
        "return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
    )
    if not sitekey:
        return None

    # Submit to CaptchaAI
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": captchaai_key,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": url,
        "json": 1,
    })
    task_id = resp.json()["request"]

    # Poll
    for _ in range(60):
        time.sleep(5)
        resp = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": captchaai_key, "action": "get",
            "id": task_id, "json": 1,
        })
        data = resp.json()
        if data["request"] != "CAPCHA_NOT_READY":
            break

    token = data["request"]
    driver.execute_script(f"""
        document.querySelector('#g-recaptcha-response').value = '{token}';
    """)
    return token

تشغيل عدة سيناريوهات QA بالتوازي

عند تشغيل عدة ملفات تعريف في اللحظة نفسها، تضبط عدد العمال المتزامنين عبر ThreadPoolExecutor بما يوازي عدد الـ threads في خطتك. الكود التالي يوزّع السيناريوهات على مجموعة من العمال ويجمع النتائج فور اكتمالها.

from concurrent.futures import ThreadPoolExecutor, as_completed


def process_profile(profile_config):
    """Run a task on one privacy-focused browser profile."""
    browser = profile_config["browser"]  # "multilogin", "gologin", "dolphin"
    profile_id = profile_config["profile_id"]
    url = profile_config["url"]

    driver = None
    try:
        if browser == "multilogin":
            driver = start_multilogin_profile(profile_id)
        elif browser == "gologin":
            driver = start_gologin_profile(profile_id)
        elif browser == "dolphin":
            driver = start_dolphin_profile(profile_id)

        result = solve_and_submit(driver, url)
        return {"profile": profile_id, **result}

    except Exception as e:
        return {"profile": profile_id, "status": "error", "error": str(e)}

    finally:
        if driver:
            driver.quit()
        if browser == "gologin":
            stop_gologin_profile(profile_id)
        elif browser == "dolphin":
            stop_dolphin_profile(profile_id)


# Run 3 QA profiles in parallel
profiles = [
    {"browser": "gologin", "profile_id": f"profile-{i}", "url": "https://target.com/form"}
    for i in range(3)
]

with ThreadPoolExecutor(max_workers=5) as executor:
    futures = {executor.submit(process_profile, p): p for p in profiles}

    for future in as_completed(futures):
        result = future.result()
        print(f"[{result['status']}] Profile: {result['profile']}")

مثال عملي: مطابقة الملفات المتوازية مع خطة CaptchaAI

عندما تشغّل عدة ملفات تعريف بالتوازي، وكل ملف يحل اختبار CAPTCHA في اللحظة نفسها، فأنت تحتاج إلى عدد مماثل من الـ threads المتزامنة لدى CaptchaAI. الفوترة هنا تعتمد على عدد الـ threads المتزامنة لا على عدد عمليات الحل، وكل خطة تشمل عددًا غير محدود من عمليات الحل خلال الشهر.

تخيّل فريق QA في متجر إلكتروني إقليمي يختبر نموذج التسجيل عبر خمسة حسابات تاجر مملوكة في وقت واحد: خطة BASIC ($15/شهر، 5 threads) تكفي لهذه البداية. وعند التوسع إلى نحو 50 سيناريو متوازٍ ضمن دورة اختبار أكبر، تصبح خطة ADVANCE ($90/شهر، 50 thread) هي الأنسب. اضبط عدد max_workers في الكود بما يتوافق مع عدد الـ threads المتاح في خطتك حتى لا تصطدم الطلبات بحد المعدل.

خلاصة المطابقة بين حجم الاختبار والخطة:

  • خمسة ملفات تعريف متوازية → خطة BASIC بسعر $15/شهر مع 5 threads.
  • نحو خمسين سيناريو متوازيًا → خطة ADVANCE بسعر $90/شهر مع 50 thread.

أفضل الممارسات

ثبّت إعداداتك على ملف تعريف واحد أولًا، ثم كرّر النمط نفسه على بقية الملفات لضمان اتساق النتائج.

القواعد التالية تحافظ على استقلال كل جلسة اختبار وتجعل النتائج قابلة للتكرار عبر عمليات التشغيل المختلفة:

  • خصّص ملف تعريف واحد لكل سيناريو QA حتى تمنع تداخل جلسات الاختبار.
  • افصل الشبكة حسب السيناريو عند الحاجة للحفاظ على اتساق السجلات بين البيئات.
  • حمّل صفحة مملوكة للتحقق من الصحة أولًا لتتأكد أن التطبيق يستجيب قبل اختبار النموذج.
  • اترك مهلة تهيئة قصيرة قبل الإرسال حتى لا يختلط بطء التحميل بفشل CAPTCHA.
  • نظّف ملفات تعريف الارتباط بين عمليات التشغيل لتسهّل إعادة إنتاج المشكلة بدقة.

استكشاف الأخطاء وإصلاحها

جميع الأمثلة تفترض بيئة اختبار مملوكة ومصرّحًا باختبارها؛ اضبط الإعدادات على تطبيقك قبل التشغيل.

معظم المشكلات في هذا المسار مصدرها إعداد الجلسة أو المنافذ لا خدمة الحل نفسها. الجدول التالي يربط كل عرض بالسبب الأرجح والإجراء المناسب:

المشكلة السبب المحتمل الإجراء
ملف التعريف لا يبدأ تعارض في المنفذ تأكد من عدم استخدام ملف تعريف آخر للمنفذ نفسه
WebDriver يتعذّر عليه الاتصال منفذ تصحيح غير صحيح راجع استجابة الـ API للحصول على المنفذ الصحيح
اختبار CAPTCHA ما زال يظهر عدم اتساق إعداد الجلسة طابق إعدادات الجلسة واللغة والمنطقة الزمنية مع بيئة الاختبار
رفض الرمز المحلول لم تكتمل عناصر الصفحة أو انتهت صلاحية الجلسة تحقّق من زمن التحميل وسلامة الجلسة قبل الإرسال
بطء إنشاء ملف التعريف تجاوز حد معدل الـ API أضف تأخيرات بين طلبات إنشاء الملفات

عند رفض الرمز المحلول تحديدًا، جرّب هذا الترتيب:

  1. تأكد أن عنصر #g-recaptcha-response موجود في الصفحة قبل حقن الرمز.
  2. اترك مهلة تهيئة قصيرة حتى تكتمل عناصر النموذج ثم أعد الإرسال.
  3. أعد فتح الجلسة إن انتهت صلاحيتها، ثم أعد المحاولة بمفتاح الموقع نفسه.

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

هل يحل CaptchaAI كل أنواع CAPTCHA التي قد أواجهها داخل هذه المتصفحات؟

يحل CaptchaAI عائلة reCAPTCHA v2 وv3 وCloudflare Turnstile وCloudflare Challenge وGeeTest v3 وتحديات الصور والـ OCR، وهي الأنواع الأكثر شيوعًا في نماذج التسجيل والدخول. أما hCaptcha وFunCaptcha (Arkose Labs) فغير مدعومين حاليًا، لذا خطّط لسيناريوهات الاختبار على أساس الأنواع المدعومة فعلًا.

كيف أختار خطة CaptchaAI المناسبة لعدد الملفات المتوازية؟

اربط عدد الملفات التي تعمل في اللحظة نفسها بعدد الـ threads المتزامنة في الخطة. خمسة ملفات متوازية تناسبها BASIC ($15/شهر، 5 threads)، وخمسون سيناريو متوازيًا تناسبها ADVANCE ($90/شهر، 50 thread)، مع عدد غير محدود من عمليات الحل شهريًا في كل خطة.

هل يمكنني إعادة استخدام ملف التعريف نفسه عبر عدة جلسات اختبار؟

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

الرمز المحلول مرفوض داخل ملف تعريف معزول، ما السبب؟

غالبًا لم تكتمل عناصر الصفحة قبل الإرسال أو انتهت صلاحية الجلسة. تأكد من أن #g-recaptcha-response موجود في الصفحة، واترك مهلة تهيئة قصيرة قبل حقن الرمز وإرسال النموذج.


أدلة ذات صلة


ثبّت أولًا إعدادات الجلسة وسجلات المتصفح داخل بيئتك المملوكة، ثم أدخل CaptchaAI في المسار نفسه وضمن السيناريو نفسه لتحصل على نتائج اختبار قابلة للتكرار.

التعليقات غير مفعّلة لهذا المقال.