Поиск по DOM, моя библиотека
Всем доброго времени суток!
Я разрабатываю плагин для Mozilla Firefox, который является ботом-клиентом для одной популярной браузерной игры. Суть не сложна - после некоторых умозаключений плагин выбирает какоето действие. Чтобы понять какое действие нужно выполнять, и чтобы выполнить действие, нужно найти конкретный элемент в DOM структуре и прочитать необходимые параметры/выполнить симуляцию клика. Не секрет что стандартный поиск с помощью .getElement[s]By[...] не всегда всех устраивает, меня в принципе устраивал до того как мой клиент начали определять посредством подмены аттрибутов (id,clsass,tagName, name, разные свойства - типа display:none) на элементах в самой игре.
Я разработал свой небольшой движок для поиска, который включает в себя стандартные типы поиска(плюс один нестандартный - по внутреннему тексту), в комбинации с операторами WH (WHERE - аналогично mySQL - операндами могут быть аттрибуты элемента, стилевые свойства элемента, внутренний текст) и CF (анологично WH но в случае несоответствия шлёт ошибку на сервер, и прерывает работу всего плагина)
Вот примеры выборок:
get_id('td_npc')^get_class('npc_avatar_small')[1]
стандартная - анологичная стандартным DOM функциям - получаем по id элемент td_npc и в нём ищем второй элемент с названием класса npc_avatar_small.
get_iht('войти',tolow)[0]^get_tag('div' )[0 WH sty(visibility=='hidden')]
выборка посложнее - выбираем первый элемент, внутренний текст которого содержит фразу 'войти' , без учёта больших/маленьких букв, затем в нём ищем первый элемент с тэгом div, который имеет свойство стиля, visibility равное hidden. Следует заметить что выборку get_iht можно записать по-другому:
get_tag('*')[0 WH iht(tolow >io< 'войти')] - берём все элементы, и ищем первый элемент, где innerHTML.toLocaleLowerCase().indexOf('войти')!=-1.
get_name('info')[0 WH atr(type=='text')] CF atr(id==infoi)&&atr(size>50)
выборка с CF - берём первый элемент с именем info, тип которого равен text, и проверяем его id и size, если они не соответствуют тому что задано выборка возвращает false, и вызывается функция-обработчик ошибки - у меня она посылает ошибку на сервер, и выходит из игры.
Вобщем идея понятна думаю =)
Краткое описание:
Выборка - строка, где каждый элемент разделяется знаком ^.
Элемент - вызов функции выборки, у меня прописаны такие:
array get_tag(tag) - выборка по тегу
array get_class(class) - выборка по классу
array get_name(name) - выборка по атрибуту Name
elem get_id(id) - выборка по ID
array get_iht(innerText, case) - выборка по содержанию внутри данного фрагмента текста, следует заметить что innerHTML подэлементов в расчёт не берётся. Второй параметр необязательный, и если он принимает значение tolow - значит игнорируются большие/маленькие буквы.
Если функция возвращает массив то нужный элемент можно получить через квадратные скобки get_tag(tag)[1] , а также с дополнением оператора WH , который по сути задаёт доп. условия выборки - get_tag(tag)[0 WH condition]. После того как найден нужный элемент можно применить оператор CF, для подтверждения корректности элемента - get_id(id) CF condition .
Условия для операторов CF и WH состоят из функции/функций, получающих свойства элемента[ов], и проверяющих с помощью оператора и правого опереранда.
Функции для condition:
atr(выражение) - аттрибут элемента
sty(выражение) - значение стиля для из аттрибуда style
stc(выражение) - значение computed стиля
iht(выражение) - innerHTML элемента, если левый опперанд равен tolow - игнорируются большие/маленькие буквы.
Операторы для condition:
"!=", "==", ">", "<" - стандартные
">io<" - свойство.indexOf(правый операнд)!=-1 (для текстовых свойств)
">iob<" - свойство.indexOf(правый операнд)==0 (для текстовых свойств)
Функции для condition могут объединяться логическими операторами "&&", "!", "||" и круглыми скобками.
Чтобы получить элемент в javascript программе - необходимо вызвать функцию
CBT_GetEBT(tepl[,doc]) - первый параметр это строка-шаблон, второй параметр документ, откуда выборка(по умолчанию равен document) - к примеру.
var ele = CBT_GetEBT("get_iht('войти',tolow)[0]");
Вобщем может кому моя писанина пригодится =)
|
да, забыл - функция внутри CBT_GetEBT - function retor(rt) , это мой обработчик ошибок, если обработка ошибок необходима - её нужно изменить под себя.
И ещё одна правка - ошибка в коде - нужно заменить
if (car.atype == "atr") chk = CBT_TplAttribConfirm(elem.hasAttribute(car.aparam) ? elem.getAttribute(car[i].aparam) : false, car[i].aop, car[i].aval);
на
if (car[i].atype == "atr") chk = CBT_TplAttribConfirm(elem.hasAttribute(car[i].aparam) ? elem.getAttribute(car[i].aparam) : false, car[i].aop, car[i].aval);
0_0 OMG, а чем тебе jQuery не угодил?
Спецификой задачи это раз - например, мне нужно генерировать ошибку, если чтото не так. В jQuery, поиск по DOM неплохой, но ограничен, где там поиск по внутреннему тексту? Тут какбы к своему велосипеду можешь приделать что хочется, и что надо, и без траты времени.
css селекторы и xpath это официальные и быстрые api от w3c.
И если не брать в рассчет ie6 ie7 то у нас есть или то или то. А для ie6 ie7 есть оптимизированные библиотеки эмулирующие xpath или css селекторы (что чаще )
$(":contains('text')") чем не угодил?
Так же в jquery можно добавлять свои фильтры не тратя времени =)
>css селекторы и xpath это официальные и быстрые api от w3c
да, скорость не очень, но к этому я не стремился - для меня главное - блок подтверждений, то-есть если не соответствует шаблону - выходим из обработки страниц с ошибкой.
>$(":contains('text')") чем не угодил?
Да, ты прав, для простого поиска jQuery лучше, поэтому мой модуль врятли кому пригодится. Но тем не менее, если кому-то нужно последнюю версию (я его латаю, и улучшаю пока использую) можно написать в асю 491743283
get_id, get_class, get_tag - можно объединить в одну фукнцию более универсальную
1) $_$('#id .class tag') - таким образом можно обратиться по цепочке
$_$('#main .selector div[1] a')
Ищем id = main, далее внутри него элемент с классом selector (он должен быть один, так как скобочки не указаны), далее в нем второй тег div а в нем тег или теги а.
В результате имеем либо DOMObject либо коллекцию DOMObject
2) оптимизация, это когда не известен либо родительский элемент либо дочерний и этот неизвестный элемент мы получаем в переменной obj;
$_$(obj, '.selector[2]') - найти дочерний selector третий по счету
$_$('.frame', obj) - найти родителя с классом frame
Подскажите пожалуйста со скриптом не могу определить селектор
Из этого кода нужен селектор
на эту кнопку он должен нажать у меня получилось вот так но не работает
xpath = "//form[@id='dvifree']//a"
var link = getFirstResult(xpath, document);
if (link&&(!window.jump)) {
window.jump=true;
dfSubmit();
} else {
Отправить комментарий
Приветствуются комментарии:Для остальных вопросов и обсуждений есть форум.