تقوم تطبيقات الصفحة الواحدة بتحميل reCAPTCHA ديناميكيًا - الأداة غير موجودة في HTML الأولي. يعرض نموذج تسجيل الدخول React اختبار CAPTCHA فقط عند تحميل المكون. تقوم صفحة Vue checkout بتحميل reCAPTCHA بعد أن ينقر المستخدم على "وضع الطلب". يفتقد استخراج مصدر الصفحة التقليدي هذه الأمور تمامًا. فيما يلي كيفية اكتشاف reCAPTCHA المحملة ديناميكيًا وحلها.
لماذا تختلف المنتجعات الصحية؟
| صفحة تقليدية | سبا |
|---|---|
| البرنامج النصي reCAPTCHA بتنسيق HTML الأولي | تم إدخال البرنامج النصي بعد تغيير المسار |
| يتم عرض القطعة عند تحميل الصفحة | يتم عرض القطعة على جبل المكون |
| مفتاح الموقع في مصدر الصفحة | مفتاح الموقع في حزمة JavaScript |
| يتم إرسال النموذج عبر POST | يتم إرسال النموذج عبر XHR/fetch |
في SPA، قد لا تكون أداة reCAPTCHA موجودة حتى يقوم المستخدم بتشغيلها. يجب أن تنتظر الأتمتة الخاصة بك حتى تظهر الأداة.
اكتشاف أداة reCAPTCHA
انتظر العنصر
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://example.com/login")
# SPA may need a click or navigation to trigger reCAPTCHA
page.click("#show-login-form")
# Wait for reCAPTCHA iframe to appear
recaptcha_frame = page.wait_for_selector(
"iframe[src*='recaptcha']",
timeout=15000
)
print("reCAPTCHA detected:", recaptcha_frame.get_attribute("src"))
استخراج مفتاح الموقع
يمكن أن يكون مفتاح الموقع في مواقع متعددة في SPA:
# Method 1: From the iframe src
iframe_src = recaptcha_frame.get_attribute("src")
# src contains: ...?k=6LcR_RsTAAAAADge...
import re
match = re.search(r'[?&]k=([^&]+)', iframe_src)
site_key = match.group(1) if match else None
# Method 2: From data-sitekey attribute
site_key = page.eval_on_selector(
"[data-sitekey]",
"el => el.getAttribute('data-sitekey')"
)
# Method 3: From JavaScript bundle (last resort)
site_key = page.evaluate("""
() => {
// Check for grecaptcha render calls
const scripts = document.querySelectorAll('script');
for (const s of scripts) {
const match = s.textContent.match(/sitekey['":\s]+(['"])(6L[^'"]+)\\1/);
if (match) return match[2];
}
return null;
}
""")
حل اختبار reCAPTCHA
بمجرد حصولك على مفتاح الموقع، قم بإرساله إلى CaptchaAI:
import requests
import time
def solve_recaptcha(site_key, page_url):
# Submit task
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"json": 1
})
task_id = resp.json()["request"]
# Poll for result
for _ in range(60):
time.sleep(3)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1
})
data = result.json()
if data["status"] == 1:
return data["request"]
raise TimeoutError("Solve timed out")
حقن الرمز المميز في SPA
المنتجعات الصحية لا تقدم النماذج التقليدية. تحتاج إلى إدخال الرمز المميز حيث يتوقعه التطبيق.
الطريقة الأولى: تعيين منطقة النص المخفية
token = solve_recaptcha(site_key, "https://example.com/login")
# Inject into the g-recaptcha-response textarea
page.evaluate(f"""
document.getElementById('g-recaptcha-response').value = '{token}';
""")
# Submit the form
page.click("#login-button")
الطريقة الثانية: تشغيل رد الاتصال
تستخدم العديد من تطبيقات SPA reCAPTCHA وظيفة رد الاتصال:
# Find the callback function name
callback = page.evaluate("""
() => {
const widget = document.querySelector('.g-recaptcha');
return widget?.getAttribute('data-callback') || null;
}
""")
# Call it with the token
if callback:
page.evaluate(f"window['{callback}']('{token}')")
else:
# Try the default grecaptcha callback
page.evaluate(f"""
if (window.grecaptcha) {{
// Set the response and trigger verification
document.getElementById('g-recaptcha-response').value = '{token}';
// Find and call any registered callbacks
const form = document.querySelector('form');
if (form) form.dispatchEvent(new Event('submit'));
}}
""")
الطريقة الثالثة: اعتراض XHR (JavaScript / Puppeteer)
const puppeteer = require('puppeteer');
async function solveRecaptchaInSPA() {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
// Intercept the API call and inject the token
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/api/login')) {
const postData = JSON.parse(request.postData() || '{}');
// Token already set via page.evaluate — let it pass
request.continue();
} else {
request.continue();
}
});
await page.goto('https://example.com/login');
await page.waitForSelector('[data-sitekey]');
const siteKey = await page.$eval(
'[data-sitekey]',
el => el.getAttribute('data-sitekey')
);
// Solve with CaptchaAI (implementation omitted — same as Python)
const token = await solveCaptcha(siteKey, page.url());
// Inject token and trigger callback
await page.evaluate((t) => {
document.getElementById('g-recaptcha-response').value = t;
const callback = document.querySelector('.g-recaptcha')
?.getAttribute('data-callback');
if (callback && window[callback]) {
window[callback](t);
}
}, token);
}
الأنماط الخاصة بالإطار
رد الفعل (رد فعل-جوجل-recaptcha)
غالبًا ما تستخدم تطبيقات React الحزمة react-google-recaptcha. يعرض المكون بشكل غير متزامن:
# Wait for React to mount the component
page.wait_for_selector(".g-recaptcha", state="attached")
# The sitekey is in the rendered div's data attribute
site_key = page.eval_on_selector(
".g-recaptcha", "el => el.dataset.sitekey"
)
فيو (vue-recaptcha)
# Vue may use v-if to conditionally render
# Navigate or interact to trigger the condition
page.click("#proceed-to-checkout")
page.wait_for_selector("iframe[src*='recaptcha']")
الزاوي
# Angular apps may lazy-load reCAPTCHA modules
# Wait for the specific Angular component
page.wait_for_selector("re-captcha, app-recaptcha, [data-sitekey]")
التعامل مع تغييرات المسار
تقوم SPA بإعادة استخدام الصفحة - ويتم التنقل دون عمليات إعادة التحميل الكاملة:
# Listen for reCAPTCHA appearing after SPA navigation
page.goto("https://example.com")
# Navigate within the SPA
page.click("a[href='/login']")
# The URL changed but no page reload happened
# Wait for the CAPTCHA to render in the new "page"
page.wait_for_selector("iframe[src*='recaptcha']", timeout=10000)
استكشاف الأخطاء وإصلاحها
| المشكلة | السبب | الإجراء |
|---|---|---|
| يُنشأ الرمز المميز لكن الجهة المستهدفة ترفضه | مفتاح الموقع أو الصفحة أو سياق الجلسة لا يتطابق | التقط المعلمات من جديد وأعد استخدام الرمز داخل جلسة HTTP أو المتصفح نفسها |
| تنتهي عملية الاستطلاع بمهلة | الفاصل الزمني أو وقت الانتظار أو معالجة الأخطاء صارمة أكثر من اللازم | استطلع كل 5 إلى 10 ثوانٍ وافصل بين انتهاء المهلة والأخطاء الفعلية وسجّل السبب |
| ينجح المثال محليًا لكنه يفشل داخل سير العمل | رد النداء أو حقل النموذج أو حقن الرمز مفقود في السلسلة الفعلية | تحقق من المسار الكامل بين أداة الحل والطلب النهائي إلى الموقع المستهدف |
الخطوات التالية
- البدء السريع مع CaptchaAI: حلّ أول كابتشا في 5 دقائق
- كيفية حلّ reCAPTCHA v2 عبر الـ API: دليل خطوة بخطوة
- كيفية حل Cloudflare Turnstile باستخدام واجهة API
- كيفية حل GeeTest v3 باستخدام API