حلّ تحدي GeeTest v3 المنزلق يعتمد في جوهره على ثلاث معلمات فقط: gt وchallenge وعنوان الصفحة pageurl. إذا استخرجت هذه القيم بشكل صحيح وأرسلتها إلى CaptchaAI قبل أن تنتهي صلاحية التحدي، تحصل في المقابل على ثلاث قيم جاهزة — challenge وvalidate وseccode — تعيدها إلى الموقع المستهدف لإتمام التحقق. في هذا الدليل نفكّك كل معلمة على حدة، ثم نسير في مسار عملي كامل بلغة Python من لحظة الاستخراج حتى الاستجابة النهائية للموقع.
معلمات GeeTest v3 الأساسية
قبل بناء أي طلب، عليك التمييز بين المعلمات التي يقبلها إرسال GeeTest v3 وأيّها إلزامي فعلاً:
| المعلمة | مطلوبة | الوصف |
|---|---|---|
gt |
نعم | معرّف حساب GeeTest الخاص بالموقع (سلسلة سداسية عشرية من 32 حرفًا). يظهر في مصدر الصفحة أو في استجابة واجهة برمجة التطبيقات |
challenge |
نعم | سلسلة التحدي الخاصة بالجلسة. يجب أن تكون جديدة مع كل عملية حل |
pageurl |
نعم | عنوان URL الكامل للصفحة التي يظهر فيها اختبار CAPTCHA |
api_server |
لا | النطاق الفرعي المخصص لخادم GeeTest API عند استخدامه |
المعلمتان gt وchallenge هما محور كل شيء: الأولى ثابتة لكل موقع، والثانية متغيّرة لكل جلسة. الخلط بينهما أو إرسال challenge قديم هو السبب الأول لفشل الحل.
كيف يعمل تحدي التمرير في GeeTest؟
يعرض GeeTest v3 قطعة أحجية (puzzle) يسحبها المستخدم أفقيًا إلى مكانها الصحيح. خلف هذه الحركة البسيطة توجد آلية تحقق من ثلاث مراحل: الموقع يُعرّف نفسه عبر حساب gt ثابت، ثم يطلب من خادم GeeTest سلسلة challenge جديدة لكل زيارة، وبعد اكتمال السحب يعيد الخادم قيمتَي validate وseccode اللتين تثبتان أن التفاعل صحيح.
المشكلة العملية أمام مهندس استخراج البيانات أن قيمة challenge ترتبط بجلسة زمنية قصيرة، ومسار الأحجية يتطلب حسابات دقيقة. بدلاً من محاكاة الحركة يدويًا، ترسل هذه القيم إلى CaptchaAI التي تعيد لك الحل جاهزًا للإرسال. GeeTest v3 مدعوم بشكل كامل في CaptchaAI، بينما لا يزال دعم GeeTest v4 قيد الإطلاق ولم يتوفر بعد.
الخطوة 1: استخراج gt وchallenge من الصفحة
الخطوة الأولى دائمًا هي قراءة الصفحة والبحث عن gt ثم عن نقطة النهاية التي تُرجع challenge. في كثير من المواقع تجد gt مضمّنًا مباشرة في مصدر HTML، بينما يأتي challenge من طلب تسجيل منفصل مثل register-slide. الكود التالي يجرّب المسارين معًا:
# extract_geetest_params.py
import requests
import re
import json
def extract_geetest_v3(page_url, session=None):
"""Extract GeeTest v3 gt and challenge from a page."""
if session is None:
session = requests.Session()
session.headers["User-Agent"] = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/125.0.0.0 Safari/537.36"
)
resp = session.get(page_url, timeout=15)
html = resp.text
# Method 1: Extract gt from HTML
gt_match = re.search(r'gt["\']?\s*[:=]\s*["\']([a-f0-9]{32})', html)
gt = gt_match.group(1) if gt_match else None
# Method 2: Find API endpoint that returns challenge
api_match = re.search(r'(https?://[^"\']+register-slide[^"\']*)', html)
challenge = None
if api_match:
api_url = api_match.group(1)
api_resp = session.get(api_url, timeout=10)
try:
data = api_resp.json()
challenge = data.get("challenge")
gt = gt or data.get("gt")
except json.JSONDecodeError:
pass
if not challenge:
# Try embedded challenge
ch_match = re.search(r'challenge["\']?\s*[:=]\s*["\']([a-f0-9]+)', html)
challenge = ch_match.group(1) if ch_match else None
return {"gt": gt, "challenge": challenge, "pageurl": page_url}
# Usage
params = extract_geetest_v3("https://example.com/login")
print(f"gt: {params['gt']}")
print(f"challenge: {params['challenge']}")
إذا كان gt يُحمَّل عبر JavaScript ولم يظهر في مصدر الصفحة، افتح طلبات الشبكة (XHR) وابحث عن استجابة نقطة التسجيل، أو استعن بأداة مثل Selenium لتشغيل الصفحة بالكامل.
الخطوة 2: إرسال المعلمات إلى CaptchaAI
بعد الحصول على gt وchallenge، ترسلهما مع pageurl إلى نقطة النهاية in.php مستخدمًا method=geetest. تُعيد الخدمة معرّف مهمة، ثم تستطلع النتيجة من res.php حتى يجهز الحل. عادةً ما يكتمل حل GeeTest v3 خلال 10 إلى 20 ثانية:
# solve_geetest.py
import requests
import time
import os
def solve_geetest(gt, challenge, pageurl, api_server=None):
"""Solve GeeTest v3 slide CAPTCHA via CaptchaAI."""
api_key = os.environ["CAPTCHAAI_API_KEY"]
payload = {
"key": api_key,
"method": "geetest",
"gt": gt,
"challenge": challenge,
"pageurl": pageurl,
"json": 1,
}
if api_server:
payload["api_server"] = api_server
# Submit
resp = requests.post(
"https://ocr.captchaai.com/in.php",
data=payload,
timeout=30,
)
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll — GeeTest typically solves in 10-20 seconds
time.sleep(10)
for _ in range(30):
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key,
"action": "get",
"id": task_id,
"json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
return data["request"] # Returns challenge, validate, seccode
if data["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(data["request"])
time.sleep(5)
raise TimeoutError("GeeTest solve timeout")
لاحظ أن الاستجابة الناجحة تحمل القيم الثلاث المطلوبة: challenge وvalidate وseccode. هذه هي البيانات التي سيعتمد عليها الموقع لقبول الجلسة.
الخطوة 3: إعادة الحل إلى الموقع المستهدف
الحل الذي تعيده CaptchaAI ليس النهاية؛ عليك تمرير قيمه الثلاث إلى نقطة نهاية التحقق في الموقع نفسه، غالبًا عبر حقول geetest_challenge وgeetest_validate وgeetest_seccode:
# submit_solution.py
import json
def submit_geetest_solution(session, validation_url, solution, original_challenge):
"""Submit GeeTest solution to the target site."""
# Parse solution if string
if isinstance(solution, str):
solution = json.loads(solution)
payload = {
"geetest_challenge": solution.get("challenge", original_challenge),
"geetest_validate": solution.get("validate", ""),
"geetest_seccode": solution.get("seccode", ""),
}
resp = session.post(validation_url, data=payload, timeout=30)
return resp
# Complete flow
def full_geetest_flow(page_url, validation_url):
import requests
from extract_geetest_params import extract_geetest_v3
session = requests.Session()
session.headers["User-Agent"] = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/125.0.0.0 Safari/537.36"
)
# Step 1: Extract parameters
params = extract_geetest_v3(page_url, session)
print(f"gt: {params['gt']}, challenge: {params['challenge'][:16]}...")
# Step 2: Solve
solution = solve_geetest(
params["gt"], params["challenge"], params["pageurl"],
)
print("Solved!")
# Step 3: Submit
resp = submit_geetest_solution(
session, validation_url, solution, params["challenge"],
)
print(f"Validation response: {resp.status_code}")
return resp
من المهم استخدام الجلسة (session) نفسها في الاستخراج والإرسال، حتى تبقى ملفات تعريف الارتباط ورؤوس الطلب متطابقة مع الجلسة التي وُلّد فيها challenge.
الحفاظ على نضارة قيمة challenge
قيمة challenge مرتبطة بالجلسة وتنتهي صلاحيتها بسرعة، لذا الأفضل جلبها مباشرة قبل الإرسال بدلاً من إعادة استخدام قيمة مخزّنة:
# fresh_challenge.py
import time
def get_fresh_challenge(session, register_url):
"""Always fetch a fresh challenge before solving."""
resp = session.get(register_url, timeout=10)
data = resp.json()
challenge = data.get("challenge")
if not challenge:
raise ValueError("No challenge returned")
return challenge
def solve_with_fresh_challenge(session, gt, register_url, pageurl):
"""Ensure challenge is fresh before submitting to CaptchaAI."""
challenge = get_fresh_challenge(session, register_url)
# Submit immediately — don't let it expire
solution = solve_geetest(gt, challenge, pageurl)
return solution
القاعدة الذهبية: استخرج challenge وأرسله إلى CaptchaAI خلال ثوانٍ. أي تحدٍ قديم أو منتهي الصلاحية سيفشل حتمًا مهما كانت بقية المعلمات صحيحة.
التعامل مع خادم GeeTest مخصص
بعض المواقع لا تستخدم النطاق الافتراضي api.geetest.com، بل نطاقًا فرعيًا خاصًا بمنطقتها. في هذه الحالة مرّر المعلمة api_server لتوجيه الطلب إلى الخادم الصحيح:
# The api_server parameter specifies a custom GeeTest backend
# Default: api.geetest.com
# Custom examples: api-na.geetest.com, api.geetest.com/ajax-custom
solution = solve_geetest(
gt="abc123...",
challenge="def456...",
pageurl="https://example.com/login",
api_server="api-na.geetest.com", # North America endpoint
)
لمعرفة القيمة الصحيحة، راقب طلبات الشبكة في الصفحة وابحث عن نطاق بالشكل api-*.geetest.com.
سيناريو عملي: أتمتة موقع حجوزات إقليمي
تخيّل مهندسًا في القاهرة أو الرياض يبني أداة مراقبة للأسعار على موقع حجوزات أو متجر إلكتروني إقليمي يحمي صفحة تسجيل الدخول بـ GeeTest v3. مع كل تشغيل للأداة، تستخرج السكربت قيمة gt الثابتة وchallenge الجديد، ثم ترسلهما إلى CaptchaAI وتعيد الحل إلى الموقع لإكمال الجلسة والوصول إلى لوحة النتائج.
لأن CaptchaAI تعتمد التسعير على أساس عدد الـ Threads المتزامنة لا على كل عملية حل، يستطيع هذا المهندس البدء بخطة BASIC ($15 شهريًا، 5 threads) لأحمال الاختبار الخفيفة، والانتقال إلى ADVANCE ($90 شهريًا، 50 thread) عندما يحتاج إلى تشغيل عشرات الجلسات المتوازية أثناء جمع البيانات في ساعات الذروة. لا توجد رسوم إضافية لكل تحدٍ ولا سقف يومي داخل الخطة، ما يجعل التكلفة قابلة للتنبؤ عند التوسّع.
استكشاف الأخطاء الشائعة وإصلاحها
| المشكلة | السبب المحتمل | الإجراء |
|---|---|---|
ERROR_CAPTCHA_UNSOLVABLE |
قيمة challenge منتهية أو معرّف gt خاطئ |
اجلب challenge جديدًا مباشرة قبل الإرسال وتأكد من صحة gt |
validate فارغة |
معلمات موجّهة لموقع GeeTest v4 (غير مدعوم بعد) | تأكد أن الموقع يعتمد GeeTest v3؛ دعم v4 قيد الإطلاق |
| رفض الموقع للحل | نقص إحدى القيم الثلاث | أرسل geetest_challenge وgeetest_validate وgeetest_seccode كاملة |
تعذّر إيجاد gt |
القيمة مُحمَّلة عبر JavaScript | استخدم Selenium أو راجع استجابات XHR لنقطة التسجيل |
الأسئلة الشائعة
هل يمكن حلّ GeeTest v4 عبر CaptchaAI؟
ليس بعد. الإصدار المتاح للحل هو GeeTest v3 فقط، أما GeeTest v4 فهو قيد الإطلاق ولم يصبح متاحًا حتى الآن. هذا الدليل مخصّص لـ GeeTest v3 المنزلق.
لماذا يتكرر خطأ ERROR_CAPTCHA_UNSOLVABLE؟
السبب الأكثر شيوعًا هو إرسال قيمة challenge قديمة انتهت صلاحيتها قبل وصول الطلب. اجلب التحدي جديدًا وأرسله فورًا، وتأكد أيضًا من أن gt يخصّ الموقع نفسه وأن pageurl صحيح.
هل أحتاج متصفحًا كاملاً مثل Selenium لاستخراج المعلمات؟
ليس دائمًا. إذا ظهرت gt وchallenge في مصدر HTML أو في استجابة طلب تسجيل بسيط، تكفي مكتبة requests. تلجأ إلى Selenium فقط عندما تُحمَّل القيم ديناميكيًا عبر JavaScript.
كم يستغرق حل تحدي GeeTest v3 تقريبًا؟
يكتمل الحل عادةً خلال 10 إلى 20 ثانية. لذلك يبدأ الكود بانتظار 10 ثوانٍ ثم يستطلع النتيجة من res.php على فترات قصيرة حتى تجهز.
أي خطة CaptchaAI تناسب حجم طلبات GeeTest لديّ؟
يعتمد الاختيار على عدد الجلسات المتزامنة. تكفي BASIC ($15 شهريًا، 5 threads) للاختبارات الخفيفة، بينما تناسب ADVANCE ($90 شهريًا، 50 thread) أحمال جمع البيانات الأكبر، مع عدد حلول غير محدود داخل كل thread.
أدلة ذات صلة
- ابدأ سريعًا مع CaptchaAI وحلّ أول كابتشا في خمس دقائق
- أتمتة مقارنة أسعار توصيل الطعام مع حل اختبارات CAPTCHA
أتقن معلمات GeeTest وابدأ الحل عبر CaptchaAI.