Изменения на сайтах
Следите за содержимым веб-страницы или всего сайта и получайте уведомление, когда оно меняется: страница с ценами или условиями, сайт документации, уведомление поставщика о техобслуживании, страница публичных объявлений или ваш собственный сайт после развёртывания. Каждое изменение сохраняется с текстом до и после, построчным diff и, если доступен браузер, снимком экрана каждой версии.
Сравнивается видимый текст каждой страницы, а не её HTML: скрипты, стили,
комментарии, блоки noscript, svg и template отбрасываются, пробельные
символы схлопываются, а каждый блок (абзац, заголовок, элемент списка, строка
таблицы) становится одной строкой. Новая сборка той же страницы, изменённый
порядок атрибутов или новое имя ресурса с защитой от кэша ничего не меняют;
переформулированное предложение — меняет.
Какая часть страницы
Заголовок раздела «Какая часть страницы»Навигация, шапка, подвал и боковые панели сайта не учитываются: они одинаковы
на каждой странице, и иначе новый пункт меню пометил бы все страницы как
изменённые за одну проверку. Они определяются по ролям, которые даёт HTML: любой
nav, header или footer, не находящийся внутри article, aside, main,
nav или section (шапка статьи сохраняется), aside вне article и main, и
любой элемент с ролью navigation, banner, contentinfo или search. Их
ссылки по-прежнему обходятся, чтобы находить страницы сайта. Опция Compare
menus, header and footer отключает это исключение.
Watched area ограничивает сравнение некоторыми элементами, например main
или #content; страница, на которой ни один из них не найден, читается целиком, а
не как пустая. Excluded areas исключает дополнительные элементы: баннер
cookie, блок «последние записи», рекламное место. Оба поля принимают простые
селекторы через запятую: тег (main), идентификатор (#content), классы
(.cookie-banner), атрибуты ([role=alert], [data-ad]) или несколько из них
вместе (div.notice[role=alert]). Потомки (main p) и другие комбинаторы не
поддерживаются.
Страница или сайт
Заголовок раздела «Страница или сайт»Page (по умолчанию) читает только адрес монитора и ничего больше. Это может быть и обычный текстовый или JSON-документ, сравниваемый построчно.
Site начинает с адреса и обходит все страницы в той же папке
(https://example.com/docs/intro.html охватывает всё под /docs/;
Path prefix выбирает другую папку). Страницы находятся:
- в карте сайта: в тех, о которых сообщает
robots.txt(строкиSitemap:), или в/sitemap.xml, включая индексы карт сайта (один уровень); - если этого нет или если карта сайта ничего не содержит под этой папкой — по ссылкам каждой страницы, в ширину.
Обходятся только страницы того же origin (схема, хост и порт). Если начальная
страница перенаправляет на другой хост того же сайта (example.com на
www.example.com, http на https или поддомен вроде docs.example.com),
считается, что сайт находится там, и ссылки на первый хост читаются на втором.
Если она перенаправляет на совсем другой сайт (страница входа вроде
login.microsoftonline.com, сторонний домен), этот сайт не обходится: читается
только начальная страница, и ни одна страница не сообщается как удалённая.
Ссылки на изображения, таблицы стилей, скрипты, PDF, архивы и другие файлы
пропускаются по расширению, а любой ответ, не являющийся HTML, игнорируется.
Фрагменты (#section), параметры отслеживания (utm_…, fbclid, gclid и
подобные) и пустые запросы удаляются, так что одна страница — это один адрес;
опция Ignore query strings отбрасывает всю часть ?…. Для страниц, найденных таким способом, соблюдается robots.txt:
группа, названная DumbMonit, а при её отсутствии группа *, с Allow,
Disallow, * и $.
Обход вежливый: не более двух запросов одновременно, полсекунды между двумя
пакетами, User-Agent DumbMonit/<version>, тайм-аут 15 секунд на запрос и не
более 5 МБ чтения на страницу. Он останавливается на Max pages (по умолчанию
25, максимум 200) или через десять минут. Если его остановил Max pages,
страница монитора сообщает, сколько страниц найдено, чтобы ненаблюдаемая часть
сайта не стала сюрпризом. User agent заменяет DumbMonit/<version> для сайта,
который отсекает роботов.
Как работает проверка
Заголовок раздела «Как работает проверка»Монитор опрашивается как любой другой (по умолчанию каждую минуту), но страницы читаются только раз в Check every минут (по умолчанию 60, от 5 до 10080). В промежутках опрос лишь сообщает состояние последней проверки: сайт не нагружается каждую минуту. Проверка выполняется в фоне; две проверки одного монитора никогда не пересекаются, а Check now на странице монитора запускает проверку немедленно.
Первая проверка только записывает эталон: каждая страница читается и сохраняется, ничего не сообщается. Начиная с этого момента для каждой страницы:
| Ситуация | Что сохраняется |
|---|---|
| Тот же текст, что и в прошлый раз (после Ignore lines) | Ничего нового; страница помечается как проверенная. |
| Другой текст | Новый снимок и событие changed с числом добавленных и удалённых строк. |
| Страница, которой раньше не было, или которая появилась снова после исчезновения | Снимок и событие new page. |
| Страница отвечает 404 или 410 | Событие removed page, последний снимок как «до». |
| Область «сайт»: полный обход больше не достигает известной страницы | Тоже событие removed page («No longer linked»). Обход, остановленный по Max pages или по лимиту времени, никогда не делает вывода, что страница исчезла. |
| Любая другая ошибка на странице (тайм-аут, 403, 500 на вложенной странице) | Ошибка показывается на странице; события нет. |
Смена адреса, области, префикса пути, Max pages, областей или Ignore lines делает следующую проверку новым эталоном, вместо того чтобы сообщать, что изменилась каждая страница (а при увеличении Max pages — что новой стала каждая добавленная страница). Обновление DumbMonit, которое иначе читает страницы, делает то же самое один раз.
Если одна проверка находит одно и то же изменение на нескольких страницах (те же удалённые и добавленные строки, например баннер), страница монитора показывает его один раз, с перечнем страниц, на которых оно произошло.
Ignore lines
Заголовок раздела «Ignore lines»Строки, меняющиеся при каждом посещении, — часы, счётчик посетителей, «обновлено
5 минут назад», случайная цитата — сообщались бы при каждой проверке. Ignore
lines содержит регулярные выражения (синтаксис Rust regex), по одному в
строке или через |; любая текстовая строка, которой соответствует одно из них,
исключается перед сравнением. Например:
Updated \d+ minutes ago|Visitors: \d+|© \d{4}Недоступная начальная страница
Заголовок раздела «Недоступная начальная страница»Когда саму начальную страницу не удаётся прочитать (нет ответа, соединение отклонено, тайм-аут, HTTP 5xx), монитор недоступен: опрос завершается ошибкой, и правило «Monitor unreachable» срабатывает как для любого монитора. Начальная страница затем перепроверяется при каждом опросе, поэтому её возвращение заметно в течение минуты. Начальная страница, отказывающая в доступе (401, 403), сообщается как проблема конфигурации, а не как сбой. Ошибки на других страницах сайта показываются только на этих страницах.
Адреса, доступные только самому хосту DumbMonit (loopback, link-local, служба метаданных облака), отклоняются, если не включена опция Allow loopback and link-local targets; адреса частной LAN разрешены всегда.
Оповещения
Заголовок раздела «Оповещения»Встроенное правило Website changed (webchange_detected, Info) срабатывает
после проверки, обнаружившей хотя бы одно изменение (изменённая, новая или
удалённая страница), и уведомление называет страницы: «/pricing, /contact и ещё
2». Пока оповещение активно, каждая следующая проверка, находящая изменения,
уведомляет снова, со своими страницами, даже если страницы те же; оповещение
снимается при первой проверке, не нашедшей ничего нового. Оно остаётся одним
оповещением на монитор всё это время, поэтому подтверждение или откладывание
оповещения охватывает и последующие проверки. Оно читает
dumbmonit_webchange_last_check_changes; привяжите его к каналу, как
любое другое правило, или повысьте его серьёзность в Alerts → Rules. См.
Встроенные правила.
| Метрика | Что |
|---|---|
dumbmonit_webchange_pages | Обойдённые страницы (удалённые не учитываются). |
dumbmonit_webchange_pages_failed | Обойдённые страницы, последнее чтение которых завершилось ошибкой. |
dumbmonit_webchange_last_check_changes | Изменения, найденные последней проверкой. |
Метрики появляются после завершения первой проверки.
Снимки экрана
Заголовок раздела «Снимки экрана»В образе DumbMonit нет браузера: снимки экрана делает необязательный headless
Chromium, управляемый по Chrome DevTools Protocol. Добавьте его как службу browser рядом с DumbMonit в docker-compose.yml и
укажите на него серверу:
services: dumbmonit: environment: DUMBMONIT_BROWSER_URL: http://browser:9222 browser: image: chromedp/headless-shell:stable shm_size: 256m restart: unless-stoppedЗатем выполните docker compose up -d. Порт браузера никуда не публикуется: с
ним общается только сервер DumbMonit, по сети Compose.
DUMBMONIT_BROWSER_URL указывает DumbMonit на браузер (подойдёт любой Chromium,
запущенный с --remote-debugging-port, например chromedp/headless-shell;
сервер читает /json/version и обращается к адресу, в который разрешается имя
хоста).
Снимок экрана делается только тогда, когда страница получает новый снимок (эталон и каждое изменение), и никогда при неизменённой проверке: окно 1366 × 900, вся страница до 5000 пикселей, в формате JPEG. Опция Screenshots отключает их для одного монитора. Без браузера или когда он не отвечает, текстовое сравнение работает так же, а у снимков просто нет изображения; страница монитора сообщает об этом.
Браузер загружает страницу так, как это делал бы посетитель, вместе со скриптами: то, что он показывает, может отличаться от текста, который сравнил DumbMonit, — то есть от HTML, отправленного сервером.
Хранение
Заголовок раздела «Хранение»Текст каждого снимка хранится в базе данных (не более 1 МБ на страницу); снимки
экрана — это файлы в /data/webchange/<device id>/. На монитор хранятся
последние 500 изменений; снимок хранится, пока он является последним для
страницы или на него ссылается сохранённое изменение, а всё остальное, включая
файлы, удаляется после каждой проверки. Удаление монитора удаляет всё это.
Следить за изменениями на сайте
Заголовок раздела «Следить за изменениями на сайте»Ниже приведены шаги, которые показывает уведомление рядом с формой.
- В адресе вставьте страницу для наблюдения, с http:// или https://. Чтобы следить за всем сайтом или одним из его разделов, вставьте его начальную страницу и установите «Scope» в «site»: будут обойдены все страницы в той же папке, до «Max pages».
- Строки, меняющиеся при каждом посещении (часы, счётчик посетителей, «обновлено 5 минут назад»), сообщались бы каждый раз: перечислите их в «Ignore lines» как регулярные выражения.
- Первая проверка только записывает эталон, ничего не сообщается. Начиная с этого момента каждая проверка сравнивает видимый текст страница за страницей и сохраняет копию «до/после» каждого изменения, показываемую на странице монитора; об изменении сообщает оповещение «Website changed».
- Чтобы получать снимок экрана каждой версии, добавьте в файл Compose headless-браузер; точные строки приведены в документации (Дополнительные параметры, «Снимки экрана при изменениях сайтов»). См. Снимки экрана при изменениях сайтов.
Учётные данные: нет. Проверки всегда выполняются на сервере DumbMonit: наблюдение за сайтом не может идти через relay-агент.
Параметры
Заголовок раздела «Параметры»| Параметр | По умолчанию | Значение |
|---|---|---|
Scope (scope) | page | page: только адрес. site: все страницы в той же папке. |
Max pages (max_pages) | 25 | Область «сайт»: максимум страниц, читаемых за проверку, от 1 до 200. |
Path prefix (path_prefix) | папка адреса | Область «сайт»: только страницы, путь которых начинается с этого (/docs/). |
Ignore lines (ignore) | — | Регулярные выражения; соответствующие им текстовые строки не сравниваются. |
Watched area (content_selector) | — | Простые селекторы; сравнивается только текст внутри них. |
Excluded areas (exclude_selector) | — | Простые селекторы; их текст не сравнивается. |
Compare menus, header and footer (keep_page_chrome) | false | Сравнивать также навигацию, шапку, подвал и боковые панели сайта. |
Ignore query strings (ignore_query) | false | Область «сайт»: адреса, отличающиеся только частью ?…, считаются одной страницей. |
User agent (user_agent) | — | Отправляется вместо DumbMonit/<version>. |
Screenshots (screenshots) | true | Хранить снимок экрана каждой новой версии, если настроен браузер. |
Check every (check_interval_minutes) | 60 | Минут между двумя проверками, от 5 до 10080. |
Accept an unverifiable certificate (insecure_tls) | false | Для вашего собственного сайта с самоподписанным сертификатом. |
Allow loopback and link-local targets (allow_private_targets) | false | Обращаться к сайту, который обслуживает сам хост DumbMonit. |