المقارنات

Headless vs Headed Chrome لحل اختبار CAPTCHA

خلاصة القرار أولاً: وضع المتصفح لا يغيّر قدرة CaptchaAI على الحل، لأن الحل يجري من جانب الخادم اعتماداً على مفتاح الموقع وعنوان الصفحة. ما يتغيّر بتغيّر الوضع شيئان فقط: كم مرة يظهر اختبار CAPTCHA أصلاً، ودرجة reCAPTCHA v3 التي يحصل عليها متصفحك.

لذلك السؤال العملي ليس "أي وضع أسرع"، بل "أي وضع يقلّل احتكاكك مع أنظمة الكشف مقابل تكلفة الذاكرة". نجيب عنه بجدول قرار، ثم نشرح آلية كشف headless مع كود جاهز للوضعين.


مقارنة سريعة: headless مقابل headed

العامل Chrome headless Chrome headed
السرعة سريع أبطأ (يعرض الواجهة)
الذاكرة ~100-200 ميجابايت ~300-500 ميجابايت
النشر على الخادم مباشر يحتاج شاشة افتراضية
كشف CAPTCHA مرتفع منخفض (يشبه مستخدماً حقيقياً)
درجة reCAPTCHA v3 0.1-0.3 0.7-0.9
تتبّع الأخطاء أصعب أسهل (ترى الصفحة)
التوسّع ممتاز مكلف في الموارد

متى تختار كل وضع؟

ابدأ من احتياجك لا من التفاصيل التقنية:

اختر headless عندما

  • تشغّل على خوادم أو CI بلا شاشة.
  • توسّع إلى أكثر من 50 جلسة.
  • الذاكرة محدودة والتكلفة حسّاسة.
  • تعتمد على CaptchaAI في الحل، فوضع المتصفح لا يعنيه.

اختر headed عندما

  • تتتبّع مسار اختبار CAPTCHA بصرياً أثناء التطوير.
  • تهمّك درجات reCAPTCHA v3، فهي أعلى في headed.
  • الموقع المستهدف يحجب headless تحديداً.
  • تعمل على جهاز فيه شاشة فعلية أصلاً.

اختر headed مع شاشة افتراضية (Xvfb) عندما

  • تحتاج مقاومة كشف بمستوى headed على خادم بلا شاشة.
  • يعطيك reCAPTCHA v3 درجات منخفضة في headless.
  • تسمح الميزانية بضِعف الذاكرة لكل جلسة تقريباً.

مثال من أرض الواقع: فريق في دبي يشغّل 40 جلسة headless لمراقبة الأسعار على خادم سحابي. عدد الجلسات لا يمسّ معدل الحل لأن CaptchaAI يحلّ من جانب الخادم؛ سقف التزامن تحدّده خطة الـ threads — مثلاً ADVANCE بسعر 90 دولاراً شهرياً تمنحك 50 thread وحلولاً غير محدودة لكل thread.


كيف تكتشف أنظمة CAPTCHA وضع headless في Chrome

أنظمة الحماية لا تسأل المتصفح "هل أنت headless؟"، بل تجمع إشارات صغيرة يفضحها الوضع تلقائياً.

إشارات الكشف الأساسية

// Tests that CAPTCHA systems run

// 1. WebDriver flag (biggest tell)
navigator.webdriver  // true in headless, undefined in real browser

// 2. Chrome object completeness
window.chrome        // Missing or incomplete in headless

// 3. Plugins
navigator.plugins.length  // 0 in headless, 3+ in headed

// 4. WebGL renderer
// Headless: "SwiftShader Renderer"
// Headed:   "ANGLE (NVIDIA GeForce GTX 1080...)"

// 5. User-Agent contains "Headless"
navigator.userAgent.includes("Headless")  // Old Chrome versions

// 6. Screen dimensions
screen.width === 0   // Some headless configs

// 7. Notification permission
Notification.permission  // "denied" in headless without override

نتائج اختبار الإشارات

الجدول التالي يوضّح اختلاف قيم هذه الإشارات بين الأوضاع:

Signal               Headed    Headless   New Headless (v112+)
─────────────────────────────────────────────────────────────
webdriver            false     true       true
chrome object        full      partial    improved
plugins              5         0          0
WebGL renderer       ANGLE     Swift      Swift
screen.width         1920      800        800
UA "HeadlessChrome"  no        yes        no (removed)

وضع "headless الجديد" في Chrome 112 وما بعده

أضاف Chrome منذ الإصدار 112 الوسيط --headless=new الذي يشغّل نفس قاعدة كود وضع headed بدل محرّك مبسّط منفصل:

from selenium import webdriver

# Old headless (more detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless")  # Legacy mode

# New headless (less detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")  # Shares headed rendering

driver = webdriver.Chrome(options=options)

الوضع الجديد يعالج بعض متجهات الكشف مثل بصمة WebGL والـ User-Agent، لكنه يكشف navigator.webdriver ويأتي بلا مكوّنات إضافية؛ فهو تحسين لا تخفٍّ كامل.

حل الكابتشا في وضع headless مع CaptchaAI (Python)

لأن CaptchaAI يحلّ من جانب الخادم، لا يغيّر وضع headless شيئاً في واجهة الحل: ترسل مفتاح الموقع وعنوان الصفحة وتستقبل الرمز الجاهز:

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

API_KEY = "YOUR_API_KEY"
API_URL = "https://ocr.captchaai.com"


def create_headless_driver():
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("--window-size=1920,1080")
    options.add_argument(
        "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
    )
    return webdriver.Chrome(options=options)


def solve_captcha(site_url, sitekey):
    resp = requests.post(f"{API_URL}/in.php", data={
        "key": API_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"{API_URL}/res.php", params={
            "key": API_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = resp.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("Solve timeout")


# Full headless workflow
driver = create_headless_driver()

try:
    driver.get("https://example.com/form")
    time.sleep(2)

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

    if sitekey:
        token = solve_captcha(driver.current_url, sitekey)
        driver.execute_script(f"""
            document.querySelector('#g-recaptcha-response').value = '{token}';
        """)
        driver.find_element(By.CSS_SELECTOR, "form").submit()

finally:
    driver.quit()

حقل الرمز هنا g-recaptcha-response لأننا نتعامل مع reCAPTCHA، ونقطتا in.php وres.php ثابتتان مهما كان الوضع.

تشغيل headed على الخوادم عبر شاشة افتراضية

إن احتجت مقاومة كشف بمستوى headed على خادم بلا شاشة، شغّل Chrome headed داخل شاشة افتراضية عبر Xvfb — عرض رسومي حقيقي دون شاشة فيزيائية.

Linux مع Xvfb

# Install
sudo apt-get install xvfb

# Run with virtual display
xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" python script.py

Python مع PyVirtualDisplay

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(1920, 1080))
display.start()

options = webdriver.ChromeOptions()
# No --headless flag = headed mode in virtual display
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome(options=options)
# Now runs headed Chrome with real rendering, but no physical display

Docker مع Xvfb

الطريقة نفسها داخل Docker: ثبّت Xvfb وشغّل السكربت عبر xvfb-run:

FROM python:3.12-slim

RUN apt-get update && apt-get install -y \
    xvfb \
    chromium \
    chromium-driver \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . /app
WORKDIR /app

CMD ["xvfb-run", "--auto-servernum", "python", "main.py"]

تصحيحات التخفّي في وضع headless (Node.js)

للبقاء في headless مع تقليل إشارات الكشف، استعن بإضافة التخفّي في Puppeteer وبعض التصحيحات اليدوية على navigator:

const puppeteer = require("puppeteer-extra");
const StealthPlugin = require("puppeteer-extra-plugin-stealth");

puppeteer.use(StealthPlugin());

async function headlessStealth() {
  const browser = await puppeteer.launch({
    headless: "new",
    args: [
      "--no-sandbox",
      "--window-size=1920,1080",
      "--disable-blink-features=AutomationControlled",
    ],
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });

  // Additional stealth patches
  await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, "webdriver", {
      get: () => undefined,
    });

    Object.defineProperty(navigator, "plugins", {
      get: () => [1, 2, 3, 4, 5],
    });
  });

  await page.goto("https://example.com/form");

  // Detect and solve CAPTCHA with CaptchaAI
  const sitekey = await page.evaluate(() =>
    document.querySelector("[data-sitekey]")?.getAttribute("data-sitekey")
  );

  if (sitekey) {
    // Call CaptchaAI API (see other guides for full implementation)
    const token = await solveCaptchaAI(page.url(), sitekey);

    await page.evaluate((t) => {
      document.querySelector("#g-recaptcha-response").value = t;
    }, token);
  }

  await browser.close();
}

مقارنة الأداء بالأرقام

الأرقام التالية تستند إلى بيانات مرصودة وتقارير مستخدمين. قد تختلف النتائج بحسب بيئة التشغيل والحجم والتوقيت.

السيناريو headless headed headed + Xvfb
زمن الإقلاع ~1 ثانية ~2 ثانية ~2.5 ثانية
الذاكرة لكل تبويب 100-200 ميجابايت 300-500 ميجابايت 300-500 ميجابايت
تحميل الصفحة (متوسط) 1.5 ثانية 2.5 ثانية 2.5 ثانية
درجة reCAPTCHA v3 0.1-0.3 0.7-0.9 0.5-0.8
أقصى تزامن (8 جيجابايت) 30-40 10-15 10-15
معدل حل CAPTCHA نفسه (API) نفسه (API) نفسه (API)

الخلاصة: الوضع يغيّر تكرار الاختبار ودرجات reCAPTCHA v3 فقط، لا معدل الحل نفسه.

معالجة المشكلات الشائعة

المشكلة السبب الحل
كُشف وضع headless راية navigator.webdriver استخدم إضافة التخفّي أو تصحيحات CDP
درجات v3 منخفضة في headless غياب إشارات العرض الرسومي انتقل إلى headed + Xvfb
تعطّل Xvfb تعارض في رقم الشاشة استخدم --auto-servernum
ذاكرة مرتفعة في headed عملية الـ GPU أضف الوسيط --disable-gpu
لقطات شاشة فارغة في headless منفذ عرض غير صحيح اضبط --window-size=1920,1080

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

هل ينخفض معدل حل CaptchaAI في وضع headless مقارنةً بـ headed؟

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

كم جلسة Chrome متزامنة يتحمّلها خادم بذاكرة 8 جيجابايت؟

في headless غالباً 30-40 جلسة، وفي headed أو headed مع Xvfb نحو 10-15 فقط لأن كل جلسة تستهلك ضعف الذاكرة. للتوسّع العالي يبقى headless الأكفأ.

هل يكفي وضع --headless=new لتفادي أنظمة كشف الروبوتات؟

هو أفضل من headless القديم لكنه يبقى قابلاً للكشف؛ المواقع التي تفحص navigator.webdriver أو عدد المكوّنات الإضافية ستضع عليه علامة، لذا ادمجه مع تصحيحات تخفّي عند الحاجة.

هل يعمل الحل داخل حاوية Docker بلا شاشة عرض؟

نعم. في headless يعمل مباشرة، وإن أردت headed داخل الحاوية فثبّت Xvfb وشغّل السكربت عبر xvfb-run كما في مثال Docker أعلاه.

متى أختار headed + Xvfb بدلاً من headless مباشرةً؟

حين تحتاج مقاومة كشف بمستوى headed على خادم بلا شاشة، أو حين يعطيك reCAPTCHA v3 درجات منخفضة في headless. المقابل ذاكرة أعلى وتزامن أقل، فوازن بينهما.


أدلة ذات صلة


اختر وضع المتصفح المناسب لسير عملك — احصل على مفتاح CaptchaAI وحلّ اختبارات CAPTCHA بأي تكوين تشغّله.

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