Олег Карнауховweb developerОбсудить проект

Блог

Яндекс не индексирует сайт, и дело не в сайте

Робот заходит, отдаётся ему то же, что и браузеру, запретов нет — а страниц в поиске нет. Разбор ловушки, которую не видно снаружи: главное зеркало на http.

Сайт выложен, страницы отвечают, в Вебмастере отправлена заявка на переобход. Проходит несколько дней — в поиске по-прежнему ничего. Дальше обычно начинают править сайт, и это худшее, что можно сделать: правишь то, что не сломано.

Сначала — проверить, а не догадываться

Первый вопрос: доходит ли робот до страниц вообще. Его легко проверить и незачем угадывать — достаточно попросить сервер отдать страницу так, как её просит Яндекс, и сравнить с тем, что получает браузер.

Сравнивать глазами бесполезно: разница может быть в одном заголовке. Поэтому сверяем контрольные суммы тел ответа.

проверка доступа для роботаbash
BOT='Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)'
UA='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/126'

for path in / /contacts /robots.txt /sitemap.xml; do
  a=$(curl -sS -A "$BOT" "https://example.com$path" | md5)
  b=$(curl -sS -A "$UA"  "https://example.com$path" | md5)
  echo "$path  $a  $b"
done
Если суммы совпали — сервер не различает робота и человека. Это снимает сразу целый класс подозрений: клоакинг, защиту хостера, фильтр по User-Agent.

Всё чисто — и это плохая новость

У меня совпало всё: код 200, тела ответов побайтово одинаковые, время до первого байта около ста миллисекунд. Дальше по списку: в robots.txt запретов на публичные страницы нет; заголовка X-Robots-Tag нет; метатега noindex нет; канонический адрес на каждой странице указывает на неё саму, а не на главную; текст отдаётся сервером, без JavaScript; редирект с http на https стоит на всех адресах и постоянный, в один переход; сертификат валиден и покрывает и апекс, и www.

Звучит как хороший результат. На самом деле это худший: если снаружи всё правильно, значит причина там, куда вы не смотрели. А посмотреть надо было внутрь Вебмастера.

Ловушка: http и https — два разных сайта

В Яндекс.Вебмастере сайт по http и сайт по https — это два разных хоста, а не один сайт с разными адресами. Если когда-то вы добавили сайт по http (а именно так его добавляли все, пока сертификаты не стали бесплатными), то главным зеркалом у Яндекса числится http-версия.

Что из этого следует. Заявки на переобход уходят на хост, которого фактически нет: по http сервер отвечает редиректом и отправляет робота на https. А https-хост, которым сайт живёт на самом деле, для Вебмастера — отдельный сайт, куда никто не переезжал. Кнопка нажата, статус меняется, в поиске ничего.

В моём случае Вебмастер сам об этом и сказал — рекомендацией «Главный адрес сайта не использует HTTPS-протокол». Её легко пролистать: выглядит как общий совет про безопасность, а на деле это диагноз.

Почему старый способ больше не работает

Раньше главное зеркало объявляли директивой Host в robots.txt. Яндекс отказался от неё в 2018 году, и теперь строка Host в файле — просто безвредный мусор: она ничего не сообщает. Если вы полагаетесь на неё, зеркало не переедет никогда.

Единственный работающий путь — сказать Яндексу о переезде явно: раздел «Индексирование», пункт «Переезд сайта», галочка «Добавить HTTPS», сохранить. Плюс добавить https-версию как отдельный сайт: справка прямо предупреждает, что адрес сайта в сервисе сам не меняется.

Как проверить у себя за пять минут

Откройте список сайтов в Вебмастере и посмотрите, что там написано перед доменом. Если сайт добавлен без https — вы, скорее всего, в этой ловушке, и все ваши переобходы уходили в пустоту.

Заодно убедитесь, что технические условия переезда выполнены: постоянный редирект с http на https со всех адресов и с сохранением пути (не «всё на главную»), валидный сертификат, внутренние ссылки и карта сайта уже по https. Если что-то из этого не так, переезд запустится, но закончится плохо.

Попутная находка: дата в карте сайта врала

Пока разбирался, нашёл вторую причину, по которой робот не спешил возвращаться. В карте сайта у всех адресов стояла одна и та же дата изменения, и она была зашита в код константой. Сайт менялся почти каждый день, а карта утверждала, что с начала месяца ничего не происходило.

Для робота это прямое указание не тратить время. Правильный источник даты — файл, в котором лежат слова страницы: правка в админке двигает дату сама, без участия человека. А для страниц, которые живут в коде, честная дата — момент выкладки.

app/sitemap.xml/route.tsts
/** Дата, с точностью до дня. UTC — чтобы день был одним и тем же, кто бы ни спросил. */
function asDay(when: Date | undefined) {
  return when ? when.toISOString().slice(0, 10) : undefined;
}

// Пол под всеми записями — дата релиза: страница не может быть честно
// старше кода, который её рисует. Правка файла поднимает её выше.
const dated = async (files: string[]) => {
  const edited = await changedAt(...files);
  return asDay(edited && edited.getTime() > floor ? edited : release);
};
Точность — сутки: мельче для расписания обхода не значит ничего, а одинаковые метки с миллисекундами читаются как машинный шум.

Что из этого стоит забрать

Проверяйте, а не предполагайте: одна команда с User-Agent робота закрывает вопрос «доходит ли до нас робот» надёжнее, чем час рассуждений.

Чистый результат проверки — не повод расслабиться, а указание искать в другом месте.

Читайте рекомендации Вебмастера буквально. Формулировка про HTTPS выглядит как совет из брошюры про безопасность, а означает, что ваш сайт для Яндекса — другой сайт.

И не обещайте роботу того, чего не было: дата в карте сайта должна брать значение из файла, а не из константы, которую надо не забыть обновить.

Чем кончилось

Переезд зеркала занимает недели, а не дни: страницы старого http-зеркала выпадают из выдачи по мере того, как индексируются их близнецы на https. Так что честный итог этой записи — «причина найдена, ждём». Что получилось на самом деле, напишу отдельно, когда в Вебмастере появятся первые настоящие цифры показов.