هل ينبغي أن تحظر زواحف الذكاء الاصطناعي؟ قرّر حسب البوت ونفّذ حسب IP
احظر زواحف الذكاء الاصطناعي حسب وظيفتها: أوقف بوتات التدريب، وأبقِ بوتات البحث بالذكاء الاصطناعي، وأعد 403 لـ GPTBot المزيّف بفحص IP. تتضمن شيفرة nginx وExpress مُجرَّبة.

يعرض سجل الوصول لديك GPTBot وClaudeBot وبضعة أسماء لا تعرفها. وكل الأدلة التي تجدها تقول الشيء نفسه: اذكر قيم User-Agent في robots.txt، ثم احظر السلاسل نفسها في إعدادات خادمك.
في هذه النصيحة ثغرة. User-Agent سلسلة يكتبها العميل، وكتابة "GPTBot" لا تكلّف شيئًا. وقائمة حظر الأسماء توقف البوتات الصادقة، التي كانت ستلتزم بـ robots.txt على أي حال، وتُمرّر كل كاشط يستعير اسمًا سمحت به. الاسم ادعاء وعنوان IP هو الدليل، وهو المبدأ نفسه في كشف البوتات بعنوان IP عمومًا.
نفرز أدناه البوتات حسب وظيفتها، ونعرض ما يستطيعه robots.txt وما لا يستطيعه، ونمرّر أربعة عناوين زواحف حقيقية عبر واجهتنا، ونقدّم لك سياسة من ثلاث طبقات مع شيفرة nginx وExpress مُجرَّبة. يحصل GPTBot المزيّف على 403. ولا يحصل Googlebot الحقيقي عليه أبدًا.

هل ينبغي أن تحظر زواحف الذكاء الاصطناعي؟ يتوقف ذلك على وظيفة البوت
ينبغي أن تحظر زواحف الذكاء الاصطناعي التي تعترض على وظيفتها وتُبقي تلك التي ترسل لك القرّاء. تؤدي بوتات الذكاء الاصطناعي ثلاث وظائف مختلفة، ويكلّفك حظر كل منها شيئًا مختلفًا.
- زواحف التدريب تجمع صفحات قد تُدرَّب بها نماذج مستقبلية. تقول OpenAI إن منع GPTBot "يشير إلى أن محتوى الموقع ينبغي ألا يُستخدم في تدريب نماذج الذكاء الاصطناعي التوليدي الأساسية". حظرها لا يكلّفك شيئًا في البحث.
- بوتات البحث بالذكاء الاصطناعي تفهرس الصفحات كي يستشهد بها مساعد. تقول OpenAI إن المواقع التي رفضت OAI-SearchBot "لن تظهر في إجابات بحث ChatGPT". حظرها يكلّفك الاستشهادات والنقرات الآتية منها.
- الجالبات التي يطلقها المستخدم تحمّل صفحة لأن شخصًا طلب من مساعد قراءتها. حظرها يُفشل طلب ذلك الشخص.
لدى ناشر خلف جدار دفع سبب واضح لرفض التدريب. والعلامة التي تريد أن توصي بها المساعدات ينبغي أن تُبقي بوتات البحث. وينتهي معظم المواقع إلى حل وسط: لا للتدريب، ونعم للبحث، وحد سرعة للجالبات. نتناول أي بوت من OpenAI تحظر وما يكلّفه كل اختيار في مقال منفصل. أما الوكلاء الذين يتسوقون نيابة عن مستخدم فمشكلة مختلفة، تناولناها في احتيال وكلاء التسوق بالذكاء الاصطناعي عند الدفع.
أي بوتات الذكاء الاصطناعي تدرّب وأيها تستشهد بك
يفرز هذا الجدول بوتات الذكاء الاصطناعي التي ستراها على الأرجح حسب الوظيفة، مع ما يقوله كل مشغّل عن robots.txt. كل خلية مأخوذة من صفحة المشغّل نفسه، فُتحت في 20 أكتوبر 2026.
| البوت | المشغّل | الوظيفة | robots.txt بكلمات المشغّل |
|---|---|---|---|
| GPTBot | OpenAI | تدريب | المنع يعني أن المحتوى "ينبغي ألا يُستخدم في التدريب" |
| OAI-SearchBot | OpenAI | بحث بالذكاء الاصطناعي | المواقع الرافضة لا تظهر في إجابات بحث ChatGPT |
| ChatGPT-User | OpenAI | جلب يطلقه المستخدم | قواعد robots.txt "قد لا تنطبق" |
| ClaudeBot | Anthropic | تدريب | يلتزم بـ robots.txt وCrawl-delay |
| Claude-SearchBot | Anthropic | بحث بالذكاء الاصطناعي | يلتزم بـ robots.txt وCrawl-delay |
| Claude-User | Anthropic | جلب يطلقه المستخدم | يلتزم بـ robots.txt وCrawl-delay |
| Google-Extended | رمز لاستخدام الذكاء الاصطناعي، دون زاحف | رمز robots.txt فقط، بلا User-Agent خاص به | |
| Googlebot | بحث، وليس بوت ذكاء اصطناعي ينبغي حظره | الزواحف الشائعة "تلتزم دائمًا بقواعد robots.txt عند الزحف آليًا" | |
| PerplexityBot | Perplexity | بحث بالذكاء الاصطناعي | غير مذكور؛ توصي Perplexity بالسماح به |
| Perplexity-User | Perplexity | جلب يطلقه المستخدم | "يتجاهل عمومًا قواعد robots.txt" |
| CCBot | Common Crawl | أرشيف ويب مفتوح يستطيع أي أحد تنزيله | يفحص robots.txt أولًا؛ يلتزم بـ Crawl-delay |
| Applebot-Extended | Apple | رمز لاستخدام التدريب بالذكاء الاصطناعي، دون زاحف | تقول Apple إنه "لا يزحف إلى صفحات الويب" |
| Meta-ExternalAgent | Meta | تدريب وفهرسة | غير مذكور؛ توثّق Meta قاعدة Disallow له |
| Bytespider | ByteDance | غير موثّق في صفحة استطعنا فتحها | غير موثّق في صفحة استطعنا فتحها |
الإثبات مسألة منفصلة عن السياسة. لا يمكن التحقق من بوت إلا إذا نشر مشغّله العناوين التي يزحف منها:
| المشغّل | ملف النطاقات | البادئات في 20 أكتوبر 2026 | DNS العكسي موثّق | تتحقق منه GeoIPHub |
|---|---|---|---|---|
| OpenAI | gptbot.json، إضافةً إلى searchbot.json وchatgpt-user.json | 18 و39 و234 | غير موثّق | نعم، الثلاثة جميعًا |
| Anthropic | bots.json، ملف واحد للبوتات الثلاثة | 38 (الملف مؤرخ 7 أكتوبر 2026) | غير موثّق | نعم، وتُسمّى المطابقة ClaudeBot |
| common-crawlers.json وأربعة ملفات أخرى | 317 في الزواحف الشائعة | نعم: googlebot.com وgoogle.com وgoogleusercontent.com | نعم | |
| Perplexity | perplexitybot.json وperplexity-user.json | 8 و4 | غير موثّق | نعم |
| Common Crawl | ccbot.json | 5 | نعم، crawl.commoncrawl.org، IPv4 فقط | نعم |
| Apple | applebot.json | 24 | نعم، applebot.apple.com | نعم، لـ Applebot |
| Meta | غير منشور | غير منشورة | غير موثّق | مطابقة ASN فقط، verified: false |
| ByteDance | لم نجد أيًّا منها | لا شيء | غير موثّق | لا |
قبل أن تنسخ قائمة من موقع آخر، تحقق من أسمائها. ما تزال بعض الأدلة التي تتصدر نتائج هذا الموضوع تذكر anthropic-ai وClaude-Web، اللذين لا تدرجهما صفحة Anthropic الحالية، وتغفل Claude-SearchBot وClaude-User. القائمة القديمة تحظر سلاسل لا يرسلها أحد.
ما يستطيعه robots.txt وما لا يستطيعه
يستطيع robots.txt إخبار البوتات المنضبطة بما تريد، ولا يستطيع إيقاف أي شيء. يقول RFC 9309، المعيار الذي يعرّفه: "هذه القواعد ليست شكلًا من أشكال تفويض الوصول." أما هل لتجاهله عواقب قانونية فسؤال للمحامي.
وهو مع ذلك الطبقة الأولى، لأن معظم البوتات المسماة تقرؤه. يرفض هذا الملف التدريب، ويرحّب بالبحث بالذكاء الاصطناعي، ويترك بحث Google وشأنه:
# Training: no
User-agent: GPTBot
User-agent: ClaudeBot
User-agent: CCBot
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: Meta-ExternalAgent
User-agent: Bytespider
Disallow: /
# AI search: yes
User-agent: OAI-SearchBot
User-agent: PerplexityBot
Allow: /
# Anthropic honours Crawl-delay (seconds between requests)
User-agent: Claude-SearchBot
Allow: /
Crawl-delay: 2
أربعة تفاصيل تحدد ما إذا كان هذا الملف يفعل ما تظن:
- Google-Extended وApplebot-Extended رموز لا زواحف. تقول صفحة الزواحف الشائعة لدى Google، المحدّثة في 15 أكتوبر 2026، إن "Google-Extended ليس له سلسلة وكيل مستخدم HTTP منفصلة" وإنه "لا يؤثر في إدراج الموقع في بحث Google". لا يصل أي طلب من Google-Extended، فلا تستطيع أي قاعدة IP حظره. وتقول صفحة Applebot لدى Apple إن Applebot-Extended "لا يزحف إلى صفحات الويب" كذلك.
- حظر Googlebot لمنع استخدام الذكاء الاصطناعي يكلّفك البحث. وكذلك مجموعة
User-agent: *معDisallow: /. - الجالبات التي يطلقها المستخدم قد تتجاهل الملف. تقول OpenAI عن ChatGPT-User إن "قواعد robots.txt قد لا تنطبق". وتقول Perplexity إن Perplexity-User "يتجاهل عمومًا قواعد robots.txt".
- التغييرات ليست فورية. تقول OpenAI: "قد يستغرق الأمر نحو 24 ساعة من تحديث robots.txt في موقع ما حتى تتكيّف أنظمتنا".
الملفات الأحدث مثل llms.txt وai.txt مجرد مقترحات. وهي، مثل robots.txt، تطلب ولا تُنفّذ.
والخطأ المعاكس هو وضع زواحف البحث في قائمة حظر "بوتات الذكاء الاصطناعي". يعرض دليل Contentstack لحظر زواحف الذكاء الاصطناعي دالة طرفية تتضمن قائمة بوتاتها googlebot وbingbot بجانب gptbot وclaudebot، وترد على جميعها بـ "Forbidden: AI crawlers are not allowed." فإذا نُسخت القاعدة كما هي، أخرجت موقعًا من بحث Google وBing. ومن ينتحل Googlebot هو Googlebot مزيّف، وهي مشكلة مختلفة بحل مختلف.
زاحف حقيقي أم منتحل: كيف يعمل التحقق
تميّز الزاحف الحقيقي من المنتحل بمقارنة عنوان IP المتصل بما ينشره المشغّل المسمّى. وأي من ثلاث طرق تنجح يتوقف على المشغّل.
- ملفات النطاقات. تنشر OpenAI وAnthropic وPerplexity وCommon Crawl وApple وGoogle قوائم JSON ببادئاتها. وبالنسبة لـ OpenAI وAnthropic هي الطريقة الوحيدة، لأن عناوينها بلا DNS عكسي.
- DNS العكسي المؤكَّد أماميًا. يطلب منك دليل التحقق لدى Google أن تحلّ IP إلى اسم، وتفحص النطاق، ثم تحلّ الاسم مجددًا وتتأكد أنه يعيد IP نفسه. وتوثّق Apple وCommon Crawl الطريقة نفسها.
- الطلبات الموقّعة (Web Bot Auth). يوقّع البوت كل طلب بمفتاح منشور. وما زالت مسودة، نتناولها في قسم الحافة أدناه.
يتناول دليلنا حول التحقق من زاحف ذكاء اصطناعي عبر IP الطرق الثلاث بالتفصيل. فحصنا أربعة عناوين زواحف في الساعة 04:37 UTC من 20 أكتوبر 2026، بلا مفتاح. وهذا عنوان ClaudeBot مقتطعًا، مع الحفاظ على التداخل ودون تعديل القيم:
{
"ip": "216.73.216.10",
"asn": {
"asn": 16509,
"org": "AMAZON-02 - Amazon.com, Inc."
},
"threat": {
"is_crawler": true,
"crawler": {
"verified": true,
"name": "ClaudeBot",
"operator": "Anthropic",
"category": "ai",
"verification_method": "ip_range_list"
}
},
"scoring": {
"fraud_score": 0,
"recommended_action": "allow",
"detection_methods": ["datacenter_ip", "no_ptr_datacenter", "verified_crawler"]
}
}
العناوين الثلاثة الأخرى من التشغيل نفسه:
| IP | crawler.name / المشغّل / الفئة | موثَّق، الطريقة | الدرجة، الإجراء | detection_methods | ASN |
|---|---|---|---|---|---|
| 132.196.86.1 | GPTBot / OpenAI / ai | true, ip_range_list | 0, allow | datacenter_ip, no_ptr_datacenter, verified_crawler | 8075 MICROSOFT-CORP-MSN-AS-BLOCK |
| 66.249.66.1 | Googlebot / Google / search_engine | true, ip_range_list | 0, allow | datacenter_ip, verified_crawler | 15169 GOOGLE |
| 107.178.192.1 | GoogleUserTriggeredFetcher / Google / fetcher | true, ip_range_list | 0, allow | datacenter_ip, rdns_hosting, verified_crawler | 396982 GOOGLE-CLOUD-PLATFORM |
عنوان GPTBot هو المضيف الأول في 132.196.86.0/24، وهي أول بادئة في gptbot.json لدى OpenAI. ثم سألنا DNS عن الأسماء، في الساعة 04:45 UTC:
$ dig -x 216.73.216.10 +short # ClaudeBot: NXDOMAIN, no name
$ dig -x 132.196.86.1 +short # GPTBot: NXDOMAIN, no name
$ dig -x 66.249.66.1 +short
crawl-66-249-66-1.googlebot.com.
$ dig crawl-66-249-66-1.googlebot.com +short
66.249.66.1
هذه هي النتيجة التي تفوّتها معظم الأدلة. ClaudeBot وGPTBot بلا سجل PTR، فلا يستطيع DNS العكسي التحقق منهما. ملف النطاقات هو الفحص الوحيد. تنطلق no_ptr_datacenter في الاثنين، ومع ذلك تبقى الدرجة 0، لأن verified_crawler إشارة تبرئة. وغياب PTR أمر طبيعي لدى هذين المشغّلين. أما Googlebot فيجتاز الاتجاهين: يعود اسمه فيُحل إلى العنوان نفسه.
وينطبق قيدان. يقول الحقل category "ai" لبوتات الذكاء الاصطناعي التدريبية وغير التدريبية على حد سواء، فينبغي أن تعتمد شيفرة السياسة على crawler.name. ويرى الاستعلام عنوان IP فقط، ولا يرى User-Agent أبدًا، فلا تُعلّم الواجهة أي انتحال. مقارنة الاسم المدّعى بالاسم المُثبَت تجري في شيفرتك. ويمكنك إجراء الفحص نفسه يدويًا في أداة استعلام IP لدينا.
سياسة من ثلاث طبقات: اطلب، تحقق، قيّد
السياسة التي تصمد لها ثلاث طبقات: اطلب عبر robots.txt، وتحقق من كل ادعاء بوت مقابل IP الخاص به، وحدّد معدّل كل ما تبقى. احظر حسب الوظيفة، ونفّذ حسب IP، ولا تضع Googlebot في قائمة حظر الذكاء الاصطناعي أبدًا.
الطبقة 1: اطلب. يحمل robots.txt قرارك لكل بوت، إضافةً إلى Crawl-delay للمشغّلين الذين يلتزمون به.
الطبقة 2: تحقق. حين يسمّي User-Agent بوتًا، استعلم عن عنوان IP المتصل وقارن الأسماء. إذا لم يكن IP تابعًا لذلك البوت، يحصل الطلب على 403. وإذا كان تابعًا له، طبّق قرار الطبقة 1، فيُرفض GPTBot الموثَّق الذي يتجاهل Disallow لديك.
الطبقة 3: قيّد. يحصل كل ما سواه على حد معدّل: طلبات لا تدّعي أي بوت، وبوتات لا يمكن التحقق منها، وجالبات تعمل نيابة عن شخص.
| الحالة | مثال | الإجراء |
|---|---|---|
| بوت موثَّق تسمح به | Googlebot من 66.249.66.1 | قدّم الصفحة عادةً، دون حد معدّل |
| بوت موثَّق رفضته ويستمر بالوصول | GPTBot من 132.196.86.1 مع منع GPTBot | 403 |
| ادعاء غير موثَّق: UA يسمّي بوتًا وIP لا يطابقه | UA الخاص بـ GPTBot من 216.73.216.10، وهو عنوان لدى Anthropic | 403، أو تحدٍّ إن فضّلت |
| بوت لا يمكن التحقق منه | Bytespider وMeta-ExternalAgent | حدّد المعدّل؛ robots.txt وسيلتك الوحيدة |
| لا ادعاء بوت | المتصفحات، والكاشطات التي تتنكر في هيئة متصفحات | حدّد المعدّل لكل IP |
الصف الثالث هو الأكثر تعليمًا. 216.73.216.10 زاحف موثَّق، لكنه ليس الزاحف الذي يسمّيه الطلب، فالفحص الذي يسأل فقط "هل هذا زاحف موثَّق؟" كان سيسمح له بالمرور. قارن الأسماء. وبالمثل، 107.178.192.1 جالب موثَّق لدى Google، لكن طلبًا منه يدّعي أنه Googlebot ليس Googlebot.
سجّل كل إخفاق في الطبقة 2. عنوان خارج النطاقات المنشورة يعني غالبًا انتحالًا، لكنه قد يكون بادئة أضافها المشغّل للتو. تُعاد جلب ملفات النطاقات لدينا يوميًا وتُعاد بناء قاعدة بيانات الاستعلام يوميًا، فقد تستغرق بادئة جديدة نحو يومين حتى يمكن التحقق منها.
نفّذها في nginx وExpress، مع اختبار GPTBot المنتحَل
التنفيذ خدمة Express صغيرة واحدة تجري الاستعلام، إضافةً إلى إعداد nginx يسألها عن كل طلب يدّعي أنه بوت. لا يستطيع nginx القياسي استدعاء HTTP API داخل المعالجة، لذلك تُرسل وحدة auth_request طلبًا فرعيًا إلى المتحقق ويخزّن nginx الجواب مؤقتًا. وبدون nginx، يحمي الملف نفسه تطبيق Express وحده.
يطابق المتحقق User-Agent مع رموز البوتات الحالية، ويستعلم عن IP بواسطة GET https://api.geoiphub.com/v1/lookup/{ip} وترويسة x-api-key، ويخزّن النتيجة ساعة، ويقارن threat.crawler.name بالاسم المدّعى. ويحتاج إلى خريطة أسماء لأن الواجهة تكتب بعض الأسماء دون الشرطة: OAISearchBot وChatGPTUser وPerplexityUser. راجع حقول الزواحف في وثائق API.
// bot-gate.js: tier 2 (verify the IP behind a bot claim) and tier 3 (rate-limit the rest).
// Tested with Node 24.20.0, Express 5.3.0 and express-rate-limit 8.7.1.
const express = require('express');
const { rateLimit } = require('express-rate-limit');
const { BlockList, isIP } = require('node:net');
const API_KEY = process.env.GEOIPHUB_KEY; // production: always set a key
const CACHE_MS = 60 * 60 * 1000; // one hour per IP
const cache = new Map(); // ip: { at, crawler }
// Your policy: User-Agent tokens you refuse even when verified. Everything verified and not listed passes.
const BLOCKED = new Set((process.env.BLOCKED_BOTS || 'GPTBot,ClaudeBot,CCBot').split(','));
// Maps each User-Agent token to the crawler.name our API returns for that operator's range file.
// Anthropic publishes one file for all three of its bots, so a match comes back as ClaudeBot.
const EXPECTED = {
'GPTBot': 'GPTBot',
'OAI-SearchBot': 'OAISearchBot',
'ChatGPT-User': 'ChatGPTUser',
'ClaudeBot': 'ClaudeBot',
'Claude-User': 'ClaudeBot',
'Claude-SearchBot': 'ClaudeBot',
'PerplexityBot': 'PerplexityBot',
'Perplexity-User': 'PerplexityUser',
'CCBot': 'CCBot',
'Googlebot': 'Googlebot',
'bingbot': 'Bingbot',
'Applebot': 'Applebot',
};
// Longest tokens first, so "Claude-SearchBot" is not read as a shorter token.
const TOKENS = Object.keys(EXPECTED).sort((a, b) => b.length - a.length);
// A real crawler never connects from a private or loopback address.
const privateNets = new BlockList();
for (const [net, bits] of [['10.0.0.0', 8], ['172.16.0.0', 12], ['192.168.0.0', 16],
['127.0.0.0', 8], ['100.64.0.0', 10]]) privateNets.addSubnet(net, bits, 'ipv4');
privateNets.addSubnet('fc00::', 7, 'ipv6');
privateNets.addAddress('::1', 'ipv6');
function claimedBot(ua = '') {
const lower = ua.toLowerCase();
return TOKENS.find((t) => lower.includes(t.toLowerCase())) || null;
}
async function lookupCrawler(ip) {
const hit = cache.get(ip);
if (hit && Date.now() - hit.at < CACHE_MS) return hit.crawler;
const res = await fetch(`https://api.geoiphub.com/v1/lookup/${ip}`, {
headers: API_KEY ? { 'x-api-key': API_KEY } : {}, // keyless only for a local test
signal: AbortSignal.timeout(1500),
});
if (!res.ok) throw new Error(`lookup ${res.status}`);
const data = await res.json();
cache.set(ip, { at: Date.now(), crawler: data.threat.crawler });
return data.threat.crawler;
}
async function verifyBot(req, res, next) {
const claim = claimedBot(req.get('user-agent'));
if (!claim) return next(); // no bot claim: tier 3 handles it
const ip = req.ip.replace(/^::ffff:/, '');
const family = isIP(ip) === 6 ? 'ipv6' : 'ipv4';
if (privateNets.check(ip, family)) {
return res.status(403).send(`unverified ${claim} claim\n`);
}
let crawler;
try {
crawler = await lookupCrawler(ip);
} catch (err) {
// Fail mode: never fail open to "verified". Mark it and let the rate limiter decide.
req.botUnverified = true;
return next();
}
// The API never flags a spoof: it sees only the IP, not the User-Agent.
// The spoof check is this comparison, in your code.
const verified = crawler.verified === true && crawler.name === EXPECTED[claim];
if (!verified) return res.status(403).send(`unverified ${claim} claim\n`);
if (BLOCKED.has(claim)) return res.status(403).send(`${claim} is blocked by policy\n`);
req.verifiedBot = crawler.name;
return next();
}
// Tier 3: everyone without a verified bot name, keyed per IPv4 address or per IPv6 /64.
// nginx auth_request understands only 2xx, 401 and 403, so the verifier endpoint answers 403.
const limiter = rateLimit({
windowMs: 60 * 1000,
limit: 120,
ipv6Subnet: 64,
skip: (req) => Boolean(req.verifiedBot),
handler: (req, res) => res.set('Cache-Control', 'no-store')
.status(req.path === '/_verify_bot' ? 403 : 429).send('rate limited\n'),
});
const app = express();
app.set('trust proxy', 'loopback'); // only nginx on this host may set X-Forwarded-For
// Endpoint for nginx auth_request: 204 lets the request through, 403 stops it.
// After a failed lookup, no-store keeps nginx from caching the 204, so the limiter sees every request.
app.get('/_verify_bot', verifyBot, limiter, (req, res) => {
if (req.botUnverified) res.set('Cache-Control', 'no-store');
res.sendStatus(204);
});
// Standalone use without nginx: protect every route.
app.use(verifyBot, limiter);
app.get('/', (req, res) => res.send('ok\n'));
app.listen(3000, '127.0.0.1');
ثلاثة خيارات مقصودة. إذا فشل الاستعلام أو استغرق أكثر من 1.5 ثانية، فلا يُعامل الطلب أبدًا كموثَّق؛ بل يمر إلى محدّد المعدّل. وخلف nginx يُرسل ذلك الجواب مع no-store، فلا يخزّنه nginx ويحتسب المتحقق كل طلب ضمن الحد نفسه. وتحمل قائمة السياسة رموز User-Agent، فمنع ClaudeBot لا يمنع Claude-SearchBot، مع أن الاثنين يعودان من الاستعلام باسم ClaudeBot. وtrust proxy على loopback فقط، وإلا استطاع العميل إرسال X-Forwarded-For خاص به واختيار العنوان الذي تفحصه. ولا يُستعلم إلا عن ادعاءات البوتات، فيتبع الحجم حركة البوتات لا مشاهدات الصفحات. وتغطي الخطة المجانية 1,500 استعلام يوميًا بمفتاح، مع تضمين كل الحقول.
يحوّل جانب nginx User-Agent إلى بوت مدّعى، ويتخطى الطلب الفرعي حين لا يوجد ادعاء، ويخزّن جواب المتحقق 204 أو 403 لكل عنوان وبوت ساعة، باستثناء الأجوبة الموسومة no-store:
# Goes in the http {} block. Tested with nginx 1.30.6 built with --with-http_auth_request_module.
# Which bot does the User-Agent claim? Empty means no claim.
map $http_user_agent $claimed_bot {
default "";
"~*(GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User|CCBot|Googlebot|bingbot|Applebot)" $1;
}
# Tier 3 key: rate-limit requests with no bot claim. Claims go to tier 2 instead.
map $claimed_bot $limit_key {
"" $binary_remote_addr;
default "";
}
limit_req_zone $limit_key zone=perip:10m rate=10r/s;
# Cache the verifier's answer per address and claimed bot for one hour.
proxy_cache_path /var/cache/nginx/botcheck keys_zone=botcheck:1m max_size=10m inactive=1h;
server {
listen 8080;
location / {
limit_req zone=perip burst=20 nodelay;
limit_req_status 429;
auth_request /_verify_bot;
proxy_pass http://127.0.0.1:8000; # your app
}
location = /_verify_bot {
internal;
if ($claimed_bot = "") { return 204; } # no claim: no lookup
proxy_pass http://127.0.0.1:3000; # bot-gate.js
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache botcheck;
proxy_cache_key $remote_addr$claimed_bot;
proxy_cache_valid 204 403 1h;
}
}
نجح nginx -t على هذا الإعداد، وشغّلناه أمام ملف Express في 20 أكتوبر 2026، في الساعة 05:05 UTC. أولًا اختبار GPTBot المنتحَل، عبر nginx، من الجهاز نفسه:
$ curl -s -o /dev/null -w "%{http_code}\n" \
-A "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot" \
http://localhost:8080/
403
$ curl -s -o /dev/null -w "%{http_code}\n" \
-A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36" \
http://localhost:8080/
200
سلسلة GPTBot تلك هي المثال الحالي في صفحة البوتات لدى OpenAI. من جهازك أنت يأتي الطلب من 127.0.0.1، الذي لا يستخدمه أي زاحف، فيرفضه المتحقق قبل أي استعلام. ولمشاهدة الاستعلام، استدعِ ملف Express مباشرة بالعنوان الذي كان nginx سيمرّره:
$ GPT='Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot'
$ GB='Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
$ curl -s -A "$GPT" -H "X-Forwarded-For: 216.73.216.10" http://127.0.0.1:3000/
unverified GPTBot claim
$ curl -s -A "$GPT" -H "X-Forwarded-For: 132.196.86.1" http://127.0.0.1:3000/
GPTBot is blocked by policy
$ curl -s -A "$GB" -H "X-Forwarded-For: 107.178.192.1" http://127.0.0.1:3000/
unverified Googlebot claim
$ curl -s -A "$GB" -H "X-Forwarded-For: 66.249.66.1" http://127.0.0.1:3000/
ok
تابع السطر الأول من البداية إلى النهاية. يدّعي User-Agent أنه GPTBot. يستعلم المتحقق عن 216.73.216.10، وتجيب الواجهة بزاحف موثَّق اسمه ClaudeBot. ClaudeBot ليس GPTBot، فيحصل الطلب على 403. أما عنوان GPTBot الحقيقي 132.196.86.1 فيجتاز التحقق ويُرفض فقط لأن هذه السياسة ترفض التدريب؛ ومع BLOCKED_BOTS=CCBot حصل على 200. وحصل ادعاء Claude-SearchBot من 216.73.216.10 على 200، لأن هذه السياسة ترفض رمز ClaudeBot لا بوت البحث لدى Anthropic. ونسخة اختبارية فقط من إعداد nginx مررت العناوين الأربعة نفسها أعادت 403 و403 و403 و200. ومع جعل الواجهة غير متاحة عمدًا، حصلت 130 ادعاءً بـ bingbot من عنوان واحد عبر nginx على 120 استجابة بحالة 200 ثم 403: انقطاع الخدمة يقيّد ادعاءات البوتات بدل تمريرها.
إذا اختبرت بلا مفتاح، فاجعله قصيرًا. الاستعلامات المجهولة محدودة في الدقيقة، والاستدعاء الثلاثون داخل نافذة 60 ثانية واحدة هو أصلًا 429 يحظر عنوانك ساعتين.
حدّد معدّل ما لا يمكنك التحقق منه بدل حظره
تحديد المعدّل هو الأداة المناسبة للحركة التي لا تستطيع إثباتها في أي اتجاه: البوتات التي لا يمكن التحقق منها، والجالبات التي يطلقها المستخدم، وكل ما لا يدّعي أي بوت. لمعرفة أي البوتات تنشر ملفات نطاقات وأيها لا تنشر، راجع قائمتنا ملفًا بملف. يوقف الحد كاشطًا ينسخ موقعك في عصر واحد دون إقصاء الأشخاص خلف جالب.
كلا المقتطفين يفعلان ذلك أصلًا. يعتمد limit_req في nginx على عنوان العميل للطلبات التي لا تدّعي أي بوت، بمعدل 10 في الثانية مع دفعة 20. في اختبارنا، أعادت 40 طلبًا متتاليًا 25 نجاحًا و15 استجابة بحالة 429. اضبط الأرقام، واستثنِ الأصول الثابتة إن كان تحميل صفحة واحدة يجلب العشرات. ويعتمد محدّد Express لعملاء IPv6 على /64 الخاص بهم، لأن مشتركًا واحدًا يتحكم عادةً في /64 كاملة؛ راجع تحديد معدّل IPv6 بالبادئة /64 لمعرفة متى توسّع إلى /56 أو /48.
Crawl-delay هو النسخة المهذبة للبوتات التي تلتزم به. تقول صفحة مساعدة الزواحف لدى Anthropic: "ندعم امتداد Crawl-delay غير القياسي في robots.txt"، وتقول الأسئلة الشائعة لدى Common Crawl: "نلتزم بمعامل Crawl-delay". وغيرها لا يفعل. تقول مواصفة robots.txt لدى Google إن حقولًا "مثل crawl-delay غير مدعومة"، وتقول Apple: "لا يتبع Applebot crawl-delay". ولا تذكره صفحتا OpenAI وPerplexity.
لا تلتقط الطبقة 2 إلا الطلبات التي تسمّي بوتًا. ولحظر كاشطات الذكاء الاصطناعي التي لا تدّعي أنها بوتات أبدًا، أضف السلوك إلى الطبقة 3: معدلات الطلبات، والمسارات، والشبكة التي يأتي منها الطلب. يتناول مقالنا حول كشف كشط الويب من سجلاتك تلك الإشارات.
خيارات الحافة: حظر الذكاء الاصطناعي من Cloudflare والدفع لكل زحف
خلف Cloudflare، يمكنك حظر زواحف الذكاء الاصطناعي بإعداد بدل الشيفرة، أو تحصيل مقابل لكل طلب. ولا يغني أي منهما عن معرفة البوتات التي تتعامل معها.
أعلنت Cloudflare في 1 يوليو 2025، في مقال عُدّل آخر مرة في 15 يوليو 2026، أنها "تغيّر الإعداد الافتراضي إلى حظر زواحف الذكاء الاصطناعي ما لم تدفع للمبدعين مقابل محتواهم." وإن كنت تشغّل قواعدك الخاصة أيضًا، فتحقق مما تحظره Cloudflare أصلًا في منطقتك كي تتفق الطبقتان.
مع الدفع لكل زحف، يحصل الزاحف الذي يطلب صفحة مسعّرة على "استجابة 402 Payment Required مصحوبة بترويسة crawler-price"، ويمكنه إعادة المحاولة بنية الدفع. وتوقّع الزواحف الطلبات وفق مقترحات Web Bot Auth كي لا يدفع أحد باسم غيره. وتقول Cloudflare إن الدفع لكل زحف "في نسخة تجريبية خاصة حاليًا".
Web Bot Auth ليس معيارًا بعد. ففي 20 أكتوبر 2026 كان لدى مجموعة عمل webbotauth في IETF وثيقة واحدة للمجموعة، هي draft-ietf-webbotauth-httpsig-protocol-00 بتاريخ 1 سبتمبر 2026، ولا RFC؛ وقد مرّ موعد معلَم أبريل 2026 في ميثاقها لمواصفة على مسار المعايير. ويقترح مشروع فردي، draft-illyes-webbotauth-jafar، صيغة JSON مشتركة لملفات نطاقات الزواحف. وإلى أن تتحقق تلك، تبقى نطاقات IP وDNS العكسي هما ما تستطيع فحصه.
قِس ما غيّرته السياسة
قِس السياسة بتسجيل نتيجة التحقق في كل طلب بوت، ثم مقارنة ما قبل وما بعد.
- الحصة حسب البوت الموثَّق. سجّل
crawler.nameوcrawler.verifiedبجانب كل طلب ادّعى بوتًا. حصة الادعاءات الفاشلة هي معدّل الانتحال لديك. والحصة حسب الاسم تُظهر أي المشغّلين يزحفون إليك فعلًا. - الإحالات من الذكاء الاصطناعي. احتسب الزيارات المحالة من chatgpt.com وperplexity.ai وclaude.ai وcopilot.microsoft.com وgemini.google.com. تعامل مع هذا العدد على أنه حد أدنى، فبعض حركة المساعدات تصل بلا مُحيل.
- حجم الزحف. قارن الطلبات يوميًا من كل بوت قبل التغيير وبعده. يغطي تقرير إحصاءات الزحف في Search Console زواحف Google فقط، فيجب أن تأتي بيانات البوتات الأخرى من سجلاتك.
إذا انخفضت الاستشهادات بعد حظر بوت بحث بالذكاء الاصطناعي، فقد حصلت على جوابك بشأن ذلك البوت.
متى تعيد النظر في سياسة زواحف الذكاء الاصطناعي
أعد النظر في سياستك كلما أضاف مشغّل بوتًا أو غيّر ملف نطاقات أو أوقف رمزًا، ومرة كل ربع سنة على الأقل. تدرج صفحة البوتات لدى OpenAI الآن OAI-AdsBot، مع ملفه الخاص adsbot.json. لا تتضمن مصادر الزواحف لدينا ذلك الملف ولا تسميه الشيفرة أعلاه، فيقع ادعاء OAI-AdsBot في الطبقة 3 إلى أن تقرر.
كن واضحًا بشأن ما لا يستطيعه هذا الإعداد:
- لا يثبت إلا البوتات التي تنشر نطاقات. لا يمكن التحقق من Bytespider وMeta-ExternalAgent، وانتحال أيٍّ منهما يبدو تمامًا كالحقيقي.
- البادئات الجديدة تتأخر. قد تستغرق بادئة أُضيفت اليوم نحو يومين حتى يمكن التحقق منها، فقد يفشل بوت حقيقي لوقت قصير في الطبقة 2.
- حظر IP قد يأتي بنتيجة عكسية. تحذّر Anthropic من أن حظر عناوينها IP "قد لا يعمل بشكل صحيح أو دائم لضمان الانسحاب، لأن ذلك يعيق قدرتنا على قراءة ملف robots.txt الخاص بك." أبقِ Disallow في robots.txt حتى حين تنفّذه الطبقة 2.
- لا يرى الاستعلام User-Agent. فحص الانتحال هو مقارنة الاسم في شيفرتك.
- تفوّت الطبقة 2 الكاشطات التي لا تدّعي اسمًا أبدًا. تلك مهمة الطبقة 3.
ابدأ من سجلاتك. اختر عنوانًا واحدًا ادّعى GPTBot أو ClaudeBot هذا الأسبوع، ومرّره عبر استعلام، وقارن crawler.name بالاسم الذي ادّعاه.
الأسئلة الشائعة
هل ينبغي أن أحظر زواحف الذكاء الاصطناعي؟
يتوقف ذلك على وظيفة البوت. احظر زواحف التدريب مثل GPTBot وClaudeBot إن كنت تعترض على استخدام محتواك في تدريب النماذج. واسمح ببوتات البحث بالذكاء الاصطناعي مثل OAI-SearchBot إن أردت أن يُستشهد بك. وحدّد معدّل الجالبات التي يطلقها المستخدم بدل الاعتماد على robots.txt.
هل يوقف robots.txt زواحف الذكاء الاصطناعي؟
فقط تلك التي تختار الالتزام به. ينص RFC 9309 على أن قواعده "ليست شكلًا من أشكال تفويض الوصول". والكاشط الذي يستخدم User-Agent الخاص بـ GPTBot يتجاهله، ولذلك يجب أن يفحص التنفيذ عنوان IP عند وصول الطلب.
هل يضر حظر زواحف الذكاء الاصطناعي بتحسين محركات البحث؟
حظر الرمز Google-Extended لا يؤثر في بحث Google؛ تقول Google إنه "لا يؤثر" في إدراج الموقع في البحث. أما حظر Googlebot لمنع استخدام الذكاء الاصطناعي فيُخرجك من البحث. وحظر بوتات البحث بالذكاء الاصطناعي مثل OAI-SearchBot يُبقيك خارج إجابات البحث لدى ذلك المساعد.
هل يمكنني حظر Google-Extended عبر IP؟
لا. Google-Extended رمز في robots.txt وليس له User-Agent خاص به. زواحف Google الحالية هي التي تجلب الصفحات، فالتحكم الوحيد هو قاعدة robots.txt للرمز. ويعمل Applebot-Extended بالطريقة نفسها: تقول Apple إنه لا يزحف إلى صفحات الويب.
كيف أعرف أن طلبًا يدّعي أنه GPTBot حقيقي؟
تحقق من أن عنوان IP المتصل ضمن ملف gptbot.json المنشور لدى OpenAI. لا يفيد DNS العكسي هنا: عناوين GPTBot وClaudeBot التي فحصناها بلا سجل PTR. يعيد الاستعلام threat.crawler.verified واسم البوت، وتقارن شيفرتك ذلك الاسم بـ User-Agent.
هل يمكن التحقق من كل زواحف الذكاء الاصطناعي عبر IP؟
لا. لم نجد ملف نطاقات من ByteDance لـ Bytespider، ولا تنشر Meta أي ملف لـ Meta-ExternalAgent، فلا يمكن التحقق من أيٍّ منهما عبر IP. حدّد معدّلهما بدل الوثوق بـ User-Agent.
الفريق الذي يقف وراء واجهة GeoIPHub API
بقلم فريق GeoIPHub، وهم من يبنون واجهة GeoIPHub API لاستخبارات IP وماسحها. تُعَدّ المسودات بمساعدة الذكاء الاصطناعي ويحررها الفريق، وأمثلة API استعلامات حقيقية على واجهة API الحية ما لم تُوصف بأنها توضيحية.


