Аналіз лог-файлів: поведінка пошукових роботів

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

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Аналіз лог-файлів: поведінка пошукових роботів
Середній
~2-3 дні
Часті запитання

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

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

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

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

Аналіз лог-файлів: поведінка пошукових роботів під мікроскопом

Лог-файли веб-сервера — єдине джерело правди про поведінку пошукових роботів. На відміну від Google Search Console, яка показує дані із затримкою, логи дають реальну картину: які URL обходить Googlebot, як часто, з якими помилками. На основі цих даних ми оптимізуємо crawl budget. За 5 років проаналізували логи 200+ проєктів — типова економія 40% непотрібного краулінгу. Наприклад, на одному проєкті з 50 000 сторінок Googlebot витрачав 80% бюджету на дублі та технічні сторінки, які не приносять трафіку. Після аналізу ми скоротили кількість краулінгу на 35%, що прискорило індексацію нових статей у 2 рази. Економія на серверних ресурсах була суттєвою.

Чому аналіз логів незамінний для SEO?

Без логів ви працюєте наосліп. Реальні завдання, які вирішує log file analysis:

  • Діагностика crawl budget: Googlebot може витрачати 80% ресурсів на дублі або сторінки з низькою цінністю.
  • Пошук URL, які бот обходить, але не індексує (при статусі 200, але відсутності в GSC).
  • Виявлення повільно відповідаючих сторінок (response time > 3 с) — вони знижують швидкість краулінгу.
  • Виявлення небажаних ботів (скрейпери, агресивні парсери), які навантажують сервер.
  • Розуміння ефективності інфраструктури: якщо upstream_response_time зростає, значить бекенд не справляється.

Як ідентифікувати пошукових роботів?

Для кожного робота свій user-agent. Основні:

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)

Які метрики важливі при аналізі?

Після парсингу дивимося на наступні показники:

Метрика Норма Що робити при аномалії
Crawl rate (запитів/день) 100–5000 для середнього сайту Різкий спад — перевірте robots.txt, серверні помилки. Зростання — можливо, контент став популярнішим.
Частка помилок 4xx/5xx <5% Якщо >10% — терміново виправляйте broken links, налаштуйте 301 редиректи.
Середній response time <1 с >2 с — оптимізуйте сервер, CDN, кешування.
% краулінгу дублів <20% Встановіть canonical, забороните неіндексовані розділи в robots.txt.

Якщо бот занадто часто заходить на розділи з дублюючим контентом — блокуємо їх в robots.txt або додаємо атрибут noindex.

Як налаштувати безперервний моніторинг ботів?

Для безперервного моніторингу ми стрімимо логи в ClickHouse. ClickHouse обробляє дані в 10 разів швидше PostgreSQL, що критично при об'ємах від 10 млн записів.

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;

-- Query: top non-indexed URLs
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;

Звичайний pipeline: Filebeat → Logstash/Vector → ClickHouse. На виході — Grafana дашборд з алертами по аномаліях. Нижче — таблиця етапів налаштування:

Етап Інструменти Час
Збір логів Filebeat, Vector 1 день
Парсинг і завантаження Logstash, Vector → ClickHouse 2 дні
Візуалізація Grafana 1 день
Налаштування алертів Grafana 1 день

Що робити з паразитними ботами?

Не всі боти корисні. Скануємо 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) за останні 3–6 місяців.
  • Парсинг і очищення: дедуплікація, фільтрація, збагачення даними про ботів.
  • Побудова звіту з таблицями та графіками: crawl rate, помилки, повільні сторінки.
  • Рекомендації з оптимізації: виправлення помилок, налаштування robots.txt, редиректів.
  • Опціонально: налаштування автоматичного pipeline ClickHouse + Grafana.
  • Передача прав на скрипти та дашборди.

Досвід наших інженерів — 5+ років, сертифікація з Google Analytics та Яндекс.Метрики. Гарантуємо конфіденційність даних.

Процес роботи: від логів до звіту

  1. Аналітика — вивчаємо поточну структуру логів та налаштування сервера.
  2. Проектування — обираємо метод парсингу (Python, Go або через ClickHouse).
  3. Реалізація — пишемо скрипти, парсимо логи, вивантажуємо метрики.
  4. Тестування — звіряємо вибірку з GSC для верифікації даних.
  5. Деплой — віддаємо звіт, навчаємо вашу команду інтерпретувати результати.

Терміни та вартість

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

Отримайте консультацію з аналізу логів вашого сайту. Ми допоможемо виявити приховані проблеми індексації та зекономити ресурси сервера. Зв'яжіться з нами для оцінки вашого проєкту — ми підберемо оптимальний стек і розрахуємо терміни.

Чому Core Web Vitals критичні для технічного SEO

PageSpeed показує 34/100 на мобільних. У Search Console — червоні метрики по всіх сторінках категорій. Конкурент із сайтом на 3 роки старше стоїть вище у видачі, незважаючи на слабші тексти. Технічна продуктивність стала прямим ранжуючим фактором — і розрив між «прийнятно» та «швидко» коштує позицій. Ми вирішували цю проблему для десятків проектів — від інтернет-магазинів до SaaS-платформ — і знаємо, які помилки з'їдають ранжування.

Як досягти хороших показників Core Web Vitals?

Core Web Vitals: що реально впливає на позиції

Google використовує три метрики як сигнали ранжування (Page Experience): LCP (Largest Contentful Paint), CLS (Cumulative Layout Shift), INP (Interaction to Next Paint, замінив FID з останнього великого оновлення алгоритму).

LCP: чому 8 секунд — це не проблема зображення

LCP вимірює час відмальовки найбільшого видимого елемента сторінки. Найчастіше — hero image або H1. Пороги: добре < 2.5s, погано > 4s.

Типовий діагноз на реальному проекті: інтернет-магазин одягу, LCP 7.8s на мобільних. Елемент — hero image категорії, 4.2MB JPEG без srcset, завантажується через CSS background-image (не <img>). Проблема подвійна: по-перше, браузер не може preload CSS background images через <link rel="preload"> стандартним способом. По-друге, 4.2MB на мобільному з'єднанні — це фізично повільно.

Рішення по кроках:

  1. Переносимо hero з CSS background в <img> з fetchpriority="high" та loading="eager"
  2. Конвертуємо в WebP, додаємо srcset: 800w для мобільних, 1400w для десктопа
  3. <link rel="preload" as="image" href="hero-800.webp" media="(max-width: 768px)"> в <head>
  4. Прибираємо всі render-blocking скрипти вище hero через defer

Підсумок: LCP 7.8s → 1.9s. Без зміни хостингу, без CDN.

Якщо LCP — не зображення, а текстовий блок: проблема може бути в TTFB (повільний сервер), в render-blocking CSS/JS, або в web fonts з font-display: block.

CLS: зсуви, які дратують користувача і Google

CLS вимірює сумарний зсув елементів в процесі завантаження. Пороги: добре < 0.1, погано > 0.25. CLS 0.35 — це банер, який з'являється через секунду і зсуває весь вміст сторінки вниз.

Джерела CLS:

  • Зображення без заданих розмірів. <img src="photo.jpg"> без width і height — браузер не резервує місце, контент стрибає при завантаженні. Фікс: явні width/height або aspect-ratio в CSS.
  • Рекламні блоки та віджети. Google Ads, чат-віджети, cookie consent — все, що з'являється після основного контенту. Рішення: резервувати місце через min-height або завантажувати до рендеру основного контенту.
  • Web fonts. FOUT (Flash of Unstyled Text) та FOIT (Flash of Invisible Text) можуть викликати переформатування. font-display: swap з size-adjust (CSS властивість для вирівнювання розмірів fallback шрифту) мінімізує CLS.
  • Динамічний контент. Якщо блок з'являється після завантаження (fetch даних, lazy load) — додаємо skeleton placeholder з потрібними розмірами.
Типовий сценарій CLS до CLS після Основний фікс
Банер знижок без min-height 0.42 0.02 min-height: 300px
Картинки в статтях без атрибутів 0.18 0.01 width/height + aspect-ratio
Віджет чату, що завантажується через 3с 0.35 0.05 position: fixed із зарезервованим відступом

INP: чому інтерфейс «зависає» на 500ms

INP вимірює затримку відповіді на будь-яку взаємодію користувача: клік, тап, введення. Пороги: добре < 200ms, погано > 500ms. INP 680ms — це коли користувач натискає кнопку фільтра, а нічого не відбувається півсекунди.

Головна причина високого INP — заблокований main thread. JavaScript-бандл 2.1MB парситься і виконується синхронно. Поки виконується, користувацькі події не обробляються.

Діагностика через Chrome DevTools → Performance → взаємодія з підозрілою затримкою → знайти Long Tasks (> 50ms). Типові винуватці:

  • Безперервна обробка великого списку без requestIdleCallback або requestAnimationFrame
  • Важкі event listeners без debounce/throttle
  • Синхронний setState в React, який тригерить повний ре-рендер складного дерева компонентів
  • Third-party scripts: livechat, аналітика, віджети — вони виконуються в тому ж main thread

Рішення: code splitting через динамічний import(), перенесення важких обчислень в Web Workers, React.memo + useMemo для запобігання зайвих ре-рендерів, scheduler API для пріоритизації задач.

Schema.org: розмітка, яку читають роботи

Структуровані дані через JSON-LD — не прямий ранжуючий фактор, але дають rich snippets у видачі (зірки рейтингів, ціни, дата публікації), що збільшує CTR на 20–30%.

Типи розмітки за сценаріями:

  • E-commerce: Product з offers (ціна, наявність, валюта), aggregateRating (рейтинг з відгуків), brand. BreadcrumbList для навігації. ItemList для сторінок категорій.
  • Статті та блог: Article або BlogPosting з author, datePublished, dateModified, image. Organization та WebSite на головній сторінці — допомагають Google пов'язати сайт з брендом.
  • Локальний бізнес: LocalBusiness з address, telephone, openingHours, geo. Критично для локального SEO.
  • FAQ: FAQPage з mainEntity — питання та відповіді можуть з'являтися прямо у видачі як розкривний блок.

Валідація: Google Rich Results Test та Schema Markup Validator. Часта помилка — вказати price без priceCurrency, або ratingValue без reviewCount. Google ігнорує неповну розмітку.

Як проводити технічний SEO-аудит

Сканованість. robots.txt блокує потрібні сторінки (або навпаки, не блокує службові). Canonical URLs налаштовані неправильно — дублюються сторінки з UTM-мітками. Sitemap містить сторінки з noindex. Все це Screaming Frog або Sitebulb покажуть за годину сканування.

Core Web Vitals в масштабі. Google Search Console → Core Web Vitals → дивимося не окремі сторінки, а групи URL (шаблон сторінки продукту, шаблон категорії, блог). Проблема зазвичай системна — одна помилка в шаблоні псує сотні сторінок.

JavaScript SEO. Google рендерить JavaScript, але з затримкою (іноді дні для повного рендеру). Для критичного контенту — SSR або SSG обов'язкові. Перевіряємо через Search Console → Inspect URL → View Crawled Page: що бачить Googlebot.

Internal linking. Орфанні сторінки (немає вхідних внутрішніх посилань) втрачають PageRank. Бите посилання (404) — сигнал якості.

Типові помилки при впровадженні Schema.org
  • Вказано price без priceCurrency — розмітка ігнорується.
  • ratingValue без reviewCount — у видачі не показується.
  • Кілька Product на одній сторінці без @type: ItemList — Google бере тільки перший.
  • JSON-LD в GTM — Google не завжди бачить динамічну розмітку, краще серверний рендеринг.
Етап роботи Що входить Термін
Аудит Сканування, аналіз Core Web Vitals, аудит Schema, звіт з пріоритетами 1–2 тижні
Оптимізація одного шаблону LCP, CLS, INP, впровадження SSR/SSG, налаштування preload 2–4 тижні
Повна технічна оптимізація Всі шаблони, code splitting, Web Workers, моніторинг в CI 4–10 тижнів
Впровадження Schema.org JSON-LD генерація, валідація, тестування rich snippets 1–3 тижні

Що входить в роботу

  • Документація: звіт зі знайденими проблемами, roadmap за пріоритетами, таймінги для кожного етапу.
  • Доступи: налаштування моніторингу (SpeedCurve, Sentry Search Console), передача dashboard.
  • Навчання: розбір типових помилок для вашої команди (1–2 дзвінки).
  • Підтримка: супровід протягом місяця після деплою — перевірка метрик, фікс регресій.

Зв'яжіться з нами — ми оцінимо ваш проект за 2 дні і покажемо, скільки позицій можна повернути за рахунок технічного SEO. Досвід роботи з проектами рівня сотень тисяч відвідувань на місяць — гарантуємо вимірний результат в Core Web Vitals до/після. Замовте аудит у цій формі — отримайте персональний чек-лист з 15 пунктів.