النطاق: هذا مرجع تنفيذ عملي. راجع توثيق Google والمنصات الحالية قبل اتخاذ قرار إصدار أو سياسة.
مدخلات Nginx وCloudflare
سجلات Nginx تكون أسهل عندما تتحكم في format. أما Cloudflare فقد يستخدم schema مختلفًا، فوحّد الحقول أولًا. لا تحدد bot من User-Agent وحده في قرارات الأمان؛ اجمعه مع تحقق IP أو مزود الشبكة عند الحاجة.
# طلبات حسب User-Agent
awk -F'"' '{print $6}' access.log \
| awk 'BEGIN{IGNORECASE=1} /Googlebot/{g++} /GPTBot|ClaudeBot|PerplexityBot/{ai++} !/bot|crawler|spider/{human++} END{print "google",g; print "ai",ai; print "human",human}'
# توزيع الحالات للزواحف
awk -F'"' '/Googlebot|GPTBot|ClaudeBot|PerplexityBot/ { split($1,a," "); print a[9] }' access.log | sort | uniq -c | sort -nrParser Python قابل للتكرار
حلل request line وUser-Agent بانتظام بدل split عشوائي. المثال التالي محافظ: السطر التالف يُعدّ ولا يُحذف بصمت.
import re
from collections import Counter
line_re = re.compile(r'^(?P<ts>\S+) \S+ "(?P<request>[^" ]+) (?P<status>\d{3}) (?P<bytes>\d+)" "(?P<ref>[^" ]*)" "(?P<ua>[^" ]*)"')
bots = ('Googlebot', 'Bingbot', 'GPTBot', 'ClaudeBot', 'PerplexityBot')
counts = Counter(); malformed = 0
with open('access.log', encoding='utf-8', errors='replace') as log:
for line in log:
match = line_re.match(line)
if not match: malformed += 1; continue
row = match.groupdict(); ua = row['ua']
group = next((bot for bot in bots if bot.lower() in ua.lower()), 'human/other')
path = row['request'].split('?', 1)[0]
counts[(group, row['status'], path)] += 1
for key, total in counts.most_common(30): print(total, *key)
print('malformed=', malformed)حوّل الطلبات إلى قرارات زحف
أنشئ تقريرًا على مستوى URL يضم hits والأيام الفريدة وفئات status والحجم ومجموعات البوتات. أعط الأولوية لصفحات تتلقى 4xx/5xx أو redirects متسلسلة، بينما لا تصل الزواحف إلى canonicals مهمة.
# أعلى URLs غير 200 للبوتات
awk -F'"' '/Googlebot|GPTBot|ClaudeBot|PerplexityBot/ { split($1,a," "); if (a[9] !~ /^2/) print a[9], $2 }' access.log | sort | uniq -c | sort -nr | head -50
# جدول قرار مختصر
status >= 500 -> أصلح موثوقية origin
status == 404 -> أصلح الروابط أو أعد المورد canonical
status 301/302 -> أزل السلاسل وحدّث الروابط الداخليةالهدف ليس dashboard ضخمًا؛ الهدف قائمة قابلة للدفاع بهدر crawl budget والصفحات المهمة التي لا تصل إليها الزواحف.