קובצי היומן של השרת הם מקור האמת היחיד לגבי התנהגות בוט החיפוש. בניגוד ל-Google Search Console, שמציג נתונים באיחור, היומנים מספקים תמונה אמיתית: אילו כתובות URL Googlebot מבקר, באיזו תדירות, ועם אילו שגיאות. בהתבסס על נתונים אלה, אנו מייעלים את תקציב הסריקה. במשך 5 שנים, ניתחנו יומנים של יותר מ-200 פרויקטים — חיסכון אופייני של 40% בסריקות מיותרות. לדוגמה, בפרויקט אחד עם 50,000 עמודים, Googlebot בילה 80% מהתקציב שלו על כפילויות ועמודים טכניים שלא הביאו תנועה. לאחר הניתוח, צמצמנו את הסריקה ב-35%, והאצנו את האינדוקס של מאמרים חדשים פי 2. החיסכון במשאבי השרת היה משמעותי.
למה ניתוח יומנים הוא הכרחי לקידום אורגני?
בלי יומנים, אתה עובד בעיוורון. בעיות אמיתיות שניתוח יומנים פותר:
- אבחון תקציב סריקה: Googlebot עלול לבזבז 80% מהמשאבים על כפילויות או עמודים בעלי ערך נמוך.
- זיהוי כתובות URL שהבוט מבקר בהן אך לא מבצע אינדוקס (סטטוס 200, אבל לא מופיעות ב-GSC).
- איתור עמודים עם זמן תגובה איטי (זמן תגובה > 3 שניות) — הם מאטים את הסריקה.
- זיהוי בוטים לא רצויים (מגרדים, מנתחים אגרסיביים) שמעמיסים על השרת.
- הבנת יעילות התשתית: אם upstream_response_time עולה, השרת האחורי מתקשה.
איך לזהות בוטי חיפוש?
לכל בוט יש סוכן משתמש משלו. העיקריים:
CRAWLER_PATTERNS = {
'Googlebot': r'Googlebot(?:/\d+\.\d+)?',
'Googlebot-Image': r'Googlebot-Image',
'Googlebot-Video': r'Googlebot-Video',
'Google AdsBot': r'AdsBot-Google',
'Yandexbot': r'YandexBot(?:/\d+\.\d+)?',
'YandexImages': r'YandexImages',
'Bingbot': r'bingbot(?:/\d+\.\d+)?',
'Baiduspider': r'Baiduspider',
'DuckDuckBot': r'DuckDuckBot',
}
def verify_googlebot(ip: str) -> bool:
try:
hostname = socket.gethostbyaddr(ip)[0]
if not re.search(r'\.googlebot\.com$|\.google\.com$', hostname):
return False
resolved_ip = socket.gethostbyname(hostname)
return resolved_ip == ip
except socket.herror:
return False
האותנטיות של Googlebot מאומתת באמצעות DNS הפוך. כפי שצוין באימות Googlebot, זו הדרך היחידה להבטיח דיוק. אנו משתמשים בסקריפט דומה ומשיגים דיוק זיהוי של 100%.
ניתוח יומנים: סקריפט בסיסי
import re
import gzip
from pathlib import Path
from datetime import datetime
from collections import defaultdict, Counter
from dataclasses import dataclass, field
from typing import Iterator
LOG_PATTERN = re.compile(
r'(?P<ip>[\d.]+) .+ \[(?P<time>[^\]]+)\] '
r'"(?P<method>\w+) (?P<url>[^\s]+) HTTP/[\d.]+"'
r'(?P<status>\d+) (?P<bytes>\d+) '
r'"[^"]*" "(?P<ua>[^"]*)"'
r'(?:\s+(?P<request_time>[\d.]+))?'
)
@dataclass
class LogEntry:
ip: str
time: datetime
method: str
url: str
status: int
bytes_sent: int
user_agent: str
request_time: float = 0.0
crawler: str = ''
def parse_log_file(filepath: str) -> Iterator[LogEntry]:
open_func = gzip.open if filepath.endswith('.gz') else open
with open_func(filepath, 'rt', encoding='utf-8', errors='replace') as f:
for line in f:
m = LOG_PATTERN.match(line)
if not m:
continue
try:
entry = LogEntry(
ip=m.group('ip'),
time=datetime.strptime(m.group('time'), '%d/%b/%Y:%H:%M:%S %z'),
method=m.group('method'),
url=m.group('url'),
status=int(m.group('status')),
bytes_sent=int(m.group('bytes')),
user_agent=m.group('ua'),
request_time=float(m.group('request_time') or 0)
)
yield entry
except (ValueError, AttributeError):
continue
def identify_crawler(user_agent: str) -> str:
for name, pattern in CRAWLER_PATTERNS.items():
if re.search(pattern, user_agent, re.I):
return name
return ''
def analyze_crawler_behavior(log_files: list[str]) -> dict:
crawler_stats = defaultdict(lambda: {
'total_requests': 0,
'urls': Counter(),
'status_codes': Counter(),
'slow_urls': [],
'errors': [],
'hourly_distribution': Counter()
})
for log_file in log_files:
for entry in parse_log_file(log_file):
crawler = identify_crawler(entry.user_agent)
if not crawler:
continue
entry.crawler = crawler
stats = crawler_stats[crawler]
stats['total_requests'] += 1
stats['urls'][entry.url] += 1
stats['status_codes'][entry.status] += 1
stats['hourly_distribution'][entry.time.hour] += 1
if entry.request_time > 2.0:
stats['slow_urls'].append({
'url': entry.url,
'time': entry.request_time,
'timestamp': entry.time.isoformat()
})
if entry.status >= 400:
stats['errors'].append({
'url': entry.url,
'status': entry.status,
'timestamp': entry.time.isoformat()
})
return dict(crawler_stats) אילו מדדים חשובים בניתוח?
לאחר הניתוח, אנו בוחנים את המדדים הבאים:
| מדד | טווח תקין | פעולה בחריגה |
|---|---|---|
| קצב סריקה (בקשות ליום) | 100–5000 לאתר ממוצע | ירידה חדה — בדוק robots.txt, שגיאות שרת. עלייה — ייתכן שהתוכן פופולרי יותר. |
| שיעור שגיאות 4xx/5xx | <5% | אם >10% — תקן קישורים שבורים מיד, הגדר הפניות 301. |
| זמן תגובה ממוצע | <1 שנייה | >2 שניות — ייעל שרת, CDN, מטמון. |
| אחוז סריקת כפילויות | <20% | הגדר canonical, חסום קטעים שאינם ניתנים לאינדוקס ב-robots.txt. |
אם בוט מבקר לעתים קרובות בקטעי תוכן כפול — חסום אותם ב-robots.txt או הוסף noindex.
איך להקים ניטור בוטים רציף?
לניטור רציף, אנו מזרימים יומנים ל-ClickHouse. ClickHouse מעבד נתונים פי 10 מהר יותר מ-PostgreSQL, וזה קריטי לנפחים של 10M+ רשומות.
CREATE TABLE crawler_logs (
timestamp DateTime,
ip IPv4,
method LowCardinality(String),
url String,
status UInt16,
bytes UInt32,
user_agent String,
request_ms Float32,
crawler LowCardinality(String)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (crawler, timestamp)
TTL timestamp + INTERVAL 6 MONTH;
-- Запрос: топ URL, которые Googlebot посещает но не индексирует (200 OK, нет в GSC)
SELECT url, count() as visits
FROM crawler_logs
WHERE crawler = 'Googlebot' AND status = 200 AND timestamp >= now() - INTERVAL 30 DAY
GROUP BY url
ORDER BY visits DESC
LIMIT 50;צינור נתונים אופייני: Filebeat → Logstash/Vector → ClickHouse. פלט — לוח מחוונים של Grafana עם התראות על חריגות. שלבי הקמה:
| שלב | כלים | זמן |
|---|---|---|
| איסוף יומנים | Filebeat, Vector | יום אחד |
| ניתוח וטעינה | Logstash, Vector → ClickHouse | יומיים |
| ויזואליזציה | Grafana | יום אחד |
| הגדרת התראות | Grafana | יום אחד |
מה לעשות עם בוטים טפיליים?
לא כל הבוטים מועילים. אנו סורקים את user_agent לאיתור מגרדים לא ידועים. אלה שזוהו נחסמים ב-nginx:
map $http_user_agent $bad_bot {
default 0;
~*SemrushBot 0;
~*AhrefsBot 0;
~*MJ12bot 1;
~*DotBot 1;
}
server {
if ($bad_bot) {
return 403;
}
} מה כולל שירות ניתוח היומנים שלנו
אנו מספקים פרויקט מפתח:
- איסוף יומנים משרתים (nginx, Apache, IIS) משלושת עד ששת החודשים האחרונים.
- ניתוח וניקוי: הסרת כפילויות, סינון, העשרה בנתוני בוטים.
- בניית דוח עם טבלאות וגרפים: קצב סריקה, שגיאות, עמודים איטיים.
- המלצות לאופטימיזציה: תיקון שגיאות, הגדרת robots.txt, הפניות.
- אופציונלי: הקמת צינור נתונים אוטומטי עם ClickHouse + Grafana.
- העברת זכויות לסקריפטים וללוחות מחוונים.
למהנדסים שלנו יש ניסיון של 5+ שנים, והסמכות מ-Google Analytics ו-Yandex.Metrica. סודיות הנתונים מובטחת.
תהליך העבודה: מיומנים לדוח
- ניתוח — לימוד מבנה היומנים הנוכחי ותצורת השרת.
- עיצוב — בחירת שיטת ניתוח (Python, Go, או דרך ClickHouse).
- יישום — כתיבת סקריפטים, ניתוח יומנים, ייצוא מדדים.
- בדיקה — הצלבה עם GSC לאימות נתונים.
- השקה — מסירת הדוח, הדרכת הצוות שלך על פרשנות.
לוחות זמנים ומחירים
ניתוח חד-פעמי של חודש אחד (עד 5 GB) — 2–3 ימי עסקים. הקמת צינור נתונים אוטומטי (ניתוח → ClickHouse → לוח מחוונים של Grafana) עם התראות — 4–7 ימים. המחיר מותאם אישית, בהתבסס על נפח היומנים ומורכבות התשתית. קבל ייעוץ על ניתוח היומנים של האתר שלך. נעזור לחשוף בעיות אינדוקס נסתרות ולחסוך במשאבי שרת. צור קשר להערכת הפרויקט שלך — נבחר את הסט הטכנולוגי האופטימלי ונחשב לוחות זמנים.







