Реалізація Log File Analysis для аналізу поведінки пошукових роботів

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація Log File Analysis для аналізу поведінки пошукових роботів
Середня
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Впровадження Log File Analysis для аналізу поведінки поисковых роботів

Лог-файли веб-сервера — єдиний джерело достовірних даних про те що поисковы роботи справді роблять на сайті. Google Search Console показує узагальнену картину з затримкою. Логи показують точно: які URL обходить Googlebot, як часто, скільки часу витрачає, які URL ігнорує, де отримує помилки 404/500, є ли аномалії.

Структура записів в access.log

# Nginx access.log (combined формат)
66.249.64.13 - - [15/Nov/2024:14:23:01 +0300] "GET /products/laptop-apple/ HTTP/1.1" 200 45231 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

Поля: IP, ident, auth, hour, метод+URL+протокол, status, bytes, referer, user-agent.

Додати час відповіді у логи:

# nginx.conf
log_format detailed '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time';

access_log /var/log/nginx/access.log detailed;

Ідентифікація поисковых роботів

Основні User-Agent паттерни:

CRAWLER_PATTERNS = {
    'Googlebot': r'Googlebot(?:/\d+\.\d+)?',
    'Yandexbot': r'YandexBot(?:/\d+\.\d+)?',
    'Bingbot': r'bingbot(?:/\d+\.\d+)?',
    'Baiduspider': r'Baiduspider',
}

Перевірити підлінність Googlebot через зворотній DNS (PTR-запит):

import socket
import re

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

Базовий парсинг логів

import re
import gzip
from datetime import datetime
from collections import defaultdict, Counter

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.]+))?'
)

def parse_log_file(filepath: str):
    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
            yield {
                'ip': m.group('ip'),
                'time': m.group('time'),
                'method': m.group('method'),
                'url': m.group('url'),
                'status': int(m.group('status')),
                'bytes': int(m.group('bytes')),
                'user_agent': m.group('ua'),
                'request_time': float(m.group('request_time') or 0)
            }

def analyze_crawlers(log_files: list[str]) -> dict:
    stats = defaultdict(lambda: {
        'total_requests': 0,
        'urls': Counter(),
        'status_codes': Counter(),
        'slow_urls': [],
        'errors': []
    })

    for log_file in log_files:
        for entry in parse_log_file(log_file):
            crawler = identify_crawler(entry['user_agent'])
            if not crawler:
                continue

            s = stats[crawler]
            s['total_requests'] += 1
            s['urls'][entry['url']] += 1
            s['status_codes'][entry['status']] += 1

            if entry['request_time'] > 2.0:
                s['slow_urls'].append(entry)

            if entry['status'] >= 400:
                s['errors'].append(entry)

    return dict(stats)

Ключові метрики

Crawl rate: Норма для середнього сайту — 100–5000 запитів Googlebot у день. Різкий спад — признак проблеми (блокування robots.txt, помилки сервера, зменшення пріоритету).

Найбільше/найменше краулируєми розділи:

def crawl_distribution(urls: Counter) -> dict:
    sections = defaultdict(int)
    for url, count in urls.items():
        section = f'/{url.split("/")[1]}/' if '/' in url else '/'
        sections[section] += count
    return dict(sorted(sections.items(), key=lambda x: x[1], reverse=True))

URL які обходить бот але повертають помилки (404, 500): Ці URL потрібно восстановити або додати 301-редирект.

Моніторинг через ClickHouse + Grafana

Для постійного моніторингу, стримити логи в ClickHouse:

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;

Пошук паразитних ботів

Не все боти корисні. Пошук по user_agent:

def find_suspicious_crawlers(log_files: list[str]) -> list:
    known_good = set(CRAWLER_PATTERNS.keys()) | {'curl', 'wget'}

    ua_counter = Counter()
    for log_file in log_files:
        for entry in parse_log_file(log_file):
            if not identify_crawler(entry['user_agent']):
                ua_counter[entry['user_agent']] += 1

    suspicious = []
    for ua, count in ua_counter.most_common(50):
        if count > 1000:
            suspicious.append({'user_agent': ua, 'requests': count})

    return suspicious

Заблокувати в nginx:

map $http_user_agent $bad_bot {
    default         0;
    ~*SemrushBot    0;  # Дозволити
    ~*AhrefsBot     0;
    ~*MJ12bot       1;  # Заблокувати
}

server {
    if ($bad_bot) {
        return 403;
    }
}

Тривалість

Разовий аналіз логів за 1 місяць (до 5 GB) з звітом — 2–3 робочих дні. Налаштування автоматизованого pipeline (парсинг → ClickHouse → Grafana дашборд) з алертами — 4–7 днів.