توقّف السكربت عند رمز 403 أو 503، وظهرت صفحة تحدي Cloudflare بدل المحتوى الذي تريده؟ المفتاح الوحيد الذي يفتح الطريق هو كوكي واحد اسمه cf_clearance: بمجرد أن يحصل عليه العميل، تعبر الطلبات التالية دون اعتراض حتى تنتهي صلاحيته. لكنه ليس كوكي عادياً يُنسخ ويُلصق أينما شئت؛ فهو مقيّد بعنوان IP الذي وُلّد منه، وبوكيل المستخدم نفسه، وبمهلة قصيرة قد لا تتجاوز الدقائق في بعض المواقع.
في هذا الدليل نفكّك تدفق تحدي Cloudflare من لحظة الحجب حتى منح الكوكي، ونوضّح لماذا يُرفض cf_clearance أحياناً رغم صحّته، ثم نُظهر كيف تحصل عليه وتعيد استخدامه وتجدّده برمجياً عبر CaptchaAI.
لماذا تصطدم بجدار Cloudflare أصلاً
قبل أن يظهر الكوكي، يمرّ طلبك بسلسلة قرارات على حافة شبكة Cloudflare. فهم هذه السلسلة يوضّح أين ولماذا يُفرض التحدي، ولماذا تُحجب طلبات الأتمتة أكثر من متصفح عادي على اتصال منزلي نظيف:
- يطلب العميل صفحة محمية بواسطة Cloudflare.
- تقيّم Cloudflare إشارات المخاطر: سمعة عنوان IP، والعناوين المرسلة، وبصمة TLS.
- إذا وُضعت علامة على الزائر، تُرجع Cloudflare رمز 403 أو 503 مصحوباً بصفحة تحدي تعتمد على JavaScript.
- تُجري صفحة التحدي فحوصات على المتصفح، وقد تعرض أداة Turnstile.
- عند النجاح، تضع Cloudflare الكوكي
cf_clearanceوتعيد التوجيه إلى عنوان URL الأصلي. - تمرّ الطلبات اللاحقة الحاملة للكوكي دون اعتراض حتى تنتهي صلاحيته.
الخلاصة أن التحدي ليس ثابتاً لكل زائر، بل ردّ فعل على درجة خطورة تُحسب لحظياً؛ ولهذا قد تعبر أحياناً بلا احتكاك وتُحجب في مرة تالية من العنوان نفسه.
مستويات تحدي Cloudflare الثلاثة
لا تعرض Cloudflare نوعاً واحداً من التحدي، بل تختار مستوى الصرامة بحسب تقييمها للطلب. معرفة النوع الذي تواجهه تختصر عليك اختيار طريقة الحل المناسبة:
| التحدي | رمز الاستجابة | تفاعل المستخدم | الوصف |
|---|---|---|---|
| JS Challenge | 503 | لا شيء | تنفيذ JavaScript فقط |
| التحدي المُدار (Managed) | 403 | ربما | تقرّر Cloudflare — قد تعرض Turnstile أو تمرّ بصمت |
| التحدي التفاعلي | 403 | نعم | يعرض دائماً أداة Turnstile |
تحلّ CaptchaAI الأنواع الثلاثة عبر حلّ Cloudflare Challenge، سواء اقتصر التحدي على تنفيذ JavaScript أو تطلّب التفاعل مع أداة Turnstile، فتوفّر عليك بناء منطق منفصل لكل مستوى.
ما هو كوكي cf_clearance ولماذا يصعب نسخه
عندما تُحلّ صفحة التحدي بنجاح، يضع المتصفح كوكي باسم cf_clearance يُثبت للخادم أن هذه الجلسة اجتازت الفحص. هو ليس رمز دخول إلى حسابك على الموقع، بل شهادة على مستوى الحماية تقول لـ Cloudflare: «هذا الزائر تحقّقنا منه، دعه يمر».
خصائصه الأساسية كالتالي:
| الخاصية | التفاصيل |
|---|---|
| الاسم | cf_clearance |
| النطاق | نطاق الموقع المستهدف (على سبيل المثال .example.com) |
| المسار | / |
| مدة الصلاحية | عادة من 30 دقيقة إلى 24 ساعة |
| HttpOnly | نعم |
| Secure | نعم (عبر HTTPS فقط) |
| SameSite | None |
المشكلة أن الكوكي ليس محمولاً بالكامل؛ فهو مرتبط بعوامل تجعل نقله إلى بيئة أخرى محفوفاً بالفشل:
- عنوان IP — تربط Cloudflare الكوكي غالباً بعنوان IP الذي حلّ التحدي، فاستخدامه من عنوان مختلف يفشل عادةً.
- وكيل المستخدم (User-Agent) — يجب أن تطابق سلسلة UA في طلباتك اللاحقة السلسلة نفسها التي استُخدمت أثناء الحل.
- بصمة TLS — تربط بعض التكوينات الكوكي ببصمة TLS ClientHello للعميل.
القاعدة الذهبية: اجعل مصدر الحل ومصدر الطلبات اللاحقة متطابقين في عنوان IP ووكيل المستخدم، وإلا صار الكوكي الصالح بلا قيمة.
حل تحدي Cloudflare عبر CaptchaAI
النمط العملي بسيط: أرسل مهمة التحدي إلى نقطة النهاية in.php، ثم استطلع النتيجة دورياً من res.php حتى يعود الرمز. لاحظ أن الحقل الذي يحمل رمز الحل هو cf-turnstile-response لأن طبقة التحدي تعتمد على Turnstile.
الحل عبر Python
import requests
import time
API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://example.com/protected-page"
# Submit Cloudflare Challenge task
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "0x0000000000000000000000", # may be generic for CF challenge
"pageurl": TARGET_URL,
"json": "1",
}).json()
if resp["status"] != 1:
raise Exception(f"Submit error: {resp['request']}")
task_id = resp["request"]
print(f"Task ID: {task_id}")
# Poll for result
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": "1"
}).json()
if result["status"] == 1:
token = result["request"]
print(f"Token received: {token[:50]}...")
break
if result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Error: {result['request']}")
الحل عبر JavaScript
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
const TARGET_URL = 'https://example.com/protected-page';
const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
params: {
key: API_KEY,
method: 'turnstile',
sitekey: '0x0000000000000000000000',
pageurl: TARGET_URL,
json: 1,
}
});
const taskId = submit.data.request;
// Poll
let token = null;
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 5000));
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: 1 }
});
if (poll.data.status === 1) {
token = poll.data.request;
break;
}
}
console.log(`Token: ${token.substring(0, 50)}...`);
من الرمز إلى الكوكي: الحقن ثم الاستخراج
الرمز الذي أعادته الخدمة ليس هو cf_clearance بعد؛ بل هو إجابة Turnstile التي تُقدّمها لصفحة التحدي كي تمنحك الكوكي. لذلك تحقن الرمز في الحقل المخصص ثم ترسل النموذج، وبعد إعادة التوجيه تستخرج cf_clearance من الجلسة:
# With Selenium
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(TARGET_URL) # Load the challenge page
# Inject token into Turnstile response field
driver.execute_script("""
const input = document.querySelector('input[name="cf-turnstile-response"]');
if (input) input.value = arguments[0];
// Trigger form submit or callback
const form = document.querySelector('form');
if (form) form.submit();
""", token)
# Wait for redirect and extract cookies
import time
time.sleep(3)
cookies = driver.get_cookies()
cf_clearance = next(
(c for c in cookies if c['name'] == 'cf_clearance'), None
)
if cf_clearance:
print(f"cf_clearance: {cf_clearance['value'][:30]}...")
إعادة استخدام الكوكي داخل جلسة خفيفة
بمجرد امتلاك قيمة صالحة لـ cf_clearance، لا تحتاج متصفحاً كاملاً لكل طلب. مرّر الكوكي مع وكيل المستخدم نفسه داخل جلسة requests خفيفة، ثم اطلب الصفحات المحمية مباشرة:
session = requests.Session()
session.cookies.set("cf_clearance", cf_clearance["value"], domain=".example.com")
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
# Now access protected pages
resp = session.get("https://example.com/api/data")
print(resp.status_code) # 200
هذا النمط يقلّل الكلفة الحسابية بوضوح: تحلّ التحدي مرة واحدة عبر المتصفح، ثم تجني مئات الطلبات السريعة من كوكي واحد صالح.
إبقاء الكوكي حياً: التجديد الاستباقي
الكوكي مؤقت بطبعه، وقد تُقصّر بعض المواقع مدته إلى دقائق. بدل انتظار فشل الطلب برمز 403، افحص حقل expiry مسبقاً وأعد الحل قبل انتهاء الصلاحية بهامش أمان صغير:
import datetime
def is_cookie_valid(cookie):
if not cookie:
return False
expiry = cookie.get("expiry", 0)
return datetime.datetime.now().timestamp() < expiry - 60 # 60s buffer
def get_or_refresh_clearance(driver, target_url, solve_func):
cookies = driver.get_cookies()
cf = next((c for c in cookies if c["name"] == "cf_clearance"), None)
if is_cookie_valid(cf):
return cf["value"]
# Re-solve
token = solve_func(target_url)
# ... inject and extract new cookie
دالة تجديد استباقية بهذا الشكل تمنع الانقطاعات في التشغيل الطويل دون تدخل يدوي.
سيناريو عملي: مراقبة أسعار متجر إقليمي خلف Cloudflare
تخيّل فريقاً في القاهرة أو الرياض يبني أداة لمتابعة الأسعار على متجر إلكتروني إقليمي محمي بـ Cloudflare. المشكلة المتكررة أن الكوكي cf_clearance يُحلّ من خادم سحابي في أوروبا، بينما تصدر طلبات الجمع من عنوان IP آخر، فتُرفض بعد أول أو ثاني طلب. الحل ليس رفع عدد المحاولات، بل توحيد المصدر: استخدم الوكيل السكني نفسه — ويُفضّل أن يكون داخل النطاق الجغرافي للموقع — في مرحلتي الحل والجمع معاً، وثبّت وكيل المستخدم عبر الجلستين.
بهذا الترتيب يبقى الكوكي متسقاً مع بصمة الشبكة التي وُلّد منها، فتنخفض نسبة الرفض بشكل ملموس. ولأن CaptchaAI تعتمد التسعير القائم على عدد الـ Threads المتزامنة لا على عدد عمليات الحل، يمكن للفريق البدء من خطة BASIC ($15 شهرياً، 5 Threads) وحلّ عدد غير محدود من التحديات ضمن ذلك الحد، ثم الترقية إلى STANDARD ($30 شهرياً، 15 Thread) عند الحاجة إلى تزامن أعلى.
معالجة الأخطاء الشائعة
معظم حالات فشل cf_clearance تعود إلى عدم تطابق بين بيئة الحل وبيئة الطلب. يلخّص الجدول التالي الأعراض وأسبابها والإصلاح المباشر لكل منها:
| مشكلة | السبب | الإصلاح |
|---|---|---|
| رُفض الكوكي بعد الحل | عدم تطابق عنوان IP | استخدم الوكيل نفسه للحل وللطلبات |
| تنتهي صلاحية الكوكي بسرعة | TTL قصير يضبطه الموقع | أعد الحل قبل انتهاء الصلاحية وافحص حقل expiry |
| رمز 403 رغم صلاحية الكوكي | عدم تطابق وكيل المستخدم | طابق UA بين جلستي الحل والطلب |
| صفحة التحدي لا تُحمّل | JavaScript معطّل | استخدم متصفحاً كاملاً مثل Selenium أو Puppeteer |
الأسئلة الشائعة
هل تكفي مكتبة requests وحدها للحصول على cf_clearance أول مرة؟
لا؛ الحصول على الكوكي أول مرة يتطلب متصفحاً كاملاً مثل Selenium أو Puppeteer، لأن صفحة التحدي تنفّذ JavaScript ولا تكتفي مكتبة requests بذلك. بعد استخراج الكوكي، يمكنك التحوّل إلى جلسة requests خفيفة لبقية الطلبات.
ما الفرق بين رمز Turnstile وكوكي cf_clearance؟
رمز Turnstile إجابة مؤقتة تقدّمها لصفحة التحدي لإثبات اجتيازك، بينما cf_clearance هو الكوكي الناتج الذي يمنحك المرور طوال صلاحيته. الأول وسيلة تُستهلك مرة واحدة، والثاني النتيجة التي تعيد استخدامها في طلبات متعددة.
هل تغطّي CaptchaAI مستويات تحدي Cloudflare الثلاثة كلها؟
نعم؛ يشمل حلّ Cloudflare Challenge في CaptchaAI الأنواع الثلاثة — JS Challenge والمُدار والتفاعلي — إضافة إلى Cloudflare Turnstile، وكلاهما ضمن الأنواع المتاحة بشكل كامل.
لماذا يظهر رمز 403 رغم أن الكوكي ما زال صالحاً؟
الغالب أن السبب اختلاف وكيل المستخدم بين جلسة الحل وجلسة الطلب. تفحص Cloudflare تطابق UA مع بصمة الجلسة التي مُنح فيها الكوكي، فأي تغيير في السلسلة قد يُبطل التصريح رغم أن مدة الصلاحية لم تنته بعد.
كم تبلغ تكلفة حل تحديات Cloudflare عبر CaptchaAI؟
تعتمد CaptchaAI تسعيراً قائماً على عدد الـ Threads المتزامنة مع عمليات حل غير محدودة داخل كل خطة، بدءاً من BASIC ($15 شهرياً، 5 Threads). لا توجد رسوم لكل عملية حل، ما يجعل التكلفة قابلة للتوقّع في الأحمال الكبيرة.
ابدأ حل Cloudflare Challenge مع CaptchaAI
أنشئ مفتاح API الخاص بك على captchaai.com وابدأ بحلّ صفحات التحدي واستخراج كوكي cf_clearance في دقائق.