لتسريع مكالمات CAPTCHA API لا تحتاج إلى خوادم أقوى ولا إلى إعادة كتابة منطق الحل؛ يكفي أن تتوقف عن فتح اتصال جديد مع كل طلب. فكل عملية حل تتكوّن من طلب إرسال واحد يتبعه من 3 إلى 10 طلبات استطلاع، وإذا أنشأ عميلك اتصالاً منفصلاً لكل طلب فإنه يكرّر مصافحة TCP وتفاوض TLS في كل مرة — أي 100 إلى 300 مللي ثانية مهدرة لكل اتصال. في هذا الدليل نعيد استخدام الاتصال نفسه عبر إبقائه مفتوحاً (Keep-Alive) وعبر تعدد الإرسال في HTTP/2 مع CaptchaAI، فيتقلّص هذا الحمل إلى الحد الأدنى.
لماذا تصنع إعادة استخدام الاتصال هذا الفرق؟
لنأخذ عملية حل reCAPTCHA v2 نموذجية. هي في جوهرها سلسلة من طلبات HTTP تسير على النحو التالي:
- طلب إرسال واحد إلى
in.php - من 4 إلى 6 طلبات استطلاع إلى
res.php - الإجمالي: من 5 إلى 7 طلبات HTTP لكل عملية حل
المشكلة ليست في الطلبات نفسها، بل فيما يسبق كلاً منها. فكل اتصال TCP جديد يبدأ بمصافحة ثلاثية، ثم يضيف HTTPS فوقها جولة تفاوض TLS كاملة. وحين يفتح عميلك اتصالاً منفصلاً لكل طلب تتراكم هذه التكلفة بسرعة: فبدون إبقاء الاتصال مفتوحاً تصبح الكلفة 5 × (مصافحة TCP ~50 مللي ثانية + TLS ~100 مللي ثانية) = 750 مللي ثانية حمل إضافي، بينما تنخفض مع إبقائه مفتوحاً إلى 1 × (TCP + TLS) + 4 × (~5 مللي ثانية لإعادة الاستخدام) = 170 مللي ثانية حمل إضافي.
التوفير: نحو 580 مللي ثانية لكل عملية حل. وعند حجم يبلغ 10,000 عملية حل يومياً، يتحول ذلك إلى ما يقارب 1.6 ساعة من زمن الاستجابة الموفّر كل يوم — دون تغيير سطر واحد في منطق الحل.
يزداد هذا الأثر كلما ابتعدت بيئة التشغيل جغرافياً عن الخوادم. فالمطوّر الذي يشغّل أدواته من الشرق الأوسط أو شمال إفريقيا يواجه غالباً زمن ذهاب وإياب (RTT) أعلى، ومصافحة TLS تتطلب عدة جولات؛ لذا يوفّر إلغاؤها المتكرر وقتاً أكبر مما يوفّره داخل مركز بيانات مجاور.
سيناريو عملي: مراقبة أسعار بحجم كبير
تخيّل فريقاً يشغّل أداة لمراقبة أسعار متاجر إلكترونية تصطدم بجدار reCAPTCHA v2 عند كل جلسة. عند 10,000 عملية حل يومياً، يعني إبقاء الاتصال مفتوحاً توفير نحو 1.6 ساعة من زمن الاستجابة المتراكم، أي دورات جمع أسرع ونافذة تحديث أحدث للأسعار.
ومن ناحية التكلفة، لا يغيّر Keep-Alive فاتورتك مع CaptchaAI؛ فالتسعير قائم على عدد الـ Threads المتزامنة لا على عدد الطلبات، وكل خطة تشمل عمليات حل غير محدودة لكل Thread. مثلاً تبدأ خطة BASIC من 15 دولاراً شهرياً بخمسة Threads، وتوفّر خطة ADVANCE بسعر 90 دولاراً شهرياً خمسين Thread. فدور إبقاء الاتصال مفتوحاً هنا ليس خفض الكلفة بل تسريع كل عملية ضمن الـ Threads نفسها.
Python: إعادة استخدام الاتصال عبر requests.Session
تدعم مكتبة requests إبقاء الاتصال مفتوحاً تلقائياً ما دمت تستخدم كائن Session بدلاً من دوال الوحدة المباشرة. ينشئ الكائن تجمّع اتصالات داخلياً ويعيد استخدامه في كل الطلبات الصادرة إلى المضيف نفسه:
# keepalive_solver.py
import os
import time
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Create a session — reuses TCP connections across requests
session = requests.Session()
session.headers.update({"Connection": "keep-alive"})
def solve_captcha(sitekey, pageurl):
"""Solve reCAPTCHA v2 using a persistent connection."""
# Submit — uses existing connection if available
resp = session.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll — reuses the same connection
time.sleep(15)
for _ in range(25):
poll = session.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.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Solve multiple CAPTCHAs reusing the same connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
تعالج الحلقة الأخيرة خمس عمليات حل عبر الجلسة نفسها؛ الاتصال الأول وحده يدفع تكلفة المصافحة، والبقية تعيد استخدامه. احتفظ بالجلسة حيّة طوال عمر التطبيق ولا تنشئ واحدة لكل عملية حل.
Python: تفعيل HTTP/2 عبر httpx
لا تدعم مكتبة requests بروتوكول HTTP/2؛ فللاستفادة من تعدد الإرسال استخدم httpx مع الخيار http2=True:
# http2_solver.py
import os
import time
import httpx
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
BASE_URL = "https://ocr.captchaai.com"
# HTTP/2 client with connection pooling
client = httpx.Client(http2=True, timeout=30.0)
def solve_captcha(sitekey, pageurl):
"""Solve using HTTP/2 multiplexed connections."""
resp = client.get(f"{BASE_URL}/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
time.sleep(15)
for _ in range(25):
poll = client.get(f"{BASE_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Multiple solves over a single HTTP/2 connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
client.close()
يوجّه هذا العميل كل الطلبات عبر اتصال HTTP/2 واحد يحمل تدفقات متعددة، وهو ما يفيد عند الحل المتوازي. وتذكّر استدعاء client.close() عند الانتهاء.
JavaScript: مثيل Axios مع Keep-Alive
في بيئة Node.js لا يفعّل Axios إبقاء الاتصال مفتوحاً افتراضياً؛ عليك تمرير وكيل (agent) عبر http.Agent وhttps.Agent مع الخيار keepAlive: true، ويحدّد maxSockets عدد الاتصالات المتزامنة في التجمّع:
// keepalive_solver.js
const axios = require('axios');
const http = require('http');
const https = require('https');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
// Create agents with keep-alive enabled
const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });
const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });
// Axios instance with persistent connections
const api = axios.create({
baseURL: 'https://ocr.captchaai.com',
httpAgent,
httpsAgent,
timeout: 30000,
});
async function solveCaptcha(sitekey, pageurl) {
// Submit — reuses connection
const submit = await api.get('/in.php', {
params: {
key: API_KEY, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) throw new Error(submit.data.request);
const taskId = submit.data.request;
// Poll — reuses same connection
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await api.get('/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
});
if (poll.data.status === 1) return poll.data.request;
if (poll.data.request !== 'CAPCHA_NOT_READY') throw new Error(poll.data.request);
await new Promise(r => setTimeout(r, 5000));
}
throw new Error('Timeout');
}
(async () => {
for (let i = 0; i < 5; i++) {
const token = await solveCaptcha(
'6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'https://www.google.com/recaptcha/api2/demo'
);
console.log(`Solve ${i + 1}: ${token.slice(0, 30)}...`);
}
// Clean up agents
httpAgent.destroy();
httpsAgent.destroy();
})();
لا تنسَ استدعاء httpAgent.destroy() وhttpsAgent.destroy() عند إغلاق التطبيق حتى لا تبقى اتصالات معلّقة.
استكشاف الأخطاء وإصلاحها
| المشكلة | السبب المحتمل | الحل |
|---|---|---|
| الاتصال يُغلق بين الاستطلاعات | مهلة انتهاء عند الخادم أو الخادم الوسيط | ارفع مهلة keep-alive إلى أكثر من 30 ثانية في إعداد العميل |
| لا تحسّن ملحوظ في الأداء | المكتبة تستخدم إبقاء الاتصال مفتوحاً أصلاً بشكل افتراضي | تحقّق عبر أدوات مراقبة الشبكة من إعادة استخدام الاتصال فعلاً |
| أخطاء "connection refused" | استُنفد تجمّع الاتصالات | ارفع قيمة maxSockets أو خفّض مستوى التزامن |
| لم يُتفاوض على HTTP/2 | الخادم أو الوسيط لا يدعم h2 | ارجع إلى إبقاء الاتصال مفتوحاً عبر HTTP/1.1 |
HTTP/2 مقابل HTTP/1.1 في حل اختبار CAPTCHA
القيم في الجدول تقديرية وتعتمد على بيئة التشغيل؛ استخدمها للمقارنة النسبية بين الخيارين لا كأرقام مطلقة.
| الميزة | HTTP/1.1 مع Keep-Alive | HTTP/2 |
|---|---|---|
| إعادة استخدام الاتصال | نعم (تسلسلي) | نعم (متعدد الإرسال) |
| التدفقات المتزامنة | تدفق واحد لكل اتصال | حتى 100+ لكل اتصال |
| ضغط الترويسات | لا | ضغط HPACK |
| خفض زمن الاستجابة | ~60% | ~70% |
| يتطلب دعم المتصفح | لا | لا (مكالمات API) |
| الأنسب لـ | الحل المتسلسل | الحل المتوازي |
للحل المتسلسل — اختبار CAPTCHA واحد في كل مرة — يكفي إبقاء الاتصال مفتوحاً عبر HTTP/1.1. أما للحل المتوازي، فيمنحك تعدد الإرسال في HTTP/2 ميزة إضافية لأنه يشارك اتصالاً واحداً بين كل التدفقات بدل فتح اتصال لكل عملية.
كيف تحدّد حجم تجمّع الاتصالات؟
طابِق حجم التجمّع مع مستوى التزامن لديك؛ فلا فائدة من اتصالات أكثر مما تستخدمه فعلاً:
نصيحة: ابدأ بحجم تجمّع مساوٍ لأعلى تزامن متوقع، ثم اضبطه بالقياس لا بالتخمين.
| العمليات المتزامنة | حجم التجمّع الموصى به |
|---|---|
| 1–5 | 5 اتصالات |
| 5–20 | 10 اتصالات |
| 20–50 | 25 اتصالاً |
| 50–100 | 50 اتصالاً |
| 100+ | استخدم HTTP/2 (اتصال واحد) |
التجمّع الأكبر من اللازم يهدر الذاكرة، والأصغر من اللازم يجبر العميل على فتح اتصالات جديدة فيلغي فائدة إبقاء الاتصال مفتوحاً. وعند تجاوز 100 عملية متزامنة، انتقل إلى HTTP/2 واكتفِ باتصال واحد.
الأسئلة الشائعة
كم يبلغ التوفير الفعلي في زمن الاستجابة عند تفعيل Keep-Alive؟
في مثالنا يقارب التوفير 580 مللي ثانية لكل عملية حل reCAPTCHA v2، لأن الاتصال الأول وحده يدفع تكلفة مصافحة TCP وTLS. والقاعدة ثابتة: كلما زاد عدد الطلبات لكل جلسة، زاد ما توفّره.
هل يؤثر إبقاء الاتصال مفتوحاً على تكلفتي في CaptchaAI؟
لا. يحتسب CaptchaAI الفاتورة على أساس عدد الـ Threads المتزامنة لا على عدد طلبات HTTP، وكل خطة تشمل عمليات حل غير محدودة لكل Thread. لذا فإن Keep-Alive يسرّع كل عملية دون أن يزيد أو ينقص ما تدفعه.
كيف أتأكد أن مكتبتي تعيد استخدام الاتصال فعلاً؟
راقب حركة الشبكة عبر أدوات المراقبة أو سجلّات العميل، وتحقّق من عدم تكرار مصافحة TLS مع كل طلب. كما يكشف الأمر curl --http2 https://ocr.captchaai.com/res.php ما إذا كان الخادم يتفاوض على h2.
هل يعمل Keep-Alive عبر خادم وسيط أو بروكسي؟
نعم، شرط أن يدعم الخادم الوسيط نفسه الاتصالات المستمرة. فبعض وكلاء SOCKS5 لا يحافظون على الاتصال مفتوحاً فتضيع الفائدة؛ تحقّق من إعدادات البروكسي قبل الإنتاج.
متى أنتقل من HTTP/1.1 إلى HTTP/2؟
عندما تبدأ الحل المتوازي. فمع الحل المتسلسل يكفي إبقاء الاتصال مفتوحاً عبر HTTP/1.1، أما عند إرسال عشرات العمليات في وقت واحد فإن تعدد الإرسال في HTTP/2 يشارك اتصالاً واحداً بين كل التدفقات.
الخطوات التالية
- ابدأ سريعاً: حلّ أول اختبار CAPTCHA خلال خمس دقائق
- حل reCAPTCHA v2 عبر الـ API خطوة بخطوة
- حل Cloudflare Turnstile عبر الـ API
- حل GeeTest v3 عبر الـ API