تطبق بعض مواقع الويب كلاً من reCAPTCHA v2 وv3 على نفس الصفحة. النمط النموذجي هو: يعمل الإصدار 3 بشكل غير مرئي في الخلفية، وإذا كانت النتيجة منخفضة جدًا، يظهر الإصدار 2 كتحدي احتياطي مرئي. يؤدي هذا التنفيذ المزدوج إلى حدوث ارتباك في التشغيل الآلي لأنك تحتاج إلى التعامل مع نوعين مختلفين من اختبار CAPTCHA بطرق حل مختلفة. يغطي هذا الدليل اكتشاف الاستراتيجيات وحلها وحالات الحافة المشتركة.
لماذا تستخدم المواقع الإصدارين v2 وv3 معًا
User visits page
↓
reCAPTCHA v3 runs invisibly in background
↓
Score returned to server (e.g., 0.4)
↓
Score below threshold (e.g., < 0.7)?
├─ YES → Show reCAPTCHA v2 checkbox/image challenge
└─ NO → Allow action without visible CAPTCHA
يوفر هذا النمط أفضل ما في العالمين:
- معظم المستخدمين (درجة الإصدار 3 العالية) لا يرون أي احتكاك منخفض في اختبار CAPTCHA →
- المستخدمون المشبوهون (درجة v3 منخفضة) يشاهدون تحدي v2 للإجراء الاحتياطي →
- يتحكم مشغل موقع الويب في الحد الفاصل بين غير المرئي والمرئي
أنماط التنفيذ المزدوجة
النمط 1: التقييم المسبق للإصدار 3 + الإصدار الثاني الاحتياطي
النمط الأكثر شيوعا. يتم تشغيل الإصدار 3 أولاً، ويظهر الإصدار 2 فقط إذا لزم الأمر.
<!-- Both scripts loaded -->
<script src="https://www.google.com/recaptcha/api.js?render=V3_SITE_KEY"></script>
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>
<form id="loginForm">
<!-- v2 widget (hidden initially) -->
<div id="recaptcha-v2-container" style="display:none;">
<div class="g-recaptcha" data-sitekey="V2_SITE_KEY"></div>
</div>
<button type="submit">Login</button>
</form>
<script>
// First attempt: v3 invisible
grecaptcha.ready(function() {
grecaptcha.execute('V3_SITE_KEY', {action: 'login'}).then(function(v3Token) {
fetch('/api/verify-v3', {
method: 'POST',
body: JSON.stringify({token: v3Token})
})
.then(r => r.json())
.then(data => {
if (data.score < 0.7) {
// Score too low → show v2 fallback
document.getElementById('recaptcha-v2-container').style.display = 'block';
grecaptcha.render('recaptcha-v2-container', {sitekey: 'V2_SITE_KEY'});
} else {
// Score OK → submit form directly
document.getElementById('loginForm').submit();
}
});
});
});
</script>
النمط 2: مفاتيح موقع مختلفة لإجراءات مختلفة
تستخدم بعض المواقع الإصدار 3 للمراقبة السلبية والإصدار 2 لإجراءات محددة عالية المخاطر:
Homepage → v3 only (passive score)
Login page → v3 assessment, v2 fallback
Checkout → v2 always (high security)
Contact form → v3 only
النمط 3: نص واحد، وضع مزدوج
تدعم Google تحميل برنامج نصي reCAPTCHA واحد يتعامل مع الإصدارين v2 وv3:
<script src="https://www.google.com/recaptcha/api.js?render=V3_SITE_KEY"></script>
<script>
// v3 execute
grecaptcha.execute('V3_SITE_KEY', {action: 'login'});
// v2 render (uses a different site key)
grecaptcha.render('v2-container', {sitekey: 'V2_SITE_KEY'});
</script>
الكشف عن التنفيذ المزدوج
كشف بايثون
import requests
import re
def detect_dual_recaptcha(url):
"""Detect if a page uses both reCAPTCHA v2 and v3."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36",
}
html = requests.get(url, headers=headers, timeout=15).text
result = {
"has_v3": False,
"has_v2": False,
"v3_site_key": None,
"v2_site_key": None,
"dual": False,
"pattern": None,
}
# Detect v3 (render parameter or enterprise.execute)
v3_match = re.search(r"api\.js\?render=([A-Za-z0-9_-]+)", html)
if v3_match and v3_match.group(1) != "explicit":
result["has_v3"] = True
result["v3_site_key"] = v3_match.group(1)
# Detect v3 in execute calls
v3_execute = re.search(
r"grecaptcha\.(?:enterprise\.)?execute\s*\(\s*['\"]([^'\"]+)['\"]",
html,
)
if v3_execute:
result["has_v3"] = True
if not result["v3_site_key"]:
result["v3_site_key"] = v3_execute.group(1)
# Detect v2 (g-recaptcha class or explicit render)
v2_match = re.search(r'data-sitekey="([^"]+)"', html)
if v2_match:
key = v2_match.group(1)
if key != result.get("v3_site_key"):
result["has_v2"] = True
result["v2_site_key"] = key
# Check for explicit v2 render
v2_render = re.search(
r"grecaptcha\.render\s*\([^,]+,\s*\{[^}]*sitekey:\s*['\"]([^'\"]+)",
html,
)
if v2_render:
result["has_v2"] = True
if not result["v2_site_key"]:
result["v2_site_key"] = v2_render.group(1)
result["dual"] = result["has_v3"] and result["has_v2"]
if result["dual"]:
# Determine pattern
if "display:none" in html or "display: none" in html:
result["pattern"] = "v3_pre_assessment_v2_fallback"
else:
result["pattern"] = "v2_v3_simultaneous"
return result
detection = detect_dual_recaptcha("https://example.com/login")
print(detection)
الكشف عن Node.js
const axios = require("axios");
async function detectDualRecaptcha(url) {
const { data: html } = await axios.get(url, { timeout: 15000 });
const result = {
hasV3: false,
hasV2: false,
v3SiteKey: null,
v2SiteKey: null,
dual: false,
};
// v3 detection
const v3Match = html.match(/api\.js\?render=([A-Za-z0-9_-]+)/);
if (v3Match && v3Match[1] !== "explicit") {
result.hasV3 = true;
result.v3SiteKey = v3Match[1];
}
// v2 detection
const v2Match = html.match(/data-sitekey="([^"]+)"/);
if (v2Match && v2Match[1] !== result.v3SiteKey) {
result.hasV2 = true;
result.v2SiteKey = v2Match[1];
}
result.dual = result.hasV3 && result.hasV2;
return result;
}
detectDualRecaptcha("https://example.com/login").then(console.log);
حل إستراتيجيات reCAPTCHA المزدوجة
الإستراتيجية 1: حل الإصدار 3 أولاً، ثم الإصدار 2 إذا لزم الأمر
تعكس الإستراتيجية المثالية التدفق الخاص بالموقع:
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_v3(site_key, page_url, action="login"):
"""Solve reCAPTCHA v3 and return token."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"version": "v3",
"action": action,
"json": 1,
}).json()
task_id = submit["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}).json()
if result.get("status") == 1:
return result["request"]
raise TimeoutError("v3 solve timeout")
def solve_v2(site_key, page_url):
"""Solve reCAPTCHA v2 and return token."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"json": 1,
}).json()
task_id = submit["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}).json()
if result.get("status") == 1:
return result["request"]
raise TimeoutError("v2 solve timeout")
def solve_dual_recaptcha(v3_key, v2_key, page_url, action="login"):
"""Handle dual reCAPTCHA: try v3, fall back to v2."""
# Step 1: Try v3
v3_token = solve_v3(v3_key, page_url, action)
# Step 2: Submit v3 token to target
response = requests.post(f"{page_url}/verify", data={
"g-recaptcha-response": v3_token,
})
# Step 3: Check if v2 fallback is needed
if "recaptcha" in response.text.lower() and v2_key:
print("v3 score too low — v2 fallback triggered")
v2_token = solve_v2(v2_key, page_url)
return {"version": "v2", "token": v2_token}
return {"version": "v3", "token": v3_token}
result = solve_dual_recaptcha(
v3_key="6LcExample_v3_key",
v2_key="6LcExample_v2_key",
page_url="https://example.com/login",
)
print(f"Solved with {result['version']}")
الإستراتيجية 2: تخطي الإصدار 3، وحل الإصدار 2 مباشرة
إذا كنت تعلم أن الموقع يعرض دائمًا الإصدار v2 لحركة المرور الآلية (ستكون نتيجة الإصدار 3 منخفضة)، فتخطى الإصدار 3 وحل الإصدار 2 على الفور:
# If you consistently fail v3 assessment, just solve v2 directly
token = solve_v2(v2_site_key, page_url)
submit_form(token)
وهذا يوفر الوقت والتكلفة لحل الإصدار الثالث الذي قد لا يتجاوز الحد الأدنى.
الإستراتيجية 3: التعامل مع المتصفح
بالنسبة للتطبيقات المعقدة، استخدم متصفحًا للتعامل مع التدفق الاحتياطي:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.get("https://example.com/login")
time.sleep(3)
# Check if v2 widget is visible
v2_visible = driver.execute_script("""
const container = document.querySelector('.g-recaptcha');
if (!container) return false;
const style = window.getComputedStyle(container.parentElement);
return style.display !== 'none' && style.visibility !== 'hidden';
""")
if v2_visible:
# v2 is showing — solve v2
sitekey = driver.find_element(
By.CSS_SELECTOR, "[data-sitekey]"
).get_attribute("data-sitekey")
token = solve_v2(sitekey, driver.current_url)
driver.execute_script(
f'document.getElementById("g-recaptcha-response").value = "{token}";'
)
else:
# v3 only — solve v3
# Extract v3 key from page source
v3_key = driver.execute_script(
"return document.querySelector('script[src*=\"render=\"]')"
".src.match(/render=([^&]+)/)[1];"
)
token = solve_v3(v3_key, driver.current_url)
# Inject v3 token into the form
driver.execute_script(f"""
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'g-recaptcha-response';
input.value = '{token}';
document.querySelector('form').appendChild(input);
""")
driver.find_element(By.CSS_SELECTOR, "form").submit()
حالات الحافة
مفتاحان مختلفان للموقع في نفس الصفحة
ستحتوي المواقع التي تستخدم اختبار reCAPTCHA المزدوج على مفتاحين مختلفين للموقع — أحدهما للإصدار 3 والآخر للإصدار 2. يظهر مفتاح v3 في عنوان URL للبرنامج النصي ?render=KEY وفي grecaptcha.execute('KEY', ...). يظهر المفتاح v2 في data-sitekey="KEY" في قسم عنصر واجهة المستخدم. سيؤدي استخدام المفتاح الخاطئ للإصدار الخاطئ إلى ظهور رموز غير صالحة.
reCAPTCHA Enterprise مع النسخة الاحتياطية v2
تستخدم بعض تطبيقات Enterprise الإصدار v3 Enterprise للتسجيل والإصدار 2 للتحديات:
# Detect and handle Enterprise + v2 combo
if "recaptcha/enterprise.js" in html:
# Use enterprise parameter for v3
v3_params = {"enterprise": 1, "version": "v3"}
else:
v3_params = {"version": "v3"}
نماذج متعددة في صفحة واحدة
إذا كانت الصفحة تحتوي على نماذج متعددة (تسجيل الدخول + التسجيل)، فقد يكون لكل منها مثيل reCAPTCHA الخاص به. قم باستخراج مفتاح الموقع من النموذج المحدد الذي تستهدفه:
# Target the login form specifically
login_form = soup.find("form", id="login-form")
widget = login_form.find(attrs={"data-sitekey": True})
sitekey = widget["data-sitekey"]
الأسئلة المتداولة
هل أحتاج إلى حل الإصدارين v2 وv3 في نفس الصفحة؟
لا، عادةً ما تقوم بحل الإصدار الثالث أولاً (يتم تشغيله تلقائيًا). إذا تجاوزت نتيجة الإصدار v3 حد الموقع، فلن يظهر أي اختبار للإصدار v2 وبذلك تكون قد انتهيت. ما عليك سوى حل الإصدار 2 إذا كانت نتيجة الإصدار 3 تؤدي إلى الإجراء الاحتياطي.
هل يمكنني استخدام استدعاء CaptchaAI API واحد لإجراء reCAPTCHA المزدوج؟
رقم v2 وv3 هما نوعان منفصلان من CAPTCHA مع مفاتيح موقع مختلفة وطرق حل مختلفة. يتطلب كل منها استدعاء API الخاص به إلى CaptchaAI. ومع ذلك، تحتاج فقط إلى إجراء مكالمة واحدة إذا مر الإصدار 3 دون تشغيل الإصدار 2.
كيف أعرف إذا تم تشغيل الإصدار الاحتياطي v2؟
تحقق من استجابة الخادم بعد إرسال رمز v3. إذا كانت الاستجابة تحتوي على HTML لعنصر واجهة المستخدم v2 أو تؤدي إلى اختبار v2 (إعادة التوجيه أو استجابة AJAX باستخدام CAPTCHA HTML)، فسيتم تشغيل الإجراء الاحتياطي. في المتصفح، تحقق مما إذا كانت حاوية الإصدار 2 أصبحت مرئية بعد إرسال الإصدار 3.
ما هو مفتاح الموقع الذي أستخدمه لكل إصدار؟
مفتاح موقع v3 موجود في عنوان URL للبرنامج النصي: api.js?render=V3_KEY. مفتاح موقع v2 موجود في عنصر واجهة المستخدم HTML: data-sitekey="V2_KEY". هم دائما مفاتيح مختلفة.
ملخص
تستخدم تطبيقات reCAPTCHA المزدوجة الإصدار 3 للتقييم المسبق غير المرئي والإصدار 2 كإجراء احتياطي مرئي عندما تكون نتيجة الإصدار 3 منخفضة جدًا. اكتشف كلا الإصدارين عن طريق التحقق من معلمة العرض (v3) ومفتاح بيانات عنصر واجهة المستخدم (v2). استراتيجية الأتمتة المثالية هي: حل الإصدار 3 أولاً باستخدامCaptchaAIوأرسل الرمز المميز، وحل الإصدار 2 فقط في حالة تشغيل الإجراء الاحتياطي. يتطلب كل إصدار استدعاء API منفصلاً مع مفتاح الموقع الخاص به.
مقالات ذات صلة
- Recaptcha تطبيق ديناميكي للصفحة الواحدة
- كيفية حل رد اتصال Recaptcha V2 باستخدام Api
- التعامل مع reCAPTCHA v2 وTurnstile في الموقع نفسه
أدلة ذات صلة
- البدء السريع مع CaptchaAI: حلّ أول كابتشا في 5 دقائق
- التعامل مع اختبارات CAPTCHA المتعددة في صفحة واحدة