خلاصة القرار أولاً: وضع المتصفح لا يغيّر قدرة 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. المقابل ذاكرة أعلى وتزامن أقل، فوازن بينهما.
أدلة ذات صلة
- أتمتة اختبار CAPTCHA منخفض المستوى عبر Chrome DevTools Protocol
- ابدأ مع CaptchaAI وحلّ أول اختبار CAPTCHA خلال دقائق
اختر وضع المتصفح المناسب لسير عملك — احصل على مفتاح CaptchaAI وحلّ اختبارات CAPTCHA بأي تكوين تشغّله.