Акция закончилась в 07:00 UTC. В каталоге товар снова стоит £100, а в служебной разметке страницы осталась цена £80. Такую разницу можно найти до ручного разбора каждой карточки.
Мой Merchant Sale Transition Audit на Apify сравнивает заданные цены каталога с JSON-LD из HTML страницы. JSON-LD — блок структурированных данных, где магазин указывает товар, цену и валюту для других систем. Actor — небольшая программа на Apify: на входе данные, на выходе результат проверки.
Ниже один вымышленный товар, запуск без обхода магазина и пример отчёта. Это инструкция к собственному инструменту, подготовленная с помощью ИИ и проверенная по его реализации. Реального клиентского кейса здесь нет. Для международной команды есть английская версия инструкции.
Какую задачу решает проверка
Она пригодится тому, кто готовит скидочную акцию или проверяет несколько карточек после её завершения. Нужно заранее знать SKU товара — его артикул, обычную цену, скидочную цену и точное время начала и конца акции.
В требованиях Google к sale_price цена скидки должна согласовываться со страницей товара и оформлением заказа. Период скидки можно передать через sale_price_effective_date. У этого Actor охват уже: только заданные условия каталога и статическая JSON-LD разметка. Проверку корзины и оплаты он не выполняет.
Время начала акции входит в интервал, время конца уже не входит. В нашем примере ровно в 07:00 ожидается обычная цена £100. Это правило сравнения Actor; оно не воспроизводит все настройки времени в Google Merchant Center. Часовой пояс в датах обязателен.
Запуск на одном товаре
Открой страницу Actor, перейди к запуску и выбери ввод JSON. Перед запуском посмотри текущую стоимость и лимиты в Apify: наличие инструкции не означает бесплатную работу платформы для любого аккаунта.
Вставь эти данные:
{
"feed": [
{
"sku": "DEMO-1",
"price": "100",
"currency": "GBP",
"price_basis": "tax_inclusive",
"sale_price": "80",
"sale_start": "2026-10-06T06:00:00+00:00",
"sale_end": "2026-10-06T07:00:00+00:00",
"url": "https://shop.example/product/demo-1",
"html": "\u003cscript type=\"application/ld+json\"\u003e{\"@type\":\"Product\",\"sku\":\"DEMO-1\",\"offers\":{\"@type\":\"Offer\",\"price\":\"80\",\"priceCurrency\":\"GBP\"}}\u003c/script\u003e",
"evidence_label": "synthetic_tutorial"
}
],
"mode": "simulation",
"checkedAt": "2026-10-06T07:00:00Z",
"fetchPublicUrls": false
}\u003c и \u003e — допустимая запись угловых скобок внутри JSON. После чтения JSON поле html содержит обычный блок JSON-LD. fetchPublicUrls: false отключает загрузку страниц: этот пример использует только переданный HTML.
Запусти Actor и открой результаты в dataset — таблице этого запуска. Ожидается одна строка:
| Поле | Значение | Как прочитать |
|---|---|---|
sku | DEMO-1 | Проверяемый артикул |
expected | 100 | Ожидаемая цена после акции |
observed | 80 | Цена в переданной разметке |
status | mismatch | Цены различаются |
classification | unbaselined_issue | Разница найдена, прежнего результата нет |
evaluation_mode | simulation | Учебная проверка для выбранного времени |
pointer | 0:/offers | Место цены в JSON-LD |
Теперь замени checkedAt на 2026-10-06T06:59:59Z и повтори запуск. За секунду до конца акции ожидается £80, результат будет clear. Разметка в обоих запусках одинаковая. Эти два учебных времени не доказывают, что настоящий магазин менял цену.
В хранилище запуска также появляются SUMMARY — сводка, audit.csv — таблица для выгрузки, и BASELINE — полный результат для следующего сравнения. Подробнее о запуске и результатах — в инструкции Apify.
Как понять, что проблема новая
Сначала выполни пример для 06:59:59. Скопируй весь массив из записи BASELINE этого запуска. Добавь его во вход следующего запуска как baseline, затем верни checkedAt к 07:00.
Теперь результат будет new_issue: по сравнению с более ранним совместимым учебным результатом появилось различие £100/£80. Набор из двух полей «артикул + цена» не заменяет полный массив BASELINE.
Если такая же разница уже была, возможен existing_issue. Если прежняя разница исчезла, возможен resolved. Изменение товара, условий каталога или неподходящее время baseline может сделать результаты несопоставимыми.
Для настоящей акции нужны два свежих снимка HTML, которые ты вправе использовать: до и после границы. Выбери mode: "observed", укажи для каждого снимка captured_at с часовым поясом и передай полный более ранний BASELINE в следующий запуск. checkedAt можно убрать; если оставить, оно должно точно совпадать со временем снимка. Старый HTML не становится новым наблюдением от повторного запуска.
Когда нужен ручной разбор
needs_review означает, что данных недостаточно для вывода. Например, не найден нужный SKU, подходит несколько Offer, различаются валюты, сломана JSON-LD или неоднозначен учёт налога. Налоговая база price_basis — твоё явное описание данных, а не автоматически проверенный налоговый режим. Вариант товара пока сопоставляется только по точному значению Product size.
Для подходящих общедоступных страниц можно отдельно включить fetchPublicUrls. Есть ограничения: до трёх попыток загрузить страницы, до шести HTTP запросов вместе с robots-проверками. Переадресации, cookies, закрытые адреса и браузер с JavaScript не поддерживаются. Для других разрешённых данных можно передать свой снимок HTML.
clear сообщает только о совпадении заданных статических полей. Видимая цена, доставка, остатки, география, индивидуальные скидки, корзина, JavaScript и одобрение Google остаются за пределами проверки. Инструмент сохраняет свидетельства для разбора и не исправляет магазин автоматически.
Попробовать Merchant Sale Transition Audit можно сначала на примере выше. После этого возьми небольшой набор собственных товаров с точными условиями акции.
