Что нового

[Автоматизация] Нажатие на ссылку в контейнере (програмно)

Криворукий

Новичок
Сообщения
17
Репутация
0
При разработке бота столкнулся с задачей нажатия на тест - ссылку, что периодически появляется в контейнере. Как я понял идентификатор контейнера это
Код:
<div id="battles">
, а необходимая мне гиперссылка на которую следует нажать
Код:
<a href="НУЖНАЯ ССЫЛКА">Подтвердить</a>
Нажать хочется программно, без эмуляции движений и кликов мыши. Если возможно так сделать, прошу подсказать, какую функцию мне следует изучить из библиотеки
Код:
<IE.au3>


Привожу код контейнера с ссылкой целиком.
Код:
<div id="battles"><table class="icon" cellpadding="0" cellspacing="0" border="0" width="100%">
<tbody><tr><td style="padding:4">
<table cellpadding="4" cellspacing="0" border="0" width="100%"><tbody><tr><td valign="middle" width="30px"><img src="http://icekings.ru/images/icons/green.gif" style="margin-right:5" align="left" height="30px" width="30px"></td><td> Вас вызвал <a href="/users/595381">НВ</a> [0]. [<a href="НУЖНАЯ ССЫЛКА">Подтвердить</a>] [<a

Спасибо за подсказки.


Добавлено:
Сообщение автоматически объединено:

Страх получить предупреждение творит чудеса)))

Код:
_IENavigate($oIE, 'НУЖНАЯ ССЫЛКА')
_IELinkClickByText ($oIE, "Подтвердить")


Нажатие на ссылку происходит, а как задать условие скрипту, что бы он ждал, неопределённое количество времени пока эта ссылка не появиться, а потом при её появлении нажимал на неё и переходил к дальнейшему выполнению тела скрипта? Нет ли случайно функции ЖДАТЬ выполнения условия? Или проверять выполнение условия?

Спасибо за подсказки.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Ну что-то типа
Код:
Local $sHTML = _IEBodyReadHTML($oIE)
...
делаем что надо
...
if $StringInStr($sHTML, "Нужная ссылка") then
    _IENavigate($oIE, 'НУЖНАЯ ССЫЛКА')
_IELinkClickByText ($oIE, "Подтвердить")
endif

Синтаксис может быть не соблюден, но суть разъяснена
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Мой вариант :D
Протестировано в локале - работает...
В реале нет, из-за неучёта мной таблицы table.
Код:
Dim $iCount = 0
While 1
    ConsoleWrite("Count: " & $iCount & @CRLF)
    $oLinks = _IETagNameGetCollection($oIE, "a")
    If IsObj($oLinks) Then
        For $oLink In $oLinks
            $sLinkUrl = $oLink.href
            $sLinkHtml = $oLink.innerHTML
                $sDivId = $oLink.parentNode.id
            If $sDivId = "battles" And StringInStr($sLinkHtml, "Подтвердить") Then
                ConsoleWrite(StringFormat("+----------+\r\nFound link:\r\nURL: %s\r\nHTML: %s\r\nParent div id: %s\r\n+----------+\r\n", $sLinkUrl, $sLinkHtml, $sDivId))
                ; _IENavigate($oIE, $sLinkUrl)
                _IEAction($oLink, "click")
                ExitLoop 2
            EndIf
        Next
    EndIf
    $iCount += 1
    If $iCount >= 10000 Then ExitLoop
    Sleep(2000)
WEnd

P.S. а Это тебе не помогло? :smile:
Я в ЛС тебе писал ведь ещё... :smile: Вопрос был такой же и всё про это "Подтвердить"... ;)
 
Автор
К

Криворукий

Новичок
Сообщения
17
Репутация
0
В данном фрагменте кода
Код:
if $StringInStr($sHTML, "Нужная ссылка") then
    _IENavigate($oIE, 'НУЖНАЯ ССЫЛКА')



Нужная ссылка = НУЖНАЯ ССЫЛКА, или нет?

to alex33
Твоё предложение решает только формально, на деле при появлении ссылки нажатие на неё не происходит.


Добавлено:
Сообщение автоматически объединено:


Протестировано в локале - работает...
Код:
Dim $iCount = 0
While 1
    ConsoleWrite("Count: " & $iCount & @CRLF)
    $oLinks = _IETagNameGetCollection($oIE, "a")
    If IsObj($oLinks) Then
        For $oLink In $oLinks
            $sLinkUrl = $oLink.href
            $sLinkHtml = $oLink.innerHTML
                $sDivId = $oLink.parentNode.id
            If $sDivId = "battles" And StringInStr($sLinkHtml, "Подтвердить") Then
                ConsoleWrite(StringFormat("+----------+\r\nFound link:\r\nURL: %s\r\nHTML: %s\r\nParent div id: %s\r\n+----------+\r\n", $sLinkUrl, $sLinkHtml, $sDivId))
                ; _IENavigate($oIE, $sLinkUrl)
                _IEAction($oLink, "click")
                ExitLoop 2
            EndIf
        Next
    EndIf
    $iCount += 1
    If $iCount >= 10000 Then ExitLoop
    Sleep(2000)
WEnd

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

alex33

Скриптер
Сообщения
1,457
Репутация
186
В твоём предложении происходит просто включение счётчиков, появившаяся ссылка игнорируется.
А ссылка случайно не во фрейме?
ID, Url, Html какие? Div id который содержит нужную ссылку какой?
Повторюсь: у меня в локале работает. :
 
Автор
К

Криворукий

Новичок
Сообщения
17
Репутация
0
Belfigor сказал(а):
Ну что-то типа
Код:
Local $sHTML = _IEBodyReadHTML($oIE)
...
делаем что надо
...
if $StringInStr($sHTML, "Нужная ссылка") then
    _IENavigate($oIE, 'НУЖНАЯ ССЫЛКА')
_IELinkClickByText ($oIE, "Подтвердить")
endif

Синтаксис может быть не соблюден, но суть разъяснена

В месте ... делаем что надо ... Необходимо прописать условия для переменной $StringInStr, задав ей параметр совпадения условия с дальнейшим выполнением скрипта?


Добавлено:
Сообщение автоматически объединено:

alex33 сказал(а):
В твоём предложении происходит просто включение счётчиков, появившаяся ссылка игнорируется.
А ссылка случайно не во фрейме?
ID, Url, Html какие? Div id который содержит нужную ссылку какой?

Не не во фрейме, привожу полный код контейнера

Код:
<div id="battles"><table class="icon" cellpadding="0" cellspacing="0" border="0" width="100%">
<tbody><tr><td style="padding:4">
<table cellpadding="4" cellspacing="0" border="0" width="100%"><tbody><tr><td valign="middle" width="30px"><img src="http://icekings.ru/images/icons/green.gif" style="margin-right:5" align="left" height="30px" width="30px"></td><td> Вас вызвал <a href="/users/595380">Товарищеские матчи</a> [0]. [<a href="friendly.php?approve=1">Подтвердить</a>] [<a href="friendly.php?cancel=1&amp;typeid=">Отказаться</a>]</td></tr></tbody></table></td></tr></tbody></table>
<font size="4pt">Товарищеские матчи</font>

[<a href="javascript:GetBattles(1, 0)">Обновить</a>]

<table class="form" cellpadding="0" cellspacing="0" border="0">
<tbody><tr>
     <td height="8px" width="8px"><img src="http://icekings.ru/images/form-up-left.gif" height="8" width="8"></td>
     <td></td>
     <td align="right"><img src="http://icekings.ru/images/form-up-right.gif" height="8" width="8"></td>
</tr>

<tr><td style="padding:20" colspan="3"><table class="maintable" cellpadding="4" cellspacing="0" bgcolor="#EAF4F6" border="0" width="100%">
<tbody><tr align="center">
<input name="numrows" id="numrows" value="3" type="hidden"><td><span><b>Пользователь</b></span></td>
<td><span title="Время ожидания"><b>Ждёт</b></span></td>
<td><span title="Время таймаута"><b>Таймаут</b></span></td>
<td><span><b> </b></span></td>
</tr>
<tr bgcolor="#EAF4F6"><input name="RecordID[0]" value="17589807" type="hidden"><td>
<a href="/users/485249">perilmeen</a> [8]</td>
<td>
<center>1</center></td>
<td>
<center>5</center></td>
<td>
<a href="friendly.php?id=17589807&amp;act=battles&amp;step=1&amp;typeid=">вызвать »</a></td>
</tr><tr bgcolor="#EAF4F6"><input name="RecordID[1]" value="17589761" type="hidden"><td>
<a href="/users/485906">mowing</a> [8]</td>
<td>
<center>3</center></td>
<td>
<center>5</center></td>
<td>
<a href="friendly.php?id=17589761&amp;act=battles&amp;step=1&amp;typeid=">вызвать »</a></td>
</tr><tr bgcolor="#EAF4F6"><input name="RecordID[2]" value="17589728" type="hidden"><td>
<a href="/guilds/50"></a><img src="http://icekings.ru/images/gd_guilds/small/50.jpg" align="absmiddle" border="0"> <a href="/users/466323">jjim</a> [8]</td>
<td>
<center>5</center></td>
<td>
<center>5</center></td>
<td>
<a href="friendly.php?id=17589728&amp;act=battles&amp;step=1&amp;typeid=">вызвать »</a></td>
</tr></tbody></table></td></tr></tbody></table></div>


Добавлено:
Сообщение автоматически объединено:

Пробую через поиск ссылки и тоже глухо ((

Код:
#include <IE.au3>


Local $oIE = _IECreate('icekings.ru/xml/games/friendly.php?timeout=5&act=app&step=1')
Local $oLinks = _IELinkGetCollection($oIE)
For $oLink In $oLinks
If StringInStr($oLink.innertext, ".php?approve=1") Then
 _IENavigate($oIE, 'icekings.ru/xml/games/friendly.php?approve=1')
_IELinkClickByText ($oIE, "Подтвердить")
EndIf
Next
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Криворукий [?]
В месте ... делаем что надо ... Необходимо прописать условия для переменной $StringInStr, задав ей параметр совпадения условия с дальнейшим выполнением скрипта?
ой там не
Код:
if $StringInStr($sHTML, "Нужная ссылка") then

а
Код:
if StringInStr($sHTML, "Нужная ссылка") then

StringInStr - команда которая в тексте в $sHTML ищет подстроку "Нужная ссылка", почитай описание команды, там более понятным языком написано.
в $sHTML ты считываешь код страницы, во второй параметр функции ты указываешь нужный тебе текст, например "http://blabla.ru/qwqw&asdasd", если в $sHTML содержится такой текст, функция вернет True


Добавлено:
Сообщение автоматически объединено:

я бы сделал так:
Код:
clipput($oLink.innertext)

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

alex33

Скриптер
Сообщения
1,457
Репутация
186
Криворукий, Я знаю почему неработает у тебя.
Это моя вина, я не учёл таблицу <table...>
Сейчас подправлю код скрипта... :smile: :(


Добавлено:
Сообщение автоматически объединено:

Как освобожусь перепишу. Please wait... :D
 
Автор
К

Криворукий

Новичок
Сообщения
17
Репутация
0
alex33 сказал(а):
Криворукий, Я знаю почему неработает у тебя.
Это моя вина, я не учёл таблицу <table...>
Сейчас подправлю код скрипта... :smile: :(


Добавлено:
Сообщение автоматически объединено:

Как освобожусь перепишу. Please wait... :D




Я наверное не корректно объясняю сценарий действий, попробую ещё раз. После выполнения авторизации на сайте, и подачи заявки на игру, бот становиться в очередь ожидания вызова (вызов от другого игрока). Страница на которой происходит действие, в случае поданной заявки, включает автообновление её - 5 секунд (этот параметр не изменен). Заявка на игру может быть сколько угодно оставаться без вызова другим игроком, всё это время пока никто не вызвал работает автообновление на сайте страницы. После того как кто ты вызвал на игру, происходит генерация ссылки в контейнере
ссылка
Код:
icekings.ru/xml/games/friendly.php?approve=1
визуальное появление (во вложении, скрин).

Переход по ней (после её появления) реализуются при помощи
Код:
_IENavigate($oIE, 'icekings.ru/xml/games/friendly.php?approve=1')
_IELinkClickByText ($oIE, "Подтвердить")


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


to Belfigor
попробую применить все данные вами рекомендации.

to alex33
Эт я тут всем голову морочу, ни в чём ты не виноват.

Вы ребята меня не плохо подталкиваете в продвижении решении проблемы. После повторного курения функции :
Код:
StringInStr

Понял, функция ищет текст (буквы или цифры), который указываешь искать на странице, а не ссылку как я не правильно понял из подсказки
Код:
if $StringInStr($sHTML, "Нужная ссылка") then

"Нужная ссылка"(это текст) не равна "НУЖНАЯ ССЫЛКА"(
Код:
html:aaaaaaaaa
), в соответствии с этим я поправил вид скрипта:

Код:
Local $sHTML = _IEBodyReadHTML($oIE)
if StringInStr($sHTML, "Вас вызвал") then
_IELinkClickByText ($oIE, "Подтвердить")
endif


Достаточно просто нажать на ссылку без предварительной навигации
Даже этого достаточно для перехода:
Код:
_IELinkClickByText ($oIE, "Подтвердить")


Но как заставить ждать скрипт появления ссылки?


Добавлено:
Сообщение автоматически объединено:

Может в эту сторону копнуть? Не могу определиться с переменной и условием для неё, что бы цикл продолжал работать

Код:
$Click = _IELinkClickByText ($oIE, "Подтвердить")
$???
While $Click
    Sleep (2000)
    Send("{F5}")
If $??? =  ???Then ContinueLoop
WEnd
 

Вложения

  • скрин.jpg
    скрин.jpg
    34.9 КБ · Просмотры: 9

alex33

Скриптер
Сообщения
1,457
Репутация
186
Попробуйте. Немного переделанный код:
Код:
Dim $iCount = 0
While 1
    ; ConsoleWrite("Count: " & $iCount & @CRLF)
    $oDiv = _IEGetObjById($oIE, "battles")
    $oLinks = _IETagNameGetCollection($oDiv, "a")
    If IsObj($oLinks) Then
        For $oLink In $oLinks
            $sLinkUrl = $oLink.href
            $sLinkHtml = $oLink.innerHTML
            If StringInStr($sLinkHtml, "Подтвердить") Then
                ConsoleWrite(StringFormat("+----------+\r\n Found link:\r\n URL: %s\r\n HTML: %s\r\n+----------+\r\n", $sLinkUrl, $sLinkHtml))
                ; _IENavigate($oIE, $sLinkUrl)
                _IEAction($oLink, "click")
                ExitLoop 2
            EndIf
        Next
    EndIf
    $iCount += 1
    If $iCount >= 10000 Then ExitLoop
    Sleep(2000)
WEnd

P. S. Извините...
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Криворукий [?]
Но как заставить ждать скрипт появления ссылки?
Код:
_IELoadWait
не подходит разве в данном конкретном случае?
 
Автор
К

Криворукий

Новичок
Сообщения
17
Репутация
0
To alex33
Работает, спасибо)) А можете прокомментировать действия в коде, что и как работает?

To Belfigor
Я пока не буду закрывать тему, попробую ещё покопать в сторону Вами предложенной функции. Если ничего лучше, чем предложил alex33 не получиться сделать, то тогда закрою, хорошо ?
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Криворукий сказал(а):
To alex33
Работает, спасибо)) А можете прокомментировать действия в коде, что и как работает?
Если работает это значит я не зря этот код написал :D :D :D :smile: - это хорошо.
Ну вот... :smile: :D
Код:
Dim $iCount = 0; объявляем переменную $iCount и присваиваем ей значение 0
While 1; начало цикла
    ; ConsoleWrite("Count: " & $iCount & @CRLF); пишем в консоль текущее значение переменной $iCount
    $oDiv = _IEGetObjById($oIE, "battles"); получаем объект div по его id battles
    $oLinks = _IETagNameGetCollection($oDiv, "a"); коллекция всех ссылок в div battles
    If IsObj($oLinks) Then; если $oLinks объект (предотвращение вылета скрипта с ошибкой если там нет ссылок / не удалось их получить)
        For $oLink In $oLinks; вложенный цикл for который будет проходить по коллекции ссылок
            $sLinkUrl = $oLink.href; присваиваем переменной $sLinkUrl адрес ссылки (из атрибута href)
            $sLinkHtml = $oLink.innerHTML; присваиваем переменной $sLinkHtml текст находящийся в этой ссылке
            If StringInStr($sLinkHtml, "Подтвердить") Then; если в переменной $sLinkHtml найдено значение Подтвердить        то
                ConsoleWrite(StringFormat("+----------+\r\n Found link:\r\n URL: %s\r\n HTML: %s\r\n+----------+\r\n", $sLinkUrl, $sLinkHtml)); пишем в консоль информацию о найденной ссылке
                ; _IENavigate($oIE, $sLinkUrl); переход по url ссылки
                _IEAction($oLink, "click"); клик по ссылке
                ExitLoop 2; выходим из всех циклов
            EndIf; конец условия
        Next; конец цикла for
    EndIf; конец условия
    $iCount += 1; прибавляем к переменной $iCount единицу
    If $iCount >= 10000 Then ExitLoop; если переменная $iCount больше или равна 10000 (ссылка которую мы ищем не удаётся дождаться / предотвращение зависания если ссылка не появится) - выход из цикла
    Sleep(2000); ждём 2 секунды (timeout прежде чем начать цикл заново / предотвращение перегрузки / ожидание)
WEnd; конец цикла While
P. S. Извините, если что не так / что-то не понятно (утро всётаки)...


Добавлено:
Сообщение автоматически объединено:

Криворукий сказал(а):
попробую ещё покопать в сторону Вами предложенной функции.
Если [url_ex=http://autoit-script.ru/autoit3_docs/libfunctions/_ieloadwait.htm]_IELoadWait[/url_ex] то я думаю она для этой цели не пойдёт. Хотя кто её знает...
Она ждёт когда загрузка страницы / элемента завершится.
 
Автор
К

Криворукий

Новичок
Сообщения
17
Репутация
0
to alex33
когда цикл закончится, произойдёт переход по ссылке, и появиться новое окно, в котором необходимо выполнять следующие действия
Код:
WEnd; конец цикла While

, произойдёт переход по ссылке, и появиться новое окно, в котором необходимо выполнять следующие действия
Код:
; нажатие на авторасстановку
ControlClick("Хоккей товарищ", "", "[CLASS:MacromediaFlashPlayerActiveX; INSTANCE:1]","left",1, 599, 60)
Sleep (2000)
; нажатие на тактику
ControlClick("Хоккей товарищ", "", "[CLASS:MacromediaFlashPlayerActiveX; INSTANCE:1]","left",1, 505, 18)
Sleep (2000)
; выбор тактики
Dim $aClicksX [10] =  [571, 582, 588, 594, 600, 610, 615, 620, 625, 632]
Dim $aClicksY [10] =  [73, 73, 73, 73, 73, 73, 73, 73, 73, 73 ]
For $k = 1 To 1 Step +1
   $Random = Random(0, 2, 1)
   Sleep (3000)
   ControlClick ("Хоккей товарищ", "", "[CLASS:MacromediaFlashPlayerActiveX; INSTANCE:1]","left",1, $aClicksX[$Random], $aClicksY[$Random])
   Sleep (3000)
   Next

- продолжиться ли выполнение тела скрипта дальше? У меня почему - то не происходит нажатие на
Код:
; нажатие на авторасстановку
ControlClick("Хоккей товарищ", "", "[CLASS:MacromediaFlashPlayerActiveX; INSTANCE:1]","left",1, 599, 60)

Не подскажите в чём может быть проблема?
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
я отлаживал скрипты с помощью ConsoleWrite, очень удобно :smile:
 
Автор
К

Криворукий

Новичок
Сообщения
17
Репутация
0
To alex33
Да выполнение скрипта дальше происходит, видно глюк какой - то был, на другом компьютере включил и всё без проблем.
 
Верх