تستخدم بعض المواقع reCAPTCHA في صفحة تسجيل الدخول الخاصة بها وTurnstile في صفحة الخروج الخاصة بها. اختبار A/B الآخر بين مقدمي الخدمة - يعرض عنوان URL نفسه reCAPTCHA لزائر واحد وTurnstile لآخر. إن الترميز الثابت لطريقة حل واحدة يعني أن الأتمتة الخاصة بك تنقطع عندما تواجه النوع الآخر.
لماذا تستخدم المواقع موفري CAPTCHA متعددين
السيناريو
كيف يظهر
صفحات مختلفة ومقدمو خدمات مختلفون
تسجيل الدخول = reCAPTCHA، الخروج = Turnstile
موفرو اختبار A/B
تعرض الصفحة نفسها عشوائيًا أيًا من النوعين
الهجرة قيد التقدم
تحتوي الصفحات القديمة على reCAPTCHA، بينما تحتوي الصفحات الجديدة على Turnstile
التراجع عن الفشل
فشل الموفر الأساسي في عودة → إلى الموفر الثانوي
الاختلاف الإقليمي
reCAPTCHA لزوار الولايات المتحدة، Turnstile للاتحاد الأوروبي (GDPR)
بايثون: الكشف التلقائي والحل
import requests
import time
import re
from dataclasses import dataclass
API_KEY = "YOUR_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"
@dataclass
class CaptchaInfo:
provider: str # "recaptcha" or "turnstile"
method: str # API method name
sitekey: str
pageurl: str
response_field: str # Form field name for the token
def detect_captcha_type(html, pageurl):
"""
Detect which CAPTCHA provider is on the page.
Returns CaptchaInfo or None.
"""
# Check for Turnstile
turnstile_match = re.search(
r'class=["\'][^"\']*cf-turnstile[^"\']*["\'][^>]*data-sitekey=["\']([^"\']+)["\']',
html,
)
if not turnstile_match:
turnstile_match = re.search(
r'data-sitekey=["\']([^"\']+)["\'][^>]*class=["\'][^"\']*cf-turnstile',
html,
)
if turnstile_match:
return CaptchaInfo(
provider="turnstile",
method="turnstile",
sitekey=turnstile_match.group(1),
pageurl=pageurl,
response_field="cf-turnstile-response",
)
# Check for reCAPTCHA
recaptcha_match = re.search(
r'class=["\'][^"\']*g-recaptcha[^"\']*["\'][^>]*data-sitekey=["\']([^"\']+)["\']',
html,
)
if not recaptcha_match:
recaptcha_match = re.search(
r'data-sitekey=["\']([^"\']+)["\'][^>]*class=["\'][^"\']*g-recaptcha',
html,
)
# Also check for script-rendered reCAPTCHA
if not recaptcha_match:
recaptcha_match = re.search(
r'grecaptcha\.render\([^,]+,\s*\{[^}]*["\']sitekey["\']\s*:\s*["\']([^"\']+)["\']',
html,
)
if recaptcha_match:
return CaptchaInfo(
provider="recaptcha",
method="userrecaptcha",
sitekey=recaptcha_match.group(1),
pageurl=pageurl,
response_field="g-recaptcha-response",
)
return None
def solve_captcha(info):
"""Solve any detected CAPTCHA type via CaptchaAI."""
params = {
"key": API_KEY,
"method": info.method,
"json": 1,
}
if info.method == "userrecaptcha":
params["googlekey"] = info.sitekey
params["pageurl"] = info.pageurl
elif info.method == "turnstile":
params["sitekey"] = info.sitekey
params["pageurl"] = info.pageurl
resp = requests.post(SUBMIT_URL, data=params, timeout=30).json()
if resp.get("status") != 1:
raise RuntimeError(f"Submit failed: {resp.get('request')}")
task_id = resp["request"]
for _ in range(60):
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get",
"id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
return poll["request"]
raise RuntimeError(f"Solve failed: {poll.get('request')}")
raise RuntimeError("Timeout")
def process_page(session, url):
"""Fetch page, detect CAPTCHA type, solve, and return form-ready data."""
response = session.get(url)
captcha_info = detect_captcha_type(response.text, url)
if not captcha_info:
print(f"No CAPTCHA detected on {url}")
return None
print(f"Detected {captcha_info.provider} on {url}")
print(f" Sitekey: {captcha_info.sitekey[:30]}...")
token = solve_captcha(captcha_info)
print(f" Solved: {token[:30]}...")
return {
"provider": captcha_info.provider,
"response_field": captcha_info.response_field,
"token": token,
}
# Usage: Handle multiple pages with different providers
session = requests.Session()
pages = [
"https://example.com/login", # Might have reCAPTCHA
"https://example.com/checkout", # Might have Turnstile
]
for url in pages:
result = process_page(session, url)
if result:
form_data = {result["response_field"]: result["token"]}
# Add other form fields...
# session.post(url, data=form_data)
JavaScript: كشف CAPTCHA الديناميكي
const API_KEY = "YOUR_API_KEY";
const SUBMIT_URL = "https://ocr.captchaai.com/in.php";
const RESULT_URL = "https://ocr.captchaai.com/res.php";
function detectCaptchaType(html, pageurl) {
// Turnstile
const turnstileMatch = html.match(/cf-turnstile[^>]*data-sitekey=["']([^"']+)["']/);
if (turnstileMatch) {
return { provider: "turnstile", method: "turnstile", sitekey: turnstileMatch[1], pageurl, field: "cf-turnstile-response" };
}
// reCAPTCHA
const recaptchaMatch = html.match(/g-recaptcha[^>]*data-sitekey=["']([^"']+)["']/);
if (recaptchaMatch) {
return { provider: "recaptcha", method: "userrecaptcha", sitekey: recaptchaMatch[1], pageurl, field: "g-recaptcha-response" };
}
// Script-rendered reCAPTCHA
const scriptMatch = html.match(/sitekey["']\s*:\s*["']([^"']+)["']/);
if (scriptMatch) {
return { provider: "recaptcha", method: "userrecaptcha", sitekey: scriptMatch[1], pageurl, field: "g-recaptcha-response" };
}
return null;
}
async function solveCaptcha(info) {
const body = new URLSearchParams({ key: API_KEY, method: info.method, json: "1" });
if (info.method === "userrecaptcha") { body.set("googlekey", info.sitekey); body.set("pageurl", info.pageurl); }
else if (info.method === "turnstile") { body.set("sitekey", info.sitekey); body.set("pageurl", info.pageurl); }
const resp = await (await fetch(SUBMIT_URL, { method: "POST", body })).json();
if (resp.status !== 1) throw new Error(`Submit: ${resp.request}`);
const taskId = resp.request;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const url = `${RESULT_URL}?key=${API_KEY}&action=get&id=${taskId}&json=1`;
const poll = await (await fetch(url)).json();
if (poll.request === "CAPCHA_NOT_READY") continue;
if (poll.status === 1) return poll.request;
throw new Error(`Solve: ${poll.request}`);
}
throw new Error("Timeout");
}
async function processPage(url) {
const response = await fetch(url);
const html = await response.text();
const info = detectCaptchaType(html, url);
if (!info) { console.log(`No CAPTCHA on ${url}`); return null; }
console.log(`${info.provider} detected on ${url}`);
const token = await solveCaptcha(info);
return { provider: info.provider, field: info.field, token };
}
// Usage
const pages = ["https://example.com/login", "https://example.com/checkout"];
for (const url of pages) {
const result = await processPage(url);
if (result) {
console.log(`Solved ${result.provider}: ${result.token.substring(0, 30)}...`);
}
}
مرجع الكشف عن الموفر
مزود
علامة HTML
عنوان URL للبرنامج النصي
مجال الاستجابة
reCAPTCHA v2
class="g-recaptcha"
google.com/recaptcha/api.js
g-recaptcha-response
Cloudflare Turnstile
class="cf-turnstile"
challenges.cloudflare.com/turnstile
cf-turnstile-response
hCaptcha
class="h-captcha"
js.hcaptcha.com/1/api.js
h-captcha-response
استكشاف الأخطاء وإصلاحها
المشكلة
السبب
الإجراء
النتيجة لا تطابق الحالة الفعلية
نوع CAPTCHA أو المعلمات لم تُطابَق مع الهدف الصحيح
قارن الهدف وطريقة الحل والمعلمات المطلوبة مرة أخرى
الاختبار ينجح لكن بيئة الإنتاج تفشل
الجلسة أو الرؤوس أو سياق الوكيل يختلف عن الاختبار
أعد استخدام الشروط التي نجحت في الاختبار داخل سير العمل الفعلي كلما أمكن
المشكلة ما تزال غير واضحة
السجلات لا تتضمن سياقًا كافيًا لتشخيص موثوق
سجّل نوع الحل وزمن الاستجابة ورمز الخطأ والأثر اللاحق معًا
يشرح هذا الدليل كيفية دمج عزل ملفات تعريف المتصفح مع Captcha AI في بيئات الاختبار والأتمتة المصرّح بها: فصل الجلسات، والحفاظ على ملفات تعريف الارتباط، وحل re CA...
يشرح هذا الدليل كيفية دمج عزل ملفات تعريف المتصفح مع Captcha AI في بيئات الاختبار والأتمتة المصرّح بها: فصل ال...
Apr 27, 2026
الدروس التطبيقية
تعلّم بناء مسار موحّد يستقبل طلبات الحل من عدة عملاء ويرسلها إلى Captcha AI ويعيد الرموز المحلولة، مع إدارة قائمة الانتظار والتزامن في Python وNode.js.
تعلّم بناء مسار موحّد يستقبل طلبات الحل من عدة عملاء ويرسلها إلى Captcha AI ويعيد الرموز المحلولة، مع إدارة قا...
Apr 30, 2026
المرجع
احفظ جلسة المتصفح وملفات تعريف الارتباط بين عمليات التشغيل لتقليل تكرار اختبارات CAPTCHA في سير عمل الأتمتة واختبارات QA، مع أمثلة بلغتي Python وJava Script.
أعد استخدام رموز CAPTCHA بأمان: تعرّف على مدة صلاحية كل نوع، ومتى ينجح التخزين المؤقت، وكيف تُبطل الرموز المنت...
Apr 30, 2026
الدروس التطبيقية
كشف CAPTCHA داخل النوافذ المنبثقة وحقن الرمز في الموضع الصحيح: مراقبة DOM، ضبط التوقيت، واستخراج مفتاح الموقع الديناميكي مع Captcha AI في Python وPuppeteer.
كشف CAPTCHA داخل النوافذ المنبثقة وحقن الرمز في الموضع الصحيح: مراقبة DOM، ضبط التوقيت، واستخراج مفتاح الموقع...
May 04, 2026
حالات الاستخدام
دليل هندسي لاختبار تدفق الدفع عالي الطلب في متجرك المملوك: تحقق من ظهور CAPTCHA وحقن الرمز وثبات الجلسة على بيئة staging مع Captcha AI بخطوات قابلة للتكرار.