Если вы когда-нибудь писали CSS-селекторы для автоматизации браузера, парсинга страниц или блокировки нежелательных элементов, то наверняка сталкивались с ситуацией: вчера селектор работал, а сегодня перестал находить нужный элемент.

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

Я столкнулся с этой проблемой при разработке BlockIt — расширения для Chrome, позволяющего блокировать нежелательные элементы на веб-страницах.

В какой-то момент мне понадобился инструмент, который помог бы понять, какие части DOM действительно остаются неизменными при повторных загрузках страницы.

Так появился StableHTMLFinder.

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

Проблема: DOM постоянно меняется

Представим, что нам нужно скрыть рекламный блок на сайте.

Открываем DevTools, выбираем элемент и видим примерно такой HTML:

<div class="ad-container_x7Kp2"> <div class="banner_9fA31"> Рекламное объявление </div> </div> 

Можно написать селектор:

.ad-container_x7Kp2 

Он работает. Но после обновления страницы HTML уже выглядит иначе:

<div class="ad-container_m4Rz8"> <div class="banner_2qB76"> Рекламное объявление </div> </div> 

Селектор перестаёт находить элемент.

Конечно, можно попробовать использовать частичное совпадение класса:

[class^="ad-container_"] 

Но такой подход работает лишь тогда, когда изменяемые значения сохраняют предсказуемую структуру.

А если меняются не только классы, но и идентификаторы, атрибуты, количество вложенных элементов или расположение блока?

Приходится изучать окружающую структуру страницы и искать более надёжные ориентиры.

Именно здесь возникает главная проблема: как отличить действительно стабильные признаки DOM от тех, которые лишь случайно выглядят стабильными при текущей загрузке?

Почему одного снимка DOM недостаточно

Большинство привычных инструментов генерации селекторов анализируют текущее состояние страницы.

Они могут определить уникальный класс, идентификатор, построить CSS-путь или XPath.

Однако уникальность и стабильность — совершенно разные свойства.

Например:

<button id="action_583921" class="btn_8xQ2"> Продолжить </button> 

Идентификатор action_583921 может быть уникальным на странице. Но это ничего не говорит о том, сохранится ли он после обновления.

Инструмент, который видит только один снимок DOM, не может непосредственно наблюдать изменение этого идентификатора между загрузками.

Конечно, существуют эвристики, позволяющие предположить, что определённый класс или идентификатор генерируется динамически. Но предположение не заменяет наблюдение.

Когда я начинал разрабатывать StableHTMLFinder в 2026 году, мне не удалось найти инструмент, который автоматически собирал бы несколько снимков одной страницы и на их основе строил наглядную карту устойчивых элементов и их признаков.

При этом я не хотел создавать ещё один генератор селекторов.

Первоначальная идея была гораздо проще: убрать из DOM весь нестабильный информационный шум и посмотреть, что останется.

Карта стабильности DOM

StableHTMLFinder — бесплатное расширение для Chrome, которое анализирует несколько последовательных загрузок веб-страницы и строит на их основе карту стабильности.

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

Допустим, при нескольких загрузках страницы встречается один и тот же элемент:

Первая загрузка:

<section class="content_a72" data-session="1842"> <h2 class="section-title">Новости</h2> </section> 

Вторая загрузка:

<section class="content_b91" data-session="7501"> <h2 class="section-title">Новости</h2> </section> 

Третья загрузка:

<section class="content_c38" data-session="3926"> <h2 class="section-title">Новости</h2> </section> 

В этом упрощённом примере можно заметить:

  • Тег section сохраняется.
  • Атрибут class присутствует, но его значение меняется.
  • Атрибут data-session присутствует, но его значение тоже меняется.
  • Дочерний элемент h2 и его класс остаются неизменными.

Если сопоставление элементов между загрузками достаточно надёжно, карта может представить эту структуру примерно так:

<section class data-session> <h2 class="section-title"> Новости </h2> </section> 

Это схематический пример, а не точное представление интерфейса StableHTMLFinder.

Обратите внимание: имена атрибутов class и data-session остались, а их нестабильные значения исчезли.

Таким образом, карта позволяет различать несколько ситуаций:

  • Стабилен элемент вместе с атрибутами и их значениями.
  • Стабилен элемент и наличие определённых атрибутов, но не их значения.
  • Удалось установить стабильность самого элемента, но его атрибуты не дают надёжных ориентиров.

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

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

На скриншоте показан фрагмент карты стабильности DOM, построенной расширением StableHTMLFinder. Зелёным цветом выделены стабильные элементы и их атрибуты, сохраняющиеся при повторных загрузках страницы. Один из элементов, ссылка <a>, раскрыт для просмотра дополнительной информации. Для него StableHTMLFinder сформировал CSS-селектор и правило для расширения BlockIt, которые можно скопировать одним нажатием. Древовидная структура карты позволяет исследовать вложенные элементы и их атрибуты, а также переходить от анализа стабильности DOM к практическому использованию найденных селекторов.

Полностью и относительно стабильные элементы

Не все элементы удаётся сопоставить между загрузками с одинаковой уверенностью.

Поэтому StableHTMLFinder различает полностью и относительно стабильные элементы.

Полностью стабильные элементы — наиболее надёжные участки карты. Их собственные признаки, а также соответствующие признаки родительских и непосредственно дочерних элементов совпадают между наблюдениями.

Такие элементы служат хорошими ориентирами при анализе структуры страницы.

Относительно стабильные элементы — элементы, для которых имеются достаточные основания считать, что в разных загрузках речь идёт об одном и том же DOM-узле, хотя часть признаков или окружающей структуры изменяется.

На карте они выделяются более светлым цветом.

Это важное различие: StableHTMLFinder не утверждает, что всё на странице либо абсолютно неизменно, либо полностью непригодно для анализа.

В реальных веб-приложениях ситуация гораздо сложнее.

Элемент может сохранять своё назначение, но менять классы. Его родитель может получать новые атрибуты. Между двумя знакомыми элементами могут появляться дополнительные контейнеры.

Поэтому полезно видеть не только абсолютно стабильные участки, но и те, для которых удалось установить относительную стабильность.

Островки стабильности внутри динамического DOM

Одна из наиболее интересных особенностей StableHTMLFinder — способность отображать островки стабильности.

Представим, что между загрузками страницы меняется целая цепочка вложенных контейнеров.

В одном случае нужный элемент находится внутри двух промежуточных блоков, в другом — внутри четырёх. Их классы и атрибуты также могут различаться.

Но где-то внутри этой нестабильной структуры сохраняется элемент с узнаваемыми признаками.

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

StableHTMLFinder сохраняет такие стабильные участки на карте, а разделяющую их нестабильную структуру обозначает специальным серым элементом <...>.

Они выглядят как элементы дерева, но фактически обозначают изменяющуюся структуру произвольной вложенности. Этот элемент может представлять произвольное количество нестабильных уровней вложенности, а не только один пропущенный узел.

В результате пользователь видит, что между стабильными участками страницы существует нестабильная область, но при этом не теряет возможность исследовать расположенные внутри неё элементы.

Это особенно полезно на страницах, где JavaScript динамически перестраивает отдельные части интерфейса.

Поиск элементов на карте стабильности

Допустим, вы обнаружили на сайте элемент, который хотите заблокировать.

Открыли DevTools, нашли соответствующий HTML, но его классы и идентификаторы выглядят случайными.

Вместо ручного исследования множества родительских и дочерних узлов можно воспользоваться поиском StableHTMLFinder.

Он позволяет искать элементы на карте несколькими способами, в том числе:

  • Вставить HTML-элемент, скопированный из DevTools.
  • Указать селектор для поиска нужного элемента.

Если элемент присутствует на карте стабильности, можно перейти к его карточке и изучить доступные устойчивые признаки.

Это позволяет быстро перейти от исходного DOM, заполненного динамическими значениями, к его очищенному представлению.

Особенно удобно, когда проблемный элемент сам по себе не содержит подходящих признаков, но рядом с ним находятся более стабильные элементы.

Как повысить точность поиска

StableHTMLFinder выполняет поиск преимущественно по последнему снимку DOM, полученному во время анализа страницы.

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

Если же вы скопировали элемент, который был уже изменён после последнего снимка DOM, поиск всё ещё может оказаться успешным. StableHTMLFinder попытается сопоставить его с элементами карты по сохранившимся признакам, однако уверенность в результате будет ниже.

Автоматическая генерация селекторов

Хотя StableHTMLFinder изначально задумывался как инструмент визуального анализа DOM, впоследствии я добавил автоматическую генерацию селекторов.

Это оказалось естественным продолжением основной идеи.

Если инструмент уже определил стабильные признаки элемента и его окружения, почему бы не попробовать автоматически построить селектор на их основе?

В карточке элемента можно получить предложенный селектор и скопировать его.

Рядом отображается текстовое объяснение, позволяющее понять, на каких признаках он основан.

Это важно, потому что селектор не должен оставаться для пользователя непонятной строкой.

Однако здесь есть важное ограничение.

В особо сложных случаях StableHTMLFinder может оказаться не в состоянии сформировать уникальный селектор для определённого элемента.

Хотя расширение обычно успешно формирует уникальные селекторы, у некоторых элементов отсутствует уникальная комбинация стабильных признаков в их ближнем окружении DOM. В таких редких случаях StableHTMLFinder явно сообщает, что сформировать уникальный селектор не удалось.

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

Именно поэтому я рассматриваю генерацию селекторов как вспомогательную возможность, а не как основное назначение расширения.

Как StableHTMLFinder связан с BlockIt

StableHTMLFinder появился в процессе работы над другим моим проектом — BlockIt.

BlockIt — расширение Chrome для блокировки нежелательных элементов на веб-страницах.

Оно позволяет создавать правила с использованием CSS, XPath и дополнительных условий, а также применять более сложные способы поиска элементов.

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

StableHTMLFinder помогает найти более надёжные ориентиры для таких правил.

При этом два расширения решают разные задачи:

StableHTMLFinder анализирует страницу, показывает карту стабильности и помогает создавать селекторы. Само расширение ничего не блокирует.

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

StableHTMLFinder также может предлагать специальные правила, предназначенные для использования в BlockIt.

Таким образом, одно расширение помогает исследовать DOM и подготовить правило, а другое — применить его на практике.

Подробнее о BlockIt я расскажу в отдельной статье.

Может ли StableHTMLFinder быть полезен за пределами блокировки рекламы?

Хотя проект возник из задачи блокировки нежелательных элементов, сама проблема нестабильных DOM-локаторов встречается и в других областях.

Например, при разработке браузерной автоматизации и UI-тестов.

Если тест использует динамический класс, он может перестать работать после изменения страницы, даже когда нужная кнопка или форма по-прежнему существует.

Карта стабильности потенциально может помочь разработчику определить более надёжные ориентиры.

Аналогичная задача иногда возникает при создании скриптов, взаимодействующих с веб-страницами, и инструментов извлечения данных.

Однако StableHTMLFinder не является универсальным решением для этих сценариев. Его возможности зависят от структуры конкретного сайта и наличия признаков, которые сохраняются между загрузками.

Кроме того, стабильность, установленная на основании нескольких наблюдений, не означает, что элемент никогда не изменится в будущем.

Карта отражает результаты проведённого анализа, а не даёт абсолютную гарантию.

Почему я считаю этот подход полезным

При разработке StableHTMLFinder я хотел изменить сам процесс работы с DOM.

Обычно разработчик открывает DevTools, видит огромное дерево элементов и пытается самостоятельно определить, какие признаки пригодны для селектора.

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

StableHTMLFinder предлагает другой подход:

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

Это не устраняет все сложности динамического DOM и не делает селекторы неуязвимыми к изменениям сайта.

Но позволяет сосредоточиться на более надёжной информации и избежать значительной части ручной работы.

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

Попробуйте StableHTMLFinder

StableHTMLFinder — бесплатное расширение для Chrome.

Если хотите попробовать его в работе, посетите официальную страницу проекта StableHTMLFinder, где вы найдёте ссылку для установки расширения из Chrome Web Store.

Если вы работаете с динамическими веб-страницами, мне было бы интересно узнать, с какими проблемами стабильности селекторов вы сталкивались и как подходили к их решению.