Выгрузка кода соседней вкладки Chrome, работа с ней
Доброго времени суток!
Начал изучать JS(вот прям только-только начал, сегодня), с целью написать скрипт для легкого упрощения работы себе и коллегам (мониторинг). Не прошу написать мне весь код(хотя против помощи любого размера я не буду уж точно), просто подсказку/наводку/хинт) Цель изначально такая - есть некая система обработки входящих обращений/системных инцидентов HPSM(написана на JS по словам коллег), есть у нее интерфейс, и частью этого интерфейса является отображение обращений в определенном статусе (т.е. я вижу строки таблицы, на которые могу нажать и перейти к конкретному обращению). Так-же на этой-же странице есть кнопка, которая отдельно этот список обновляет, без обновления самой страницы. Задача - html страницу, которая будет выгружать код вкладки (допустим она всегда первая) браузера с этим всем HPSM, затем выделять из этого кода отдельный кусок, который всегда на своем месте лежит, и выводить на себя. Совсем уж мечта - что-бы этот скрипт раз в 5 минут "прожимал" кнопку обновления списка на той вкладке, а затем просматривать все тот-же кусок кода, и при изменениях алерт выводить. Есть-ли вообще возможность реализовать все это на JS? Или нужно использовать что-то другое? Может подскажите направление/функции? Буду очень благодарен за любую помощь) Очень хочется облегчить работу нашему мониторингу):help: |
Всё возможно.
Прикрепи чтоль сохранённую ту самую страничку, посмотрим. А так способа два: 1. userscript - для этого придётся ставить расширение для браузера, 2. букмарклет - закладка при клике на которую запускается код. |
Aetae, странная тема, отображение в "просмотр кода" и "просмотр кода страницы"(который в новой вкладке открывается) несколько отличается.
Полностью я страницу не могу скинуть (у нас СБ очень злые, вонзят по самые гланды), но есть скрины нужной секции страницы. На странице у меня отображаются обращения, подходящие по определенному шаблону. Первый - когда этих "обращений" нет: ![]() ![]() Второй - когда они есть: ![]() ![]() По скринам видно, что при появлении в списке обращений, в класса "x-grid3-body" появляется вложенный класс (не знаю как на терминах это называется) с длиннющим названием, и кучей вложений (элементы таблицы разные, ссылки и т.д. что уже не важно. Важно что внутри "body" появляется класс, который является своеобразной строкой таблицы, по сути самим обращением в этом списке. Именно это место и интересно. ID у класса меняется каждый раз при обновлении списка, так что от него отталкиваться не выйдет, нужно отталкиваться от наличия классов в классе "x-grid3-body". Вот, кстати, код той самой кнопки "Обновить", которая обновляет список обращений: ![]() P.S.: не работает [spoiler] 1 [/spoiler] как на этом форуме спойлеры ставить? |
Это печально.
Приложение написано на ExtJS - овермайндном корпоративном бегемоте, "простенько" с ним нифига не сделаешь. Вот накидал букмарклет который теоретически должен делать то что надо, но если там ещё и сложная структура вложенных фреймов, то без прямого доступа до той страницы уже ничего не поделаешь: (function(){ var w = window.open('', 'monitoring_window'); w.document.open(); w.document.write(`<!DOCTYPE html> <html> <head> <title>monitor</title> <style> #error{ background:red; color:white; } /* здесь придётся добавить стилей для нормального отображения результата */ </style> </head> <body> <div id="error"></div> <div id="result"></div> <script> var buttonPressInterval = 5 * 60 * 1000; /* интервал повтора нажатия в мс */ var contentUpdateInperval = 1000; /* интервал обновления данных */ var errorElement = document.getElementById('error'); /* сюда выводим ошибки */ var resultElement = document.getElementById('result'); /* сюда выводим результат */ var buttonSelector = 'button[aria-label="Обновить"]'; /* селектор для кнопки */ var contentSelector = '.x-grid3-body'; /* селектор для нужного */ var lastButtonPress = 0; function simulateClick(window) { /* Имитация нажатия, поднятия и клика, неизвестно на что именно прописано событие конкретно у вас, можно поэксперементировать и убрать лишнее. */ var button = window.document.querySelector(buttonSelector); if(!button) return false; var event = window.MouseEvent, options = { bubbles: true, cancelable: true, view: window }; button.dispatchEvent(new event('mousedown', options)); button.dispatchEvent(new event('mouseup', options)); button.dispatchEvent(new event('click', options)); return true; } function show(html, element){ if(element.showHTML === html) return false; element.innerHTML = html; } (function update(){ try{ var element = opener.document.querySelector(contentSelector); if(element){ show(element.innerHTML, resultElement); } }catch(e){ return show( 'Потеряна связь с главной страницей, перезапустите букмарклет.', errorElement ); } if(new Date() - lastButtonPress >= buttonPressInterval){ show( simulateClick(opener) ? '' : 'Не найдена кнопка обновления.', errorElement ); lastButtonPress = new Date().getTime(); } setTimeout(update, contentUpdateInperval) }()); </script> </body> <html>`); w.document.close(); }()) На всякий случай, букмарклет работает так: создаёте на панели закладку, в поле адрес пишете "javascript:" после чего вставляете вышеприведённый код. Далее заходите на нужную страницу и кликаете по созданной закладке. |
Спасибо за помощь)
Сделал по вашей инструкции, но страница почему-то пустая, поле result пустое, при этом обращения есть. ![]() ![]() Если активировать вкладку на другую страницу, то ошибка "Не найдена кнопка обновления." выдается, соответственно кнопку он как минимум видит. Судя по всему он не активирует кнопку обновления, потестил с не обновленным списком уже изменившихся обращений - не реагирует( |
document.querySelectorAll(".x-grid3-body").length что выдаёт?
Если больше 1, то значит класс не уникален, сделай в инструментах разработчика на нужном элементе Копировать -> Селектор и подставь полученное значение в contentSelector. |
честно говоря не знаю где посмотреть(
в коде букмарклета такой строки нет, полагаю это какой-то параметр у страницы? |
В консоли(соседняя вкладка в инструментах разраотчика).
Кстати если 0, то значит в деле замешаны фреймы и всё печально. |
в консоли вот такая картина
![]() |
Это всё фигня, открой консоль на главной странице, введи туда document.querySelectorAll(".x-grid3-body").length и нажми enter.
|
Да, я понял что тупанул)
Увы, там 0. Запускал на обеих страницах |
Ну посмотри тогда вверх от нужно элемента встречается ли там в родителях iframe или frame, единожды или несколько раз, есть ли у него src?
|
Да, есть такой, и src тоже, detail.do?lang=ru, который является ссылкой на https://sm.mos.ru/sm/detail.do?lang=ru
![]() |
Эта ссылка выдает в отдельной вкладке вот эту часть основной страницы:
![]() причем в том состоянии, в котором она находится на основной странице, т.е. если я меняю значения на основной, и обновляю страницу по этой ссылке, то её содержимое меняется соответственно. |
(function(){ var w = window.open('', 'monitoring_window'); w.document.open(); w.document.write(`<!DOCTYPE html> <html> <head> <title>monitor</title> <style> #error{ background:red; color:white; } /* здесь придётся добавить стилей для нормального отображения результата */ </style> </head> <body> <div id="error"></div> <div id="result"></div> <script> var buttonPressInterval = 5 * 60 * 1000; /* интервал повтора нажатия в мс */ var contentUpdateInperval = 1000; /* интервал обновления данных */ var errorElement = document.getElementById('error'); /* сюда выводим ошибки */ var resultElement = document.getElementById('result'); /* сюда выводим результат */ var buttonSelector = 'button[aria-label="Обновить"]'; /* селектор для кнопки */ var contentSelector = '.x-grid3-body'; /* селектор для нужного */ var lastButtonPress = 0; function querySelectorAnyFrame(window, selector){ var element; if(element = window.document.querySelector(selector)) return element; for(var i = window.frames.length, element; i--;){ try{ if(element = window.frames[i].document.querySelector(selector)){ return element } }catch(e){} } } function simulateClick(window) { /* Имитация нажатия, поднятия и клика, неизвестно на что именно прописано событие конкретно у вас, можно поэксперементировать и убрать лишнее. */ var button = window.document.querySelector(buttonSelector); if(!button) return false; var event = window.MouseEvent, options = { bubbles: true, cancelable: true, view: window }; button.dispatchEvent(new event('mousedown', options)); button.dispatchEvent(new event('mouseup', options)); button.dispatchEvent(new event('click', options)); return true; } function show(html, element){ if(element.showHTML === html) return false; element.showHTML = element.innerHTML = html; } (function update(){ try{ var element = querySelectorAnyFrame(opener, contentSelector); if(element){ show(element.innerHTML, resultElement); } }catch(e){ return show( 'Потеряна связь с главной страницей, перезапустите букмарклет.', errorElement ); } if(new Date() - lastButtonPress >= buttonPressInterval){ show( simulateClick(opener) ? '' : 'Не найдена кнопка обновления.', errorElement ); lastButtonPress = new Date().getTime(); } setTimeout(update, contentUpdateInperval) }()); </script> </body> <html>`); w.document.close(); }()) Попробуй так, но тут уж никаких гарантий... |
ВАУ!
![]() Спасибо большое) Вы волшебник) Подучу JS, заставлю это дело звуки издавать при появлении обращений) Это, кстати, возможно, именно звук воспроизводить? Если я правильно понимаю, принципе нужно сохранять состояние element в переменную, и в функции update сравнивать со старым, с вызовом отдельной функции при отличии. |
Да, моджно. HTML5 елемент audio.
Ток звуки надоедают. В своё время хорошо помогала засветка всего экрана красным/желтым на секунду.) Но это уж сами. Эксперементируйте в консоли, после чего уже добавляйте в рабочий код. |
Огромное спасибо!
С наступающим! (Или уже наступившим) Думаю можно закрывать) |
Цитата:
..upd Кстати поправил баг, старый результат в этой функции не сохранялся.)) |
А можно как-то заставить его прожимать на основной странице ту самую кнопку "Обновить"?
Я так понял нужно уже разбираться с simulateClick, и как местный интерфейс заставить с ним работать? |
Цитата:
Поменяйте: var buttonPressInterval = 5 * 60 * 1000; на поменьше, для экспериментов. Для это кстати не обязательно перезапускать всё, можно на открытой странице "monitoring" прям в консоли написать например "buttonPressInterval = 1000;" На счёт "ручного нажатия" на кнопку - там же "simulateClick(window.opener)". |
Да, я вот тоже вспомнил про этот момент, и изменил на 5*2*1000)
simulateClick(window.opener) выдает true, но на основной странице изменений нет Если вручную нажимать на основной эту кнопку, то в консоли выдает вот это: ![]() |
В консоли на главной document.querySelector('button[aria-label="Обновить"]') и наведи на результат мышь. Подсветилась нужная кнопка?
|
Выдало
<button type="button" id="ext-gen-top20" class=" x-btn-te on-refresh cwc-toolbar-refresh" aria-label="Обновить">Обновить</button> но кнопка не высвечивается зато высвечивается если во вкладке elements навести на <tbody class="x-btn-small x-btn-icon-small-left"><tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr><tr><td class="x-btn-ml"><i> </i></td><td class="x-btn-mc "><em class="" unselectable="on"><button type="button" id="ext-gen-top435" class=" x-btn-text" aria-label="Обновить" style="background-image: url("images/toolbar/trefresh.png");">Обновить</button></em></td><td class="x-btn-mr"><i> </i></td></tr><tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr></tbody> |
Проверь в консоли
document.querySelectorAll('button.x-btn-text[aria-label="Обновить"][style*="images/toolbar/trefresh.png"]') Если результат только один, то поменяй 25 var buttonSelector = 'button[aria-label="Обновить"]';на var buttonSelector = 'button.x-btn-text[aria-label="Обновить"][style*="images/toolbar/trefresh.png"]'; Если ничего не выдало, то поменяй ещё и 49 var button = window.document.querySelector(buttonSelector);на var button = querySelectorAnyFrame(window, buttonSelector); Гадание на кофейной гуще - сложная вещь.) |
Понял в чем суть, в консоли он выдает id = "ext-gen-top20"
а на самой странице он ext-gen-top539, причем с каждым нажатием на эту кнопку, и соответственно обновлением страницы, число увеличивается спустя 4 обновления это уже 617 |
он выдал надпись, но я с телефона через team wiever сижу, немного не удобно. через 10 минут скину скрин, оно выдало
NodeList [button#ext-gen-top669.x-btn-text] 0 : button#ext-gen-top669.x-btn-text length : 1 __proto__ : NodeList при наведении на вторую строку button выделяется нужная кнопка скрин через 5 минут |
length:1
"Длина один" - по русски. С смело зафигачивай первый вариант.) |
Так, при вводе команды выводит вот это:
![]() при наведении на него ничего не выделяется Но, если на это нажать, оно раскроется: ![]() и вот если тут навести на выделенный светло-синим элемент (выделил отдельно синими чертами), то выделяется искомая кнопка! |
Aetae, вы наш Дед-Мороз)
Все работает, обновление идет) От лица всего коллектива мониторинга ЦОД огромное вам человеческое спасибо) Лучший подарок на этот НГ :D Спасибо большое за терпение, и помощь в облегчении службы честному мониторингу) (теперь у нас больше времени писать отчеты? что реально радует :D) |
Вообще ты не воспринимай код как магию, по большей он сам за себя говорит, пусть и на английском, например:
window.document.querySelector(buttonSelector); В окне из документа запросить селектор взятый из переменной buttonSelector button[aria-label="Обновить"] Элемент "button" с атрибутом aria-label равным "Обновить" button.x-btn-text[aria-label="Обновить"][style*="images/toolbar/trefresh.png"] Элемент "button" с классом "x-btn-text", атрибутом "aria-label" равным "Обновить" и атрибутом "style" содержащим "images/toolbar/trefresh.png" Собсно первый вариант не работал потому что querySelector(в отличие от querySelectorAll)запрашивает самый первый из подходящих под селектор элементов. А первый селектор оказался слишком общим и цеплял ещё какую-то кнопку. А так я сам в мониторинге крупного провайдера в своё время работал.:) |
Ну, я код изучал только в университете, и только базовые какие-то функции в php, c, c#, fasm, и капелька js с приложения на телефон)
Так что для меня это немного магия) Я понимаю принципы работы, но сам язык не знаю) Вот, кстати, и новогоднее настроение подъехало) Вы мне сегодня магии завезли, так необходимой) |
Часовой пояс GMT +3, время: 09:10. |