عندما يتوقف سكربت الأتمتة عند خانة التحقق في صفحة تسجيل الدخول، فالمسار واضح: استخرج مفتاح الموقع من الصفحة، مرّره إلى CaptchaAI للحصول على التوكن، ثم احقن التوكن في النموذج وأرسله مع اسم المستخدم وكلمة المرور. CaptchaAI يتولى جزء CAPTCHA فقط، بينما يبقى منطق تسجيل الدخول — الحقول وملفات تعريف الارتباط وإدارة الجلسة — في يدك. في هذا الدليل نغطي المسار نفسه بثلاث طرق عملية: طلبات HTTP مباشرة، ثم Selenium، ثم Puppeteer، إضافة إلى التعامل مع المصادقة متعددة العوامل.
متى تحتاج إلى أتمتة تسجيل الدخول
الحالة الأكثر تكراراً في السوق العربي هي فرق ضمان الجودة (QA) في شركات التجارة الإلكترونية والتقنية المالية. تخيّل فريقاً في الرياض أو القاهرة يشغّل اختبارات انحدار ليلية على بيئة تجريبية مملوكة للشركة: كل تشغيل يحتاج إلى تسجيل دخول حقيقي، وصفحة الدخول محميّة بـ reCAPTCHA. بدل تعطيل الحماية يدوياً في كل مرة، يمرّر السكربت مفتاح الموقع إلى CaptchaAI ويكمل الاختبار دون تدخل بشري.
للأحمال المنخفضة مثل جلسة اختبار واحدة في كل مرة، تكفي خطة BASIC ($15 شهرياً، 5 خيوط معالجة). ومع توسّع مجموعات الاختبار المتوازية إلى عشرات الجلسات المتزامنة، تنقل الفريق إلى ADVANCE ($90 شهرياً، 50 خيطاً) للحصول على تزامن أعلى. تُحتسب التسعيرة على عدد الخيوط المتزامنة لا على عدد عمليات الحل، لذا يبقى الحل غير محدود داخل الخطة.
ملاحظة: أتمتة تسجيل الدخول مشروعة عندما تملك الحساب أو تملك تصريحاً صريحاً بالوصول إليه. هذا الدليل موجّه لبيئات مملوكة أو مصرّح بها ولاختبارات ضمان الجودة.
أنواع CAPTCHA التي تظهر في صفحات تسجيل الدخول
تختلف طريقة الإرسال بحسب نوع الاختبار المعروض على صفحة الدخول:
| اختبار CAPTCHA | كيف يظهر | طريقة CaptchaAI |
|---|---|---|
| reCAPTCHA v2 | خانة اختيار أو تحدٍّ قبل الإرسال | method=userrecaptcha |
| reCAPTCHA v3 | تسجيل نقاط غير مرئي يحجب المستخدمين منخفضي الدرجة | method=userrecaptcha&version=v3 |
| Cloudflare Turnstile | قطعة تظهر قبل نموذج تسجيل الدخول | method=turnstile |
| صورة CAPTCHA | صورة نصية تُكتب يدوياً | method=base64 |
إذا كانت صفحة الدخول تعتمد على hCaptcha، فاعلم أن CaptchaAI لا يدعم هذا النوع حالياً؛ يقتصر الدعم على الأنواع المذكورة في الجدول أعلاه إلى جانب Cloudflare Challenge وGeeTest v3 وشبكة الصور.
الطريقة الأولى: طلبات HTTP المباشرة دون متصفح
عندما يقبل نموذج تسجيل الدخول طلبات POST قياسية، فهذه أخفّ طريقة وأسرعها. تحمّل صفحة الدخول لالتقاط ملفات تعريف الارتباط ومفتاح الموقع، ثم ترسل المهمة إلى in.php، وتستطلع النتيجة من res.php، وأخيراً تُرفق التوكن في حقل g-recaptcha-response:
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha(site_key, page_url):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY, "method": "userrecaptcha",
"googlekey": site_key, "pageurl": page_url
})
task_id = resp.text.split("|")[1]
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
})
if result.text == "CAPCHA_NOT_READY": continue
if result.text.startswith("OK|"): return result.text.split("|")[1]
raise Exception(result.text)
raise TimeoutError()
# Login flow
session = requests.Session()
login_url = "https://example.com/login"
# Load login page to get cookies and site key
page = session.get(login_url)
# Extract site_key from the page HTML...
site_key = "6Le-wvkS..."
# Solve CAPTCHA
token = solve_recaptcha(site_key, login_url)
# Submit login form
resp = session.post(login_url, data={
"username": "user@example.com",
"password": "your_password",
"g-recaptcha-response": token
})
if resp.url != login_url:
print("Login successful!")
# session now has auth cookies for subsequent requests
استخدام requests.Session() هنا مهم: فهو يحتفظ بملفات تعريف الارتباط بين تحميل الصفحة وإرسال النموذج، وهو ما يحتاجه الخادم للتحقق من الجلسة.
الطريقة الثانية: Selenium مع Python
عندما تتطلب صفحة الدخول تنفيذ JavaScript أو تحميل القطعة ديناميكياً، يتيح Selenium قيادة متصفح حقيقي. تملأ بيانات الاعتماد، وتقرأ data-sitekey من عنصر reCAPTCHA، ثم تحقن التوكن في الحقل المخفي قبل الضغط على زر الإرسال:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time
API_KEY = "YOUR_API_KEY"
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
# Navigate to login page
driver.get("https://example.com/login")
wait = WebDriverWait(driver, 10)
# Fill in credentials
username_field = wait.until(EC.presence_of_element_located((By.NAME, "username")))
username_field.send_keys("user@example.com")
driver.find_element(By.NAME, "password").send_keys("your_password")
# Extract site key and solve
recaptcha = driver.find_element(By.CLASS_NAME, "g-recaptcha")
site_key = recaptcha.get_attribute("data-sitekey")
token = solve_recaptcha(site_key, driver.current_url)
# Inject token
driver.execute_script(
f"document.getElementById('g-recaptcha-response').innerHTML = '{token}';"
)
# Submit
driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()
wait.until(EC.url_changes(driver.current_url))
print(f"Logged in! Now at: {driver.current_url}")
يستدعي هذا المثال الدالة solve_recaptcha نفسها من الطريقة الأولى، ما يعني أنك تكتب منطق الحل مرة واحدة وتعيد استخدامه عبر كل مسارات الأتمتة.
الطريقة الثالثة: Puppeteer مع Node.js
لمن يعمل ضمن بيئة JavaScript، يقدّم Puppeteer المسار نفسه: اقرأ مفتاح الموقع من .g-recaptcha، احصل على التوكن عبر Axios، ثم احقنه وأرسل النموذج:
const puppeteer = require("puppeteer");
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveRecaptcha(siteKey, pageUrl) {
const submit = await axios.get("https://ocr.captchaai.com/in.php", {
params: {
key: API_KEY,
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
},
});
const taskId = submit.data.split("|")[1];
while (true) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId },
});
if (result.data === "CAPCHA_NOT_READY") continue;
if (result.data.startsWith("OK|")) return result.data.split("|")[1];
throw new Error(result.data);
}
}
(async () => {
const browser = await puppeteer.launch({ headless: "new" });
const page = await browser.newPage();
await page.goto("https://example.com/login");
// Fill credentials
await page.type("#username", "user@example.com");
await page.type("#password", "your_password");
// Get site key and solve
const siteKey = await page.$eval(".g-recaptcha", (el) =>
el.getAttribute("data-sitekey")
);
const token = await solveRecaptcha(siteKey, page.url());
// Inject and submit
await page.evaluate(
(t) => (document.getElementById("g-recaptcha-response").innerHTML = t),
token
);
await page.click('button[type="submit"]');
await page.waitForNavigation();
console.log("Logged in:", page.url());
await browser.close();
})();
الجمع بين CAPTCHA والمصادقة متعددة العوامل (MFA)
تفرض بعض المواقع طبقة مصادقة إضافية بعد نجاح تسجيل الدخول الأول. المنطق بسيط: تحلّ CAPTCHA وترسل بيانات الاعتماد أولاً، ثم تكتشف إعادة التوجيه إلى صفحة التحقق وترسل الرمز في خطوة تالية داخل الجلسة نفسها:
# Step 1: Solve CAPTCHA and submit login
token = solve_recaptcha(site_key, login_url)
resp = session.post(login_url, data={
"username": "user@example.com",
"password": "your_password",
"g-recaptcha-response": token
})
# Step 2: Handle MFA page (if redirected)
if "verify" in resp.url or "mfa" in resp.url:
# Your MFA code logic here
mfa_code = get_mfa_code()
resp = session.post(resp.url, data={"code": mfa_code})
# Step 3: Verify logged in
assert "dashboard" in resp.url
معالجة الأخطاء الشائعة
معظم مشكلات أتمتة تسجيل الدخول تعود إلى انتهاء صلاحية التوكن أو فقدان الجلسة، لا إلى الحل نفسه:
| المشكلة | السبب المحتمل | الإجراء |
|---|---|---|
| العودة إلى صفحة CAPTCHA بعد الإرسال | انتهت صلاحية التوكن | احلّ وأرسل خلال 60 ثانية من استلام التوكن |
| "بيانات اعتماد غير صالحة" رغم صحة كلمة المرور | رمز CSRF مفقود | استخرج رمز CSRF من صفحة الدخول وأرفقه في الطلب |
| ضياع الجلسة بعد تسجيل الدخول | لم تُحفظ ملفات تعريف الارتباط | استخدم requests.Session() أو ملفات ارتباط المتصفح |
| حجب reCAPTCHA v3 رغم وجود التوكن | الدرجة منخفضة جداً | يعمل CaptchaAI على رفع الدرجة؛ تأكد من صحة معلمة الإجراء (action) |
نصائح لبيئة إنتاج موثوقة
- التزم بنافذة الستين ثانية بين استلام التوكن وإرسال النموذج؛ تجاوزها يبطل التوكن ويعيدك إلى صفحة التحقق.
- افصل منطق الحل عن منطق تسجيل الدخول في دالة واحدة قابلة لإعادة الاستخدام كما في الأمثلة أعلاه.
- سجّل رموز الخطأ الراجعة من
res.phpلتشخيص أسرع عند تكرار الفشل.
الأسئلة الشائعة
لماذا يعيدني الموقع إلى صفحة CAPTCHA بعد إرسال النموذج بنجاح؟
غالباً لأن التوكن انتهت صلاحيته قبل الإرسال. توكن reCAPTCHA صالح لنحو دقيقتين، لكن الأفضل إرساله خلال 60 ثانية من الحصول عليه. تأكد أيضاً من عدم فقدان رمز CSRF أو ملفات تعريف الارتباط بين الطلبين.
ما أنواع CAPTCHA التي يمكن حلّها في صفحة الدخول عبر CaptchaAI؟
reCAPTCHA v2 وv3 (بما فيها Enterprise)، وCloudflare Turnstile وCloudflare Challenge، وGeeTest v3، وصور CAPTCHA النصية وشبكة الصور. أما hCaptcha وFunCaptcha فغير مدعومين حالياً، لذا تحقق من نوع الحماية قبل بناء المسار.
هل يجب أن يكون التوكن مطابقاً لنوع الاختبار؟
نعم. لكل نوع طريقة إرسال مختلفة: userrecaptcha لعائلة reCAPTCHA، وturnstile لـ Cloudflare Turnstile. استخدام الطريقة الخاطئة يعيد توكناً لا يقبله الخادم.
كيف أرفع درجة reCAPTCHA v3 عند تسجيل الدخول؟
درجة v3 تُحسب من سلوك الجلسة كاملة. حافظ على معلمة الإجراء (action) الصحيحة، واستخدم خادماً وسيطاً بسمعة عنوان IP جيدة، وتجنّب أنماط الطلبات المتسارعة التي تخفض الدرجة.