Перейти к содержимому

Расписание сканирований и изменения ​

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

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

Что изменилось с прошлого сканирования ​

Каждое завершённое сканирование фиксирует набор открытых проблем в небольшом снимке (seo_scan_run_issues). Сравнение снимков двух запусков даёт точное различие по трём категориям:

  • Новые — проблема не была открыта раньше, открыта сейчас и никогда не была открыта ни в одном более раннем сканировании: действительно первое обнаружение.
  • Вернувшиеся — проблема была исправлена, но появилась снова. (Не «стала серьёзнее»: серьёзность фиксирована для типа проблемы, поэтому значимая регрессия — её возвращение, то самое повторное открытие из жизненного цикла.)
  • Исправленные — проблема была открыта в более раннем сканировании, но теперь исчезла.

Каждая категория сортируется по влиянию, чтобы важное было первым.

Почему снимок, а не таблица проблем ​

Проблемы имеют жизненный цикл исправления и повторного открытия: одна строка обновляется между сканированиями (её scan_run_id каждый раз указывает на новый запуск, пока проблема открыта). Это удобно для долговременной истории, но текущая таблица не может сказать, какие проблемы были открыты в конце запуска N: сохраняющаяся проблема всегда указывает только на последний запуск.

Поэтому каждый запуск сохраняет снимок открытого набора с ключом — стабильным отпечатком проблемы, issue_type | target | field (ту же идентичность сравнивает отчёт под своим брендом). Изменения вычисляются обычными операциями над двумя зафиксированными наборами отпечатков и корректны для любых двух запусков, не только соседних.

Пограничные случаи без ложных выводов ​

  • Страница выпала из набора сканирования. Её открытые проблемы больше не проверяются, поэтому остаются открытыми и снова входят в снимок каждого запуска. Они показываются как всё ещё открытые, а не ложно «исправленные». (Мы не объявляем страницу исправленной только потому, что перестали на неё смотреть.)
  • Между сканированиями отключили проверку. Она перестаёт выдавать проблемы, жизненный цикл отмечает их исправленными, и они покидают открытый набор: отображаются как исправленные. Это соответствует текущему заключению сканера; на уровне проблемы нельзя отличить «вы исправили её» от «вы отключили проверку».
  • Первое сканирование после обновления. У запусков до появления этой функции нет снимков, поэтому они никогда не выбираются базой сравнения. Первое сканирование со снимком становится исходным (текущее состояние, без изменений), а не объявляет весь сайт «новым». Со второго сканирования со снимком сравнение работает.

В панели ​

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

Сортировка по влиянию ​

Каждая категория изменений сортируется по показателю влияния, чтобы самые значимые проблемы были первыми:

impact = severity_weight × page_importance
  • severity_weight использует опубликованную методику оценки: critical имеет вес 40, warning — 15, notice — 5. Серьёзность выражает заявленную продуктом значимость дефекта, поэтому сортировка читает её, а не создаёт вторую шкалу.

  • page_importance определяется реальным поисковым спросом — числом показов страницы в Search Console, поскольку этот сигнал действительно отличает страницы друг от друга:

    page_importance = 1 + demand_weight·demand + priority_weight·priority
    demand   = log1p(page impressions) / log1p(busiest page's impressions)   ∈ [0,1]
    priority = the page's configured per-class sitemap priority              ∈ [0,1]

    Показы масштабируются логарифмически (страница с трафиком в 10× больше не становится в 10× важнее) и нормализуются относительно самой востребованной страницы. Поэтому формула одинаково работает для небольшого блога и крупного каталога. <priority> карты сайта — лишь слабый дополнительный сигнал: по умолчанию он не задан и даже при задании часто одинаков для всех страниц, поэтому не может определять сортировку; он немного влияет, если в seo.sitemap.models настроены приоритеты типов.

Без Search Console всё работает. Если нет синхронизированной истории GSC и настроенных приоритетов, page_importance равно 1 для всех страниц, а влияние — просто сортировка по серьёзности: разумное значение по умолчанию, а не выдуманные данные. Синхронизируйте историю GSC (seo-pro:gsc-sync), чтобы учитывать спрос.

Настраивайте веса и окно в seo-pro.scan.delta.impact.

Планирование сканирования ​

Пакет ничего не планирует по умолчанию. Включите:

php
// config/seo-pro.php
'schedule' => [
    'enabled' => true,          // env SEO_PRO_SCHEDULE_ENABLED
    'frequency' => 'weekly',    // daily | weekly | monthly | hourly
    'time' => '03:00',          // for daily/weekly/monthly
    'timezone' => null,         // null = app timezone
    // ...
],

Или задайте полное cron-выражение для точного управления (оно имеет приоритет над frequency):

php
'cron' => '0 3 * * 1',   // env SEO_PRO_SCHEDULE_CRON

Готово: пакет регистрирует seo-pro:scan в планировщике Laravel с withoutOverlapping, предотвращающим одновременное выполнение запланированной команды. Эта блокировка планировщика не охватывает весь срок работы заданий очереди. Регистрация выполняется только в контексте планировщика/консоли, поэтому не добавляет накладных расходов веб-запросам.

Нужен работающий планировщик

Расписание пакета ничего не делает, пока не работает планировщик Laravel: стандартная строка cron (* * * * * php artisan schedule:run) или php artisan schedule:work при разработке. См. настройку рабочего окружения.

Предпочитаете подключить сами? Оставьте schedule.enabled выключенным и запланируйте команду в своём консольном ядре: изменения и сводка продолжат работать:

php
$schedule->command('seo-pro:scan --notify')->weekly();

--sync выполняет сканирование синхронно вместо постановки одного задания на каждую цель (подходит небольшому сайту без воркера; в рабочем окружении оставьте выключенным).

Письмо со сводкой ​

Включите письмо «что изменилось с прошлого сканирования» после завершения запланированного сканирования: HTML-сводку под вашим брендом с новыми, вернувшимися и исправленными проблемами по влиянию:

php
'schedule' => [
    // ...
    'notify' => [
        'enabled' => true,                       // env SEO_PRO_SCHEDULE_NOTIFY
        'recipients' => ['seo@agency.test'],     // falls back to reports.recipients
        'subject' => 'SEO scan summary',
        'only_on_change' => true,                // skip when nothing changed
    ],
],

Она использует оформление и почтовую настройку отчёта под своим брендом: название агентства, логотип и акцентный цвет сохраняются, а если отдельные получатели не заданы, используются получатели отчётов. only_on_change пропускает письмо, когда сканирование ничего не изменило (первое исходное сканирование отправляется всегда).

Сводка отправляется только для запуска с --notify (планировщик добавляет его автоматически при включённом notify.enabled). Разовый seo-pro:scan без --notify никому не отправляет письмо.

Нужен другой канал?

Хотите Slack, вебхук или собственную сводку вместо email? Подпишитесь на событие Rankbeam\Seo\Pro\Events\SeoScanCompleted: оно вызывается один раз для завершённого запуска и содержит сам запуск, поэтому можно получить изменения через Rankbeam\Seo\Pro\Scanning\Delta\ScanRunDelta и направить их куда нужно.

Срок хранения ​

Снимки удаляются каскадно вместе с запуском, поэтому seo-pro:scan-prune автоматически удаляет устаревшие: новое расписание не нужно. Запуск очищается, только когда не содержит открытых проблем, поэтому снимок недавнего запуска всегда доступен для сравнения.

Полностью отключите снимки (без изменений и сводок) через seo-pro.scan.delta.snapshot => false.

rankbeam/laravel-seo распространяется под лицензией MIT.