YandexBot: как проверить снижение обхода во время инфраструктурного инцидента
YandexBot: как проверить снижение обхода во время инфраструктурного инцидента
Подготовлено 13 октября; дополнено 15 октября 2026 года (Екатеринбург, UTC+5). Добавлен датированный разбор Cloudflare. Это диагностическая методика, не измерение обхода SEO Recipes. Код примера и прежние результаты его тестов не изменены; дата дополнения не означает повторного выполнения тестов.
Практический повод — октябрьские инфраструктурные события, описанные в журнале Yandex Cloud. Совпадение времени проблем облака и изменения логов поискового робота ещё не устанавливает причинную связь. Проверять нужно отдельно происхождение запросов, доступность собственного сайта и состояние индексирования.
Что удалось подтвердить, а что нет
Cloudflare Radar определяет YandexBot как проверенного основного индексирующего робота поиска Яндекса. При подготовке 13 октября числовой временной ряд за фиксированный интервал получить не удалось. Эта прежняя граница проверки сохранена: ниже добавлены результаты опубликованного исследования Cloudflare, а не самостоятельно выгруженный или воспроизведённый ряд Radar.
Исследование Cloudflare от 14 октября
Публикация: 14 октября; прочитана 15 октября. Cloudflare разделяет сети поиска и облачного хостинга. Для 11 октября авторы приводят снижение наблюдаемого HTTP-трафика относительно своего базового уровня:
| Сеть | Оценка из исследования | Граница интерпретации |
|---|---|---|
| AS13238, Yandex Search | На 99% ниже базового уровня | HTTP-трафик ASN в наблюдениях Cloudflare, не размер индекса |
| AS200350, Yandex Cloud | На 90% ниже базового уровня | Облачная сеть с другим составом запросов, не отдельный ряд поискового робота |
В исследованной выборке AS13238 авторы относят 78,1% запросов к verified YandexBot, 11,5% — к YandexRenderResourcesBot, 1,9% — к YandexImages. Эти доли нельзя переносить на каждый сайт или автоматически умножать на величину падения ASN. Для издательского сегмента отмечены ответы HTTP 403 ещё до события — дополнительный повод проверить собственные правила WAF.
Числа относятся к обозначенным наблюдениям, не к текущему состоянию 15 октября. Они не доказывают остановку индексирования всего интернета, падение позиций конкретного сайта или исчезновение автоматизации социальных сетей. Состав выборки и её базовый уровень нельзя заменить своими без перерасчёта. Полный исходный ряд редакцией не получен; причинность для SEO Recipes не установлена.
Не смешивайте разные показатели:
| Показатель | Чего из него не следует |
|---|---|
| Трафик автономной системы | Что весь он относится к YandexBot |
| Запросы всех ботов определённой сети | Что это обращения основного поискового робота |
| Ряд YandexBot в наблюдениях Cloudflare | Что он измеряет весь интернет или каждый сайт |
| Нормализованный график | Абсолютное число запросов без исходных значений и определения нормализации |
| Запросы на origin | Полный объём запросов к CDN: часть могла быть обслужена кешем или остановлена защитой до origin |
| Снижение частоты обхода | Автоматическое выпадение страниц из индекса или падение позиций |
Сохраните точный URL источника, выбранные начало и конец, часовой пояс, фильтры, единицы и дату выгрузки. Без одинакового определения метрики разные проценты не сравниваются. Отсутствующий ряд — «не получен», а не нулевой трафик.
1. Проверить, кто действительно пришёл
По инструкции Яндекса, User-Agent может быть подделан. Для адреса из лога нужен обратный DNS-запрос, затем проверка домена yandex.ru, yandex.net или yandex.com и прямое разрешение полученного имени обратно в исходный IP. Версию в User-Agent нельзя фиксировать навсегда. Другие роботы, например YandexImages и YandexMetrika, имеют отдельные назначения; MirrorDetector также учитывайте отдельно от обычного обхода.
Для автоматизации нормализуйте регистр и завершающую точку имени, проверяйте границу домена, а не простое вхождение yandex в строку. При прямом запросе сравнивайте исходный адрес со всем набором A/AAAA в нормализованном IP-представлении. Тайм-аут DNS означает «не удалось проверить», не доказательство подделки. Сохраняйте время и результат проверки; DNS-запрос сегодня не доказывает принадлежность адреса в давнем логе.
Для Googlebot используйте официальную проверку Google: обратный и прямой DNS либо соответствующий публикуемый список IP. Разделяйте common crawlers, специальных роботов и запросы по инициативе пользователей. Принадлежность адреса Google сама по себе не делает запрос именно Googlebot.
За CDN или reverse proxy сначала установите источник клиентского IP. Заголовок X-Forwarded-For, присланный напрямую произвольным клиентом, нельзя использовать как доказательство происхождения. Проверяйте доверенные прокси и настройки логирования; не меняйте firewall на основании одного User-Agent.
2. Подготовить сопоставимые логи
Для одного сайта выберите один уровень наблюдения: CDN, ingress или origin. Не складывайте три копии одного запроса. Зафиксируйте полноту выгрузки, ротацию, sampling, изменения кеширования и WAF. Анализируйте только логи своих ресурсов либо данные, к которым у вас есть разрешённый доступ.
Для октябрьского расследования можно начать с одинаковых завершённых суточных окон до и после наблюдаемого изменения. Это редакционный план, не утверждение о дате начала сбоя поискового робота. Неполные сутки нельзя напрямую сравнивать с полными сутками. Полезны часовые интервалы, одинаковые дни недели и отдельная контрольная серия Googlebot, но она не доказывает причину изменения Яндекса.
В закрытом наборе сохраните время со смещением UTC, источник лога, статус HTTP, User-Agent и сведения проверки происхождения. Для более глубокой диагностики отдельно нужны URL, DNS/TLS-ошибки, TTFB и результат ответа. Не публикуйте исходные IP, токены, cookies и query-параметры с персональными данными.
3. Минимальный подсчёт кандидатов по часам
Ниже не валидатор роботов, а локальный подсчёт строк, содержащих подходящий User-Agent. Результат намеренно помечается UA candidate. Для подтверждённой серии сначала подготовьте отдельную выборку после проверки происхождения и сохраните метод и дату этой проверки. Такой отбор не выполняется кодом автоматически.
Вход — UTF-8 JSONL: одна запись на строку, поля ts (ISO 8601 со смещением или Z), user_agent (строка), status (целое 100–599). Сначала преобразуйте фактический формат своего access.log; пример не читает произвольный combined log и не угадывает его поля. Дополнительные поля не выводятся. Пример строки синтетический:
{"ts":"2026-10-13T08:30:00+05:00","user_agent":"YandexBot/3.0","status":200}
Сохраните как crawl_counts.py; требуется Python 3.11+:
import json
import re
import sys
from collections import Counter
from datetime import datetime, timezone
TOKEN = re.compile(
r"(?<![a-z0-9_-])(yandexbot|googlebot)/[0-9]+(?:\.[0-9]+)*(?=$|[\s;)])",
re.I,
)
NAMES = {"yandexbot": "YandexBot", "googlebot": "Googlebot"}
def aggregate(path):
counts = Counter()
rows = candidates = 0
with open(path, encoding="utf-8") as stream:
for number, line in enumerate(stream, 1):
if not line.strip():
continue
try:
row = json.loads(line)
if not isinstance(row, dict):
raise ValueError
ts, ua, status = row["ts"], row["user_agent"], row["status"]
if not isinstance(ts, str) or not isinstance(ua, str):
raise ValueError
if type(status) is not int or not 100 <= status <= 599:
raise ValueError
stamp = datetime.fromisoformat(ts.replace("Z", "+00:00"))
if stamp.utcoffset() is None:
raise ValueError
utc_hour = stamp.astimezone(timezone.utc).replace(
minute=0, second=0, microsecond=0
)
except (ValueError, KeyError, TypeError, OverflowError):
raise ValueError(f"Invalid record at line {number}") from None
rows += 1
names = {name.lower() for name in TOKEN.findall(ua)}
if len(names) != 1 or "mirrordetector" in ua.lower():
continue
bot = NAMES[names.pop()] + " (UA candidate)"
hour = utc_hour.isoformat().replace("+00:00", "Z")
counts[(hour, bot, f"{status // 100}xx")] += 1
candidates += 1
return counts, {"rows": rows, "ua_candidates": candidates,
"other_rows": rows - candidates}
if __name__ == "__main__":
if len(sys.argv) != 2:
sys.exit("Usage: python3 crawl_counts.py logs.jsonl")
try:
result, summary = aggregate(sys.argv[1])
except (OSError, ValueError, UnicodeError):
sys.exit("Input error: check schema, encoding, timestamps and file access")
for (hour, bot, status_class), count in sorted(result.items()):
print(json.dumps({"hour_utc": hour, "bot": bot,
"status_class": status_class, "count": count}))
print(json.dumps(summary), file=sys.stderr)
Запуск: python3 crawl_counts.py logs.jsonl. Агрегаты поступают в stdout, число прочитанных записей и кандидатов — в stderr. При ошибке входа процесс завершается ненулевым кодом до вывода агрегатов, без исходной строки в сообщении. Не используйте результат при ненулевом коде завершения. Пустые строки пропускаются.
Код не обращается к DNS или сайту, не меняет логи и не выдаёт отсутствие записей за доказанный нулевой обход. Часы без кандидатов не дополняются нулями: перед заполнением пропусков отдельно подтвердите покрытие логов. Googlebot-Image, NotYandexBot, строки с обоими именами и MirrorDetector исключаются; это сознательно узкий отбор, не универсальная классификация всех краулеров. Версия допускает числовые компоненты через точку и должна завершаться концом строки, пробелом, ; или ): YandexBot/3fake и Googlebot/2-Image не считаются кандидатами.
Граничные примеры для повторения проверки; остальные поля берутся из синтетической строки выше:
| Изменённое поле | Ожидаемый результат |
|---|---|
ts = 0001-01-01T00:00:00+14:00 | Ошибка входа без traceback и частичных агрегатов: UTC выходит за поддерживаемые годы |
ts = 9999-12-31T23:59:59-14:00 | Та же контролируемая ошибка при переполнении верхней границы |
ts = 0001-01-01T00:00:00Z | Допустимый час с четырёхзначным годом 0001, без переполнения |
user_agent = YandexBot/3fake | Запись относится к other_rows, не к кандидатам |
user_agent = Googlebot/2-Image | Запись относится к other_rows, не к кандидатам |
Проверка примера: выполнены 10 локальных тестов 13 октября на Python 3.13.5 и синтетических данных: UTC-группировка, формат и границы токенов, переполнение обоих краёв диапазона дат и представимые граничные годы, схема/типы/статусы, отсутствие часового пояса, пустой ввод, незаполненные часы, ошибка без частичного результата и отсутствие исходных IP/cookies в выводе. Реальные логи SEO Recipes не использовались; проверка DNS и сетевые измерения не выполнялись.
4. Сопоставить наблюдения, не объявляя причину заранее
| Наблюдение | Следующая проверка |
|---|---|
| Оба робота реже видны только на origin | Кеш CDN, смена маршрута, ротация и полнота логов |
| Для подтверждённого YandexBot выросли 403/429 | Правила WAF, rate limiting и журнал изменений защиты |
| Растут 5xx и время ответа для разных клиентов | Доступность приложения, БД, сети и внешних зависимостей |
| Запросы исчезли из HTTP-логов | DNS, TCP/TLS и наблюдения до HTTP; отсутствие строк не доказывает исправность соединения |
| YandexBot реже приходит, но сайт и логи исправны | Состояние обхода в Вебмастере, внешние наблюдения и возможные изменения на стороне поиска |
| Запросы вернулись | Успешные ответы и ожидаемое содержимое; затем отдельно индексирование, не только количество хитов |
Проверяйте robots.txt, случайный noindex, canonical, sitemap, редиректы и доступность типовых URL. Код 200 от страницы ошибки не подтверждает правильную выдачу документа. Подтверждённую техническую ошибку следует исправлять, но не нужно массово менять контент или отключать защиту из-за одного внешнего графика.
5. Отдельно проверить индекс и результат в поиске
По документации Вебмастера основной индексирующий робот отличается от сервисных проверяющих роботов. Для выбранных URL сопоставьте доступные в Вебмастере сведения об обходе и участии в поиске с серверным ответом и датой изменения документа. Посещения робота, добавление в индекс и позиции сохраняйте как разные наблюдения.
Итоговый отчёт должен содержать период, полноту данных, способ проверки бота, изменения сайта и альтернативные объяснения. Формулировка «в нашей подтверждённой выборке уменьшилось число запросов» допустима после измерения; «Яндекс перестал индексировать интернет» из неё не следует. Связь с аварией облака остаётся гипотезой до прямого подтверждения.
Источники и связанные материалы
- Cloudflare: исследование от 14 октября, прочитано 15 октября
- Cloudflare Radar: карточка YandexBot
- Яндекс: проверка происхождения и назначения роботов
- Google: проверка запросов краулеров и fetchers
- Хронология Yandex Cloud — отдельный инфраструктурный контекст
- Сетевой журнал и шаблон независимых проверок
Материалы Google пересказаны со ссылкой на первоисточник, распространяемый на условиях CC BY 4.0. Пример агрегации и порядок расследования — редакционные материалы SEO Recipes, не официальный инструмент поисковых систем.
