Проблема: почему URL не обновляются в IndexNow при массовом импорте
При массовом импорте контента в WordPress (например, с помощью WP All Import или пользовательских скриптов) часто возникает ситуация, когда изменения новых или обновленных записей не отправляются в поисковые системы через протокол IndexNow. Это приводит к задержкам в индексации, что критично при обновлении каталогов, новостей или товаров.
Диагностика проблемы
- Проверьте логи плагина/скрипта, отвечающего за отправку URL в IndexNow — часто при массовом импорте запросы блокируются или не вызываются.
- Убедитесь, что хуки, на которые подписана отправка URL, вызываются при импорте (например,
save_post,wp_insert_post). - Проверьте, не превышается ли лимит частоты отправки URL IndexNow — частые массовые запросы могут приводить к блокировке.
- Проверьте, что URL правильно формируются и доступны (отсутствуют редиректы и ошибки 404).
Пошаговое решение: автоматическая отправка URL в IndexNow при массовом импорте
Чтобы гарантировать отправку URL при массовом импорте, рекомендуем использовать следующий подход:
- Отслеживать массовый импорт и собирать все изменённые URL в очередь.
- Отправлять URL пакетами с заданным интервалом, чтобы не превышать лимиты IndexNow.
- Использовать WP-Cron для асинхронной отправки и повторных попыток при ошибках.
Пример реализации очереди отправки URL
class IndexNow_Queue {
private $option_name = 'indexnow_url_queue';
public function add_urls(array $urls) {
$queue = get_option($this->option_name, []);
$queue = array_unique(array_merge($queue, $urls));
update_option($this->option_name, $queue);
}
public function get_urls($limit = 20) {
$queue = get_option($this->option_name, []);
return array_slice($queue, 0, $limit);
}
public function remove_urls(array $urls) {
$queue = get_option($this->option_name, []);
$queue = array_diff($queue, $urls);
update_option($this->option_name, $queue);
}
}
// Инициализация
$indexnow_queue = new IndexNow_Queue();
// Добавление URL в очередь при массовом импорте
add_action('pmxi_after_xml_import', function($import_id) use ($indexnow_queue) {
$post_ids = get_posts([
'post_type' => 'any',
'numberposts' => -1,
'meta_query' => [[
'key' => '_import_id',
'value' => $import_id
]]
]);
$urls = [];
foreach ($post_ids as $post) {
$urls[] = get_permalink($post->ID);
}
$indexnow_queue->add_urls($urls);
});Отправка URLs пакетами с WP-Cron
add_action('indexnow_send_queue', function() use ($indexnow_queue) {
$urls = $indexnow_queue->get_urls(20);
if (empty($urls)) {
return;
}
$endpoint = 'https://api.indexnow.org/indexnow';
$key = 'ваш_ключ_из_IndexNow';
$payload = [
'host' => parse_url(home_url(), PHP_URL_HOST),
'key' => $key,
'keyLocation' => home_url('indexnow-key.txt'),
'urlList' => $urls
];
$response = wp_remote_post($endpoint, [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode($payload),
'timeout' => 10
]);
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
$indexnow_queue->remove_urls($urls);
}
});
// Запланировать cron-задание на каждые 5 минут
if (!wp_next_scheduled('indexnow_send_queue')) {
wp_schedule_event(time(), 'five_minutes', 'indexnow_send_queue');
}
// Добавить интервал 5 минут
add_filter('cron_schedules', function($schedules) {
$schedules['five_minutes'] = ['interval' => 300, 'display' => 'Каждые 5 минут'];
return $schedules;
});Проверка результата после внедрения
- Просмотрите очередь URL
indexnow_url_queueчерезget_option— она должна очищаться после успешной отправки. - Проверьте логи WP-Cron или используйте плагин WP Crontrol, чтобы убедиться, что задача
indexnow_send_queueвыполняется регулярно. - Воспользуйтесь командой curl или Postman для проверки ответа IndexNow API — при успешной отправке вернется HTTP 200.
- Проверьте через Search Console или Bing Webmaster Tools, что новые URL индексируются быстрее.
Частые ошибки и как исправить
- Не вызываются хуки при импорте: Некоторые импортеры не вызывают стандартные хуки WordPress. Используйте специфичные хуки плагина, например,
pmxi_after_xml_importдля WP All Import. - Превышение лимитов IndexNow: Отправка слишком большого количества URL за раз блокирует запросы. Используйте пакетную отправку с ограничением в 10-20 URL.
- Ошибки в формате JSON: Убедитесь, что тело запроса строго соответствует спецификации IndexNow и JSON валиден.
- Отсутствие файла ключа: IndexNow требует размещения ключа по определенному URL (
https://ваш_сайт/indexnow-key.txt), проверьте, что он доступен и содержит корректный ключ. - WP-Cron не запускается: Для сайтов с низкой посещаемостью WP-Cron может не срабатывать. Настройте системный cron для запуска
wp-cron.php.
Практические советы по безопасности и производительности
- Не храните ключ IndexNow в общедоступных файлах или репозиториях. Используйте константы или параметры в
wp-config.php. - Ограничьте количество URL в очереди, чтобы не забивать базу данных. Можно использовать transient API для временного хранения.
- Для крупных сайтов с миллионами URL рассмотрите разделение очереди по типам контента и приоритетам.
- Логируйте ошибки отправки в отдельный файл или базу для оперативной отладки.
- Проверяйте доступность URL перед отправкой, чтобы не отправлять 404 или редиректы.
Сравнение вариантов реализации очереди отправки URL
| Метод | Описание | Преимущества | Недостатки |
|---|---|---|---|
| Использование опций WordPress | Хранение очереди в опции (get_option/update_option) | Простота реализации, нет внешних зависимостей | Может замедлить загрузку базы при большом количестве URL |
| Использование transient API | Временное хранение с автоматическим удалением | Автоматическое управление сроком хранения | Не подходит для критичных данных, возможна потеря при очистке кэша |
| Использование кастомной таблицы в базе | Создание отдельной таблицы для очереди отправки | Высокая производительность при больших объемах, гибкость | Сложнее в реализации и поддержке |