لحل reCAPTCHA v2 داخل متصفح هاتف مؤتمت، اتبع المسار نفسه في كل الأدوات: استخرج مفتاح الموقع (sitekey) وعنوان الصفحة، أرسلهما إلى CaptchaAI، انتظر الرمز الناتج، ثم احقنه في حقل g-recaptcha-response وأطلق رد النداء. سياق الجهاز — هاتف أو سطح مكتب — لا يغيّر خطوات الحل نفسها.
الفارق الحقيقي في الهاتف ليس الحل، بل تهيئة المتصفح: محاكاة جهاز صحيحة، ووكيل مستخدم متطابق، وتخطيط يستجيب للمس. اختر المسار الأنسب لبيئتك:
- Playwright مع ملف تعريف iPhone جاهز — الخيار الأبسط لفرق Python، إذ يضبط سياق الهاتف تلقائياً دون إعداد يدوي.
- Selenium مع محاكاة Chrome — الخيار الأنسب لسير عمل Node.js حين تحتاج إلى تحكم دقيق في مقاييس الجهاز ووكيل المستخدم.
كلا المسارين يفوّضان حل reCAPTCHA v2 إلى CaptchaAI بالكود نفسه، ويختلفان فقط في طريقة تهيئة المتصفح.
لماذا تختلف أتمتة متصفح الهاتف عن سطح المكتب
يواجه متصفح الهاتف المؤتمت اختبارات reCAPTCHA نفسها التي تظهر على سطح المكتب، لكنه يضيف طبقة من التفاصيل الخاصة بالجهاز. كثير من المواقع تفحص وكيل المستخدم ومقاس الشاشة قبل عرض النموذج، وقد تُقدّم تخطيطاً مختلفاً — أو حتى إعداد CAPTCHA مختلفاً — للزوّار القادمين من الهواتف. إذا لم تُحاكِ الجهاز بدقة، فقد لا يظهر عنصر reCAPTCHA أصلاً، أو يُرفض الرمز عند الإرسال لأن الخادم لاحظ عدم اتساق بصمة الجلسة.
الجدول التالي يلخّص العوامل التي تحتاج إلى ضبطها قبل تفويض الحل إلى CaptchaAI:
| العامل | سطح المكتب | الهاتف المحمول | الأثر على reCAPTCHA |
|---|---|---|---|
| وكيل المستخدم | Chrome/Firefox لسطح المكتب | Safari/Chrome للهاتف | قد تعرض بعض المواقع إعدادات CAPTCHA مختلفة حسب الجهاز |
| مقاس العرض | 1920 × 1080 أو أكبر | 390 × 844 | قد يظهر عنصر reCAPTCHA بشكل مختلف |
| نوع التفاعل | أحداث الماوس | أحداث اللمس | تتحقق بعض الاختبارات من نوع التفاعل |
| الشبكة | نطاق عريض | 4G/5G | قد تحتاج إلى مهلات أطول |
سيناريو من السوق العربي
تخيّل أنك ضمن فريق ضمان جودة لمتجر إلكتروني خليجي يعتمد نسخة هاتف مُحسّنة لإتمام الشراء. يكتشف الموقع وكلاء الهاتف ويعرض تخطيط reCAPTCHA v2 مخصصاً للشاشات الصغيرة، وتحتاج إلى اختبار مسار إتمام الشراء آلياً عشرات المرات يومياً دون تدخل بشري. بدل تشغيل مزرعة أجهزة فعلية، تُحاكي جهاز iPhone داخل Playwright أو Selenium، وتفوّض حل reCAPTCHA إلى CaptchaAI، ثم تُكمل إرسال النموذج. النتيجة اختبار موثوق لواجهة الهاتف يعمل من بيئة CI واحدة، ويعطي الفريق مؤشراً مبكراً على أي عطل في مسار الدفع قبل وصوله إلى المستخدم الحقيقي.
الطريقة الأولى: حل reCAPTCHA v2 عبر محاكاة الهاتف في Playwright (بايثون)
محاكاة الجهاز في Playwright هي أبسط طريقة لأتمتة متصفح الهاتف مع حل reCAPTCHA — دون الحاجة إلى جهاز فعلي. يحمّل السكربت التالي صفحة داخل ملف تعريف iPhone 13، يستخرج مفتاح الموقع، يرسله إلى CaptchaAI، ثم يحقن الرمز ويطلق رد النداء قبل إرسال النموذج:
# playwright_mobile_captcha.py
import asyncio
import httpx
from playwright.async_api import async_playwright
API_KEY = "YOUR_API_KEY"
async def solve_recaptcha(sitekey: str, pageurl: str) -> str:
"""Submit reCAPTCHA v2 to CaptchaAI and poll for result."""
async with httpx.AsyncClient(timeout=180) as client:
# Submit task
resp = await client.get(
"https://ocr.captchaai.com/in.php",
params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
},
)
result = resp.json()
if result["status"] != 1:
raise Exception(f"Submit failed: {result['request']}")
task_id = result["request"]
# Poll for result
for _ in range(30):
await asyncio.sleep(5)
poll = await client.get(
"https://ocr.captchaai.com/res.php",
params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": "1",
},
)
poll_result = poll.json()
if poll_result["status"] == 1:
return poll_result["request"]
if poll_result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Solve failed: {poll_result['request']}")
raise Exception("Polling timeout")
async def main():
async with async_playwright() as p:
# Launch with iPhone 13 emulation
iphone = p.devices["iPhone 13"]
browser = await p.chromium.launch(headless=False)
context = await browser.new_context(**iphone)
page = await context.new_page()
await page.goto("https://example.com/mobile-form")
await page.wait_for_selector(".g-recaptcha", timeout=10000)
# Extract sitekey
sitekey = await page.get_attribute(".g-recaptcha", "data-sitekey")
pageurl = page.url
print(f"Found sitekey: {sitekey}")
# Solve via CaptchaAI
token = await solve_recaptcha(sitekey, pageurl)
print(f"Token received: {token[:50]}...")
# Inject token
await page.evaluate(f"""
document.getElementById('g-recaptcha-response').value = '{token}';
document.getElementById('g-recaptcha-response').style.display = '';
""")
# Trigger callback if it exists
await page.evaluate(f"""
try {{
const clients = ___grecaptcha_cfg.clients;
Object.keys(clients).forEach(k => {{
Object.keys(clients[k]).forEach(j => {{
if (clients[k][j] && clients[k][j].callback) {{
clients[k][j].callback('{token}');
}}
}});
}});
}} catch(e) {{}}
""")
# Submit form
await page.click('button[type="submit"]')
await page.wait_for_load_state("networkidle")
print("Form submitted successfully")
await browser.close()
asyncio.run(main())
ملف التعريف iPhone 13 يضبط مقاس الشاشة ووكيل المستخدم ونسبة البكسل تلقائياً، فتحصل على سياق هاتف متسق دون ضبط يدوي. حافظ على مهلة الاستطلاع عند 5 ثوانٍ لكل محاولة حتى لا تُثقل نقطة النهاية، وأعد استخدام الرمز داخل الجلسة نفسها قبل انتهاء صلاحيته.
الطريقة الثانية: حل reCAPTCHA v2 بـ Selenium ومحاكاة الهاتف (JavaScript)
إذا كان سير عملك مبنياً على Node.js، فاستخدم محاكاة الهاتف في Chrome DevTools Protocol عبر Selenium. هنا تضبط مقاييس الجهاز ووكيل المستخدم يدوياً، ما يمنحك تحكماً أدق حين تحتاج إلى محاكاة طراز محدد:
// selenium_mobile_captcha.js
const { Builder, By, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
async function solveCaptcha(sitekey, pageurl) {
// Submit task
const submitResp = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: API_KEY,
method: 'userrecaptcha',
googlekey: sitekey,
pageurl: pageurl,
json: '1',
},
});
if (submitResp.data.status !== 1) {
throw new Error(`Submit failed: ${submitResp.data.request}`);
}
const taskId = submitResp.data.request;
// Poll for result
for (let i = 0; i < 30; i++) {
await new Promise((r) => setTimeout(r, 5000));
const pollResp = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
});
if (pollResp.data.status === 1) return pollResp.data.request;
if (pollResp.data.request !== 'CAPCHA_NOT_READY') {
throw new Error(`Solve failed: ${pollResp.data.request}`);
}
}
throw new Error('Polling timeout');
}
async function main() {
// Configure mobile emulation
const mobileEmulation = {
deviceMetrics: { width: 390, height: 844, pixelRatio: 3.0 },
userAgent:
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) ' +
'AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
};
const options = new chrome.Options();
options.setMobileEmulation(mobileEmulation);
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
try {
await driver.get('https://example.com/mobile-form');
await driver.wait(until.elementLocated(By.css('.g-recaptcha')), 10000);
// Extract sitekey
const captchaEl = await driver.findElement(By.css('.g-recaptcha'));
const sitekey = await captchaEl.getAttribute('data-sitekey');
const pageurl = await driver.getCurrentUrl();
console.log(`Sitekey: ${sitekey}`);
// Solve CAPTCHA
const token = await solveCaptcha(sitekey, pageurl);
console.log(`Token: ${token.substring(0, 50)}...`);
// Inject token
await driver.executeScript(`
document.getElementById('g-recaptcha-response').value = arguments[0];
`, token);
// Submit form
await driver.findElement(By.css('button[type="submit"]')).click();
console.log('Form submitted');
} finally {
await driver.quit();
}
}
main().catch(console.error);
لاحظ أن قيمة userAgent هنا يجب أن تبقى نفسها التي تستخدمها عند إرسال النموذج، لأن كثيراً من الخوادم يتحقق من ثبات وكيل المستخدم بين لحظة الحل ولحظة الإرسال.
معالجة الأخطاء الشائعة
معظم مشكلات محاكاة الهاتف تعود إلى عدد محدود من الأسباب المتكررة؛ يربط الجدول التالي كل عرض شائع بسببه المرجّح وإجراء الإصلاح المباشر:
| المشكلة | السبب المحتمل | الحل |
|---|---|---|
| لا يظهر reCAPTCHA داخل المحاكاة | الموقع يكتشف المحاكاة عبر navigator.platform |
اضبط تجاوز platform في Chrome DevTools Protocol |
لا يُعثر على حقل g-recaptcha-response |
تخطيط الهاتف يستخدم طريقة عرض مختلفة | ابحث عن الحقل عبر خاصية name بدل المعرّف id |
| يُحقن الرمز لكن النموذج يفشل | الخادم يتحقق من تطابق وكيل المستخدم | استخدم وكيل المستخدم نفسه أثناء الحل وإرسال النموذج |
| بطء تحميل الصفحات في المحاكاة | صفحات ثقيلة بالموارد | استخدم الراية --disable-images في Chrome لتسريع التحميل |
أسئلة شائعة
هل يتغيّر مفتاح الموقع بين نسخة الهاتف ونسخة سطح المكتب؟
عادةً لا؛ يستخدم معظم المواقع مفتاح موقع واحداً لـ reCAPTCHA v2 عبر جميع الأجهزة. المهم أن تستخرج المفتاح من الصفحة التي تُحمّل فعلياً في سياق الهاتف، لأن بعض المواقع تقدّم صفحة هبوط مختلفة لوكلاء الهاتف قد تحمل مفتاحاً أو معلمات مختلفة.
كم عدد الخيوط (Threads) التي أحتاجها لتشغيل أتمتة الهاتف على نطاق واسع؟
يعتمد ذلك على عدد الطلبات المتزامنة لديك. يفوتر CaptchaAI حسب الخيوط المتزامنة لا حسب كل عملية حل، وكل خيط يعالج اختباراً واحداً في كل مرة مع عدد حلول غير محدود شهرياً. كمرجع سريع:
- مهمة أتمتة فردية أو خط CI واحد — تكفي خطة BASIC بسعر 15 دولاراً شهرياً وتتضمن 5 خيوط لمعظم هذه الحالات.
- تشغيل متوازٍ كثيف عبر عدة أجهزة محاكاة — انتقل إلى خطة أعلى بعدد خيوط أكبر يناسب ذروة الطلبات المتزامنة لديك.
لماذا يُقبل الرمز محلياً ويُرفض داخل خط أنابيب CI؟
غالباً لأن وكيل المستخدم أو عنوان IP أو سياق الجلسة يختلف بين جهازك وبيئة CI. راجع هذه النقاط الثلاث بالترتيب:
- طابِق وكيل المستخدم المستخدَم في الحل مع الذي يرسل النموذج.
- أعد استخدام الرمز داخل الجلسة نفسها قبل انتهاء صلاحيته القصيرة.
- ثبّت إعدادات المحاكاة نفسها في جهازك وبيئة CI معاً.
هل يدعم CaptchaAI حل reCAPTCHA v2 غير المرئي وreCAPTCHA v3 بالطريقة نفسها؟
نعم؛ تشترك جميع أنواع reCAPTCHA في طريقة الإرسال userrecaptcha ذاتها إلى CaptchaAI. ما يتغيّر هو تدفق الحقن: نسخة v2 غير المرئية وv3 لا تعرضان مربع اختيار، بل تعتمدان على رد النداء لتمرير الرمز إلى الصفحة بعد الحل.
الخطوات التالية
- ابدأ بحل أول اختبار CAPTCHA خلال خمس دقائق
- دليل حل reCAPTCHA v2 عبر الـ API خطوة بخطوة
- حل Cloudflare Turnstile عبر واجهة الـ API
- حل GeeTest v3 عبر الـ API