Клики с помощью JS path на JavaScript, С# как получить isTrusted:true действиями Zennoposter. v1.14

prostors

Client
Регистрация
16.12.2020
Сообщения
1 456
Благодарностей
79
Баллы
48
Я попробовал на базовых действиях, с помощью css селекторов и xpath, были срабатывания через раз, было игнорирование кликов.

В качестве рабочего решения нормально себя показал js path на javascript.

js path берём из devtools:
141193
,
что позволило нормально отработать с shadow root (opened) и клики срабатывали более стабильно.

мы берём js path и с помощью фри версии gemini просим создать клик на кнопке, иногда просто click() не срабатывает и нужен ещё и фокус, но всё равно, в итоге клик удаётся реализовать и клик принимает сайт

тема подсмотрена мной на ютубе, кому интересно можете поискать по shadow root или shadow dom.

в результате того, что сайты постоянно меняют вёрстку, приходится js path обновлять и это привело к тому, что об ошибке я настроил уведомления в телеграмм бота со скриншотами



Выводы:
  • добавить js path в конструктор действий и контекстное меню(правой кнопкой мыши) в зеннопостер
  • добавить вывод оповещений, не в tg или другие сервисы, а внутри зенно, сейчас лог очень общий и туда сыпется всё подряд, сделать отдельную вкладку для важных оповещений
  • добавить вывод события isTrusted: true, которое только для чтения, в PM для отслеживания кликов и других действий, я так понял, что результат по этому событию отдаёт браузер и его можно получить и вывести в информер
  • https://zenno.club/discussion/threads/kliki-s-pomoschju-js-path-na-javascript-kak-poluchit-istrusted-true-dejstvijami-zennoposter.132374/post-877090 предложение по развитию интерфейса

Иллюзия «Closed» режима и как его взломать
Мы говорили, что Shadow DOM бывает open (доступен через .shadowRoot) и closed (возвращает null). Многие разработчики думают, что closed — это надежная защита от парсинга. Это не так.

твой скрипт запускается до того, как сайт создал свои компоненты (на этапе document-start), ты можешь перехватить создание теневых деревьев:

Как обойти Closed режим Shadow Root:
// Перехватываем нативный метод attachShadow
const originalAttachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function(options) {
    // Принудительно делаем ВСЕ закрытые деревья открытыми
    if (options.mode === 'closed') {
        options.mode = 'open';
    }
    return originalAttachShadow.call(this, options);
};

клик на с# по js path срабатывает для instance.ActiveTab.MainDocument.EvaluateScript("document.querySelector('...').click();");

клик, который отдаёт isTrusted true instance.ActiveTab.FullEmulationMouseClick("left", "click"); по координатам:

прикрепляю шаблон 7.8.15 с 3 действиями - поиск координат по js path, split по разделителю для получения 4-х координат и клик мышью с полной эмуляцией, распределение равномерное
141365


но, в рамках соблюдения анонимности, я не рекомендую дёргать js path или xpath каждый раз при поиске координат кнопок, а рекомендую 1 раз собрать и хранить координаты в txt файле.

прикрепляю шаблон с получением isTrusted - true с кликом по координатам

очередное обновление:
мои разрешения экранов для кликов по координатам

1903x937
1903x850
1519x820
1349x650
1349x700
и тд

xml, который я сохраняю в файл, для каждого размера экрана браузера:

xml для координат кликов по кнопкам:
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <objectName>{-Variable.displayx-}</objectName>
  <display{-Variable.displayx-}>
    <Avatar name="Avatar">
      <coords x1="{-Variable.x1-}" y1="{-Variable.y1-}" x2="{-Variable.x2-}" y2="{-Variable.y2-}" />
    </Avatar>
    <usermenu name="usermenu">
      <coords x1="{-Variable.x1usermenu-}" y1="{-Variable.y1usermenu-}" x2="{-Variable.x2usermenu-}" y2="{-Variable.y2usermenu-}" />
    </usermenu>
        <downloadbanner name="downloadbanner">
      <coords x1="{-Variable.x1downloadbanner-}" y1="{-Variable.y1downloadbanner-}" x2="{-Variable.x2downloadbanner-}" y2="{-Variable.y2downloadbanner-}" />
    </downloadbanner>
        <upload name="upload">
      <coords x1="{-Variable.x1upload-}" y1="{-Variable.y1upload-}" x2="{-Variable.x2upload-}" y2="{-Variable.y2upload-}" />
    </upload>
        <savebanner name="savebanner">
      <coords x1="{-Variable.x1savebanner-}" y1="{-Variable.y1savebanner-}" x2="{-Variable.x2savebanner-}" y2="{-Variable.y2savebanner-}" />
    </savebanner>
  </display{-Variable.displayx-}>
</root>
файл храню на сервере и подгружаю для каждого запуска

Помощь с JS path и сайтами закрытыми с помощью Shadow Dom - бесплатно!

прикрепляю к теме шаблон с MouseClick и FullEmulationMouseClick в результате isTrusted:true на С# с координатами

добавляю шаблон со слушателем кликов и получением js path, с тестами и проверками
 

Вложения

Последнее редактирование:

prostors

Client
Регистрация
16.12.2020
Сообщения
1 456
Благодарностей
79
Баллы
48
я не рекомендую дёргать js path
Логирование вызовов querySelector / querySelectorAll
Это самый эффективный метод, если вы хотите узнать, когда и какой JS path запрашивается. Вы перехватываете стандартный метод document.querySelector и внедряете туда свой логгер.

Логирование вызовов querySelector / querySelectorAll. Код для работы с сайтом со стороны посетителя:
(function() {
    const originalQuery = document.querySelector;

    document.querySelector = function(selector) {
        // Логируем обращение
        console.log(`[DOM Access] Selected: "${selector}"`);
     
        // Опционально: можно добавить фильтр, чтобы не засорять консоль
        // if (selector.includes('my-target-element')) { debugger; }

        return originalQuery.apply(this, arguments);
    };
})();
Нюанс для ZennoPoster: Вставляйте этот код в самом начале выполнения проекта. Поскольку ZennoPoster работает в рамках текущей сессии браузера, этот «хук» будет действовать до перезагрузки страницы или навигации.
 

prostors

Client
Регистрация
16.12.2020
Сообщения
1 456
Благодарностей
79
Баллы
48
Ну так сразу и показывайте как это делать. Зачем нам лекции по основам JS? Нужно каждый пример адаптировать под использования в ZP
вывод в переменную массива history, а не в консоль devtools:
function createTrackedProxy(el) {
    const history = [];

    const proxy = new Proxy(el, {
        get(target, prop, receiver) {
            const value = Reflect.get(target, prop, receiver);

            if (typeof value === 'function') {
                return function(...args) {
                    history.push({
                        type: 'method_call',
                        name: prop,
                        args,
                        timestamp: Date.now()
                    });
                    return value.apply(target, args);
                };
            }
            return value;
        },
        set(target, prop, value, receiver) {
            history.push({
                type: 'property_set',
                prop,
                value,
                timestamp: Date.now()
            });
            return Reflect.set(target, prop, value, receiver);
        }
    });

    return { proxy, history };
}

// --- Пример использования ---
// const { proxy, history } = createTrackedProxy(document.querySelector('.my-element'));
// proxy.style.color = 'blue';
// proxy.click();
// console.log(history); // Вся информация здесь
код взят из ИИ
 
Последнее редактирование:

Alex.A

Client
Регистрация
14.11.2020
Сообщения
563
Благодарностей
321
Баллы
63
Проголосовал. Спасибо за статью!
 
  • Спасибо
Реакции: prostors

prostors

Client
Регистрация
16.12.2020
Сообщения
1 456
Благодарностей
79
Баллы
48
Мониторинг Shadow DOM
Работая с Shadow DOM, стандартный querySelector может не «видеть» элементы внутри shadowRoot. Если вам нужно логировать обращения и внутри Shadow DOM, вам придется рекурсивно навесить хуки на все найденные shadowRoot в дереве.

Мониторинг Shadow DOM - логирование:
function hookShadowRoots(node) {
    const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, null, false);
    while(walker.nextNode()) {
        if (walker.currentNode.shadowRoot) {
            // Подменяем querySelector внутри shadowRoot
            const root = walker.currentNode.shadowRoot;
            const originalQuery = root.querySelector;
            root.querySelector = function(selector) {
                console.log(`[Shadow DOM Access] Selector: ${selector}`);
                return originalQuery.apply(this, arguments);
            };
        }
    }
}
hookShadowRoots(document.body);
не тестировал, используйте, все проблемы и баги решая с помощью ИИ
 

prostors

Client
Регистрация
16.12.2020
Сообщения
1 456
Благодарностей
79
Баллы
48
поскольку мне говорят(но без подтверждений), что контент создан ИИ и вы сами можете скопировать сами из ИИ, выкладываю удалённый контент, сформированный кем? правильно, нужно узнать кем и предоставить аргументы более веские, чекер в студию

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




т.е. создать 4 новых кнопки для:
1. уже есть - css селектор, разделить, сделать отдельно от xpath
2. добавить клики по xpath - есть, но надо переключать внутри действия и будет собираться и css селектор и xpath сразу, а нужно что-то одно, т.е. разделить, чтобы не было 2 обращения к сайту, когда достаточно одного обращения
3. добавить клики по js path
4. добавить клики по координатам, с заданием площадей, скрин добавляю, для равномерных кликов

141561


5. добавить клики по картинкам
141562


любое обращение к css селектору, xpath, js path может логироваться для отслеживания ботов



обновление.
Разберём ситуацию по выявлению причин и обновлению проекта:
1. результаты по проекту совсем пропали;
2. мы начинаем проверять сайт, с которым работаем;
3. в результате находим, что появился блок на сайте, который логирует количество обращений к xpath, js path или css селекторам или isTrusted;
4. переводим проект на клики по координатам или по клики по картинкам, предварительно проверив эффективность руками в 2-3 или более прогонов;
5. проект заработал и снова приносит результат.

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




обновление от ИИ
В современных браузерах (особенно в Safari и Chrome на экранах с высокой плотностью пикселей) события PointerEvent и TouchEvent могут содержать дробные значения координат (например, clientX: 100.5). В то же время старые методы эмуляции часто оперируют только целыми числами. Использование исключительно целых координат на устройствах, которые по своему отпечатку (fingerprint) должны поддерживать дробную точность, является статистической аномалией, используемой для детекции ботов.
у нас при клике по координатам нет десятичных, сотых и тд, есть предложение добавить в возможности



обновление.
задача на обсуждение для антифрода.
ситуация-кейс:
  • нужно отследить ботов на сайте;
  • на сайте не использовали js path, xpath, css селекторы при разработке;
  • настраиваем логи на js path, xpath, css селекторы;
  • в случае использования посетителем js path, xpath или css селекторов получаем триггер об этом;
  • очень большая вероятность, что те посетители, которые используют js path, xpath, css селекторы на сайте, который в разработке не использует js path, xpath, css селекторы - боты;
  • выводим таким посетителям страницу-заглушку с капчами и уведомлениями о том, что они боты и могут уйти на другой сайт;
результат - получаем на основании логирования js path, xpath, css селекторы чуть более чистую, от ботов, аудиторию, которую можно более качественно обрабатывать в дальнейших наработках.

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




поговорим про "шум"
задача-кейс:
  • нужно выполнить клик;
  • мы сначала подводим мышку;
  • ждём пока выплывет title или alt или по другому описание во всплывающем окне;
  • дрожим мышкой;
  • делаем, так называемые
    • рывки,
    • плавные замедления
    • микро-промахи (overshoot)
    • корректировки
    • фокус
  • только потом кликаем на кнопке, картинке или другом элементе;
эти все настройки дают human-like - человекоподобное поведение - "шум" - биохакинг движения мыши - биоэмуляцию поведения

аномалии при клике могут, но не исключая, триггернуть системы антифрода
а также повтор уникального поведения, о чём поговорим в следующих комментариях



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

Почему подмена isTrusted возможна, но не будет работать:
  • Свойство isTrusted в интерфейсе Event помечено как readonly;
  • JS-код не имеет прав доступа к изменению состояния этой инициализации.

фокус->действие
  • наведение мышки фокус - клик;
  • наведение мышки фокус - двойной клик;
  • наведение мышки фокус - уточнение наведения мышки со сдвигом - клик;
  • наведение мышки фокус - проверка, нет ли перекрывающего невидимого окна - клик;
  • наведение мышки фокус - проверка, нет ли перекрывающего невидимого окна - уточнение наведения мышки со сдвигом или несколькими сдвигами - клик;
к этому всему, можно ещё добавить ожидание, пока всплывёт title или alt или по другому методу описание во всплывающем окне.




обновление
Поговорим про ловушки ботов на сайтах.
Элементы на сайтах могут прятаться за:
  • opacity: 0;
  • display: none;
  • вывод за пределы видимости с помощью index;
  • Shadow DOM инкапсулирует элементы, делая их полностью недоступными для стандартных методов глобального поиска, таких как document.querySelector или document.getElementById;
  • другие методы.
Могут показываться в рандомное время.
Могут быть дубли, один основной элемент и много ловушек, которые расположены в коде раньше вашей с похожими тегами и атрибутами.
Всё это тригерит поведенческие аномалии.

Можно использовать как решения:
  • клик по координатам;
  • клик по картинке;
оба нужно тестировать, логировать и проверять наработки на большой выборке.

Друзья! Всем успешных выборок и топовых позиций при накрутке!

Берегитесь DOM-приманок (Honeypots)!!!



обновление.
Детектирование: Не был ли изменен document.querySelector.
  • Проверка: document.querySelector.toString() может вернуть function querySelector() { [native code] }. Если вы изменили метод, toString может выдать ваш код или измененную структуру, что является 100% сигналом для антибота.
хочу затронуть тему относительных(Relative Paths) и абсолютных(Absolute URLs / Absolute paths) путей js path и xpath.
В контексте ловушек - есть предположение, что абсолютные пути всё таки лучше. Что имеем:
  • точный адрес - от начала и до конца, хоть и очень длинный;
  • точные размеры высоты и ширины;
  • точное слово-фразу, если есть внутри последнего тега;
  • точные атрибуты;
  • и тд.
На относительных путях мы имеем:
  • динамический путь, который привязан к последнему элементу и уникальному атрибуту;
  • в случае изменений вёрстки - он скорей всего будет работать, даже учитывая, что изменения могли произойти из-за добавления ловушек ботов(honeypot) в код выше или вместо;
  • возможность подставить предварительно ловушку и тогда действие произойдёт с первым попавшимся элементом, а не с нужным-видимым пользователю;
  • и тд.
Выводы:
если мы говорим о выживаемости при смене вёрстки, но не предполагаем ловушек - относительный путь.
если мы говорим о стабильности без смены вёрстки, и если смена вёрстки была - то это скорей всего поставили ловушку ботов - абсолютный путь.

Друзья!
Желаю вам стабильных вёрсток на проектах и чтобы вы через 5 лет после деплоя открывали проект - а шаблон ZennoPoster работает!


прикрепляю шаблон, по которому можно получить абсолютный путь js path с экранированием спецсимволов.
заметьте, что в контекстном меню devtools только относительный путь. мы его вставляем в переменную targetElement в первом js действии в шапке.
в шаблоне пример для сайта reddit клик по кнопке Войти или Log In:
141463



после получения абсолютного пути - кликаем по нему, с помощью click()



прикрепляю шаблон с примером, где слушатель isTrusted получает false после клика, клик сделан методом dispatchEvent на JS



MouseClick и FullEmulationMouseClick в результате isTrusted:true на С# с координатами

прикреплю к основной теме




я подготовил для вас шаблон с примером на javascript. вывод результата в консоль devtools и в переменную:
вот пример вывода абсолютного js path пути, начиная с body
141566




прикрепляю к ответу шаблон с примерами и кодом js

в шаблоне есть, на примере кликов:
  • поиск относительного пути js path;
  • поиск абсолютного пути js path;
  • поиск пути с shadow root open, включая вложенность;
  • вывод в консоль devtools как показано на скриншоте;
  • взятие из консоли данных в переменную для дальнейшей обработки.
проверял:
  • клик по js path, после получения;
  • isTrusted: true для кликов;
  • клики без переходов на страницы, только события, без перезагрузок;
  • клик по svg срабатывает и логируется.
вопрос-предложение.
как вы считаете, стоит ли добавить в Project Maker опционально, т.е. кому нужно может включить, а кому не нужно не включать:
  • логи, которые вызывает любое действие на странице, которое можно отследить с помощью слушателя addEventListener, например, клики, инпуты и тд;
  • логи Fetch (перехват данных API);
  • логи доступов к Shadow DOM attachShadow;
  • логи контроля за созданием элементов createElement.
прикрепляю шаблон с примером получения данных proxy. примеры addEventListener есть в шаблоне countJSpathProxy.zp, загруженном в эту тему.
 

prostors

Client
Регистрация
16.12.2020
Сообщения
1 456
Благодарностей
79
Баллы
48
обновления обязательно будут. кому интересно - можете оставлять заявки.
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)