Что нового

Как поместить указатель мыши на ссылку в FireFox?

bescom

Новичок
Сообщения
61
Репутация
0
Навеяно вот этой темой - http://autoit-script.ru/index.php?topic=19449.0
Как реализовать то же самое, только в FireFox, чтобы указатель мыши перемещался на выбранную ссылку? Не требую готовое решение, просто если это реализуемо, подскажите примерно, как?

Заранее благодарен за ответ, уважаемые гуру.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
UIAutomate

Код:
#include "UIAutomate.au3"

Opt("WinTitleMatchMode", 2)

Run("D:\Portable\Firefox\FirefoxPortable.exe www.autoit-script.ru")

$oParent = _UIA_GetElementFromHandle(WinWait("- Mozilla Firefox"))
$oElement = _UIA_WaitControlTypeElement($oParent, "UIA_HyperlinkControlTypeId", "UDF - Пользовательские функции")
_UIA_ElementSetFocus($oElement)
$aRect = _UIA_ElementGetBoundingRectangle($oElement)
MouseMove($aRect[0] + ($aRect[2] - $aRect[0]) / 2, $aRect[1] + ($aRect[3] - $aRect[1]) / 2, 0)
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
Огромный рахмат! Завтра буду пробовать и, если получится, тему закрою. :IL_AutoIt_1:


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

Уважаемый InnI!

Я пытаюсь сделать переход по свойству "Value.Value", то есть по ссылке (мне нужно именно по адресу, а не тексту ссылки), код такой:

Код:
#include "UIAutomate.au3"

Opt("WinTitleMatchMode", 2)

Run("c:\Program Files (x86)\Mozilla Firefox\firefox.exe www.autoit-script.ru")

$oParent = _UIA_GetElementFromHandle(WinWait("- Mozilla Firefox"))
$oElement = _UIA_WaitControlTypeElement($oParent, "UIA_HyperlinkControlTypeId", "http://autoit-script.ru/index.php?PHPSESSID=mt9387j95fot8orh42ua988kv1&board=11.0", "Value.Value")
_UIA_ElementSetFocus($oElement)
$aRect = _UIA_ElementGetBoundingRectangle($oElement)
MouseMove($aRect[0] + ($aRect[2] - $aRect[0]) / 2, $aRect[1] + ($aRect[3] - $aRect[1]) / 2, 0)


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

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
Дело в том, что при наличии одинаковых страниц будет найден первый элемент. Если вы находитесь не на этой странице, то размеры элемента будут 0:0. И вообще, все элементы, которые в данный момент не видны (свойство IsOffscreen = true) будут иметь нулевые размеры. Поэтому предлагаю такой алгоритм. Ожидаем загрузку страницы по наличию кнопки "Reload current page" (кнопка обновления страницы). Находим все элементы по условию (на всех страницах). В цикле пытаемся каждому установить фокус, т.е. вывести элемент в видимую область. И если элемент появился в области видимости (IsOffscreen = false), тогда уже определяем его координаты и двигаем мышь.
Код:
#include "UIAutomate.au3"

Opt("WinTitleMatchMode", 2)

Run("c:\Program Files (x86)\Mozilla Firefox\firefox.exe www.autoit-script.ru")

$oParent = _UIA_GetElementFromHandle(WinWait("- Mozilla Firefox"))
_UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description")
$aAll = _UIA_FindAllElements($oParent, "Value.Value", "http://autoit-script.ru/index.php?board=11.0")
For $i = 1 To $aAll[0]
  _UIA_ElementSetFocus($aAll[$i])
  If Not _UIA_ElementGetPropertyValue($aAll[$i], "IsOffscreen") Then
    $aRect = _UIA_ElementGetBoundingRectangle($aAll[$i])
    MouseMove($aRect[0] + ($aRect[2] - $aRect[0]) / 2, $aRect[1] + ($aRect[3] - $aRect[1]) / 2, 0)
    ExitLoop
  EndIf
Next
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
А через дополнение MozRepl и UDF не пробовали?
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
А через дополнение MozRepl и UDF не пробовали?
Пробовал, но только для выполнения простого перехода с помощью _FFLinkClick, а оно не имитирует нажатие мышки, да и работает не очень надежно.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI [?]
Вы перемещаете мышку на ссылку, чтобы нажать? А что, _UIA_ElementDoDefaulAction() для ссылки не работает?
Я воспользовался простым MouseClick("left") после отработки Вашего кода.

Код отлично работает, только есть три нюанса:

1. Частенько в отладчике выпадает "!> _UIA_WaitControlTypeElement : превышено время ожидания", приходится ставить Sleep, который тоже не всегда помогает.
2. Если скрипт выполнять последовательно на следующей странице, то он уже не срабатывает, мышка перемещается на середину экрана. Видимо, нужно обнулять переменные, не разбирался еще.
3. Перемещение на искомую ссылку происходит очень уж стремительно. Поизучаю сегодня описания к функциям, мож найду, как замедлить...
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
А сделать программный клик без использования мыши вам не подойдёт?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom [?]
в отладчике выпадает
Последний параметр этой функции - время ожидания в секундах. Иногда и 30 бывает мало - всё от сайта зависит.

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

очень уж стремительно
У функции MouseMove() есть третий параметр, отвечающий за скорость.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
bescom [?]
2. Если скрипт выполнять последовательно на следующей странице, то он уже не срабатывает, мышка перемещается на середину экрана. Видимо, нужно обнулять переменные, не разбирался еще.
Извините, вру, вариант InnI работает и на последующих страницах. Что-то я наборогозил в своем скрипте, разбираюсь.


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

InnI [?]
Последний параметр этой функции - время ожидания в секундах. Иногда и 30 бывает мало - всё от сайта зависит.
Так может, ставить 0, чтобы исключить ошибки?

У функции MouseMove() есть третий параметр, отвечающий за скорость.
Извиняюсь, что-то я подтупил...
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
Проблема решена, рецепт InnI великолепно работает, тему сейчас закрою.

InnI я очень благодарен за подсказку и за время, уделенное моему вопросу, поэтому прошу кинуть в личку номер электронного кошелька любой системы для перечисления небольшого вознаграждения. Пусть я не могу заплатить много, зато это будет сделано от души. Еще раз спасибо! :IL_AutoIt_1:
 
Автор
bescom

bescom

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

Итак, сразу к сути. Функция наведения на ссылку и клика мышкой по ней работает в цикле, то есть браузер переходит со страницы на страницу. И на некоторых страницах с разной периодичностью (от 2 до 200 переходов) скрипт вываливается в ошибку со следующим сообщением:

9tweadX.png


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

Если посмотреть (привожу случай чисто ради примера, могут быть и другие подобные ситуации) на комментарии любой страницы CMS WordPress, то, наведя мышку на кнопку "Ответить", можно увидеть следующее:

Код:
http://site.ru/?page_id=100500&replytocom=9999#respond

И функция _FFLinksGetAll() библиотеки FF.u3 выбирает ссылки в том же виде, и функция уважаемого InnI использует их же. Но если посмотреть в исходный код страницы, то мы увидим несколько иное:

Код:
<div class="reply">
         <a class='comment-reply-link' href='/?page_id=100500&#038;replytocom=9999#respond' onclick='return addComment.moveForm( "comment-4024", "4024", "respond", "4089" )' aria-label='Комментарий к записи admin (admin)'>Ответить</a>      </div>

Понимаете, в чем разница? Опускается "http://" и домен, зато в середину вместо "&" вставляется "&#038;" - в итоге скрипт попросту не находит ссылку на странице!

Но беда даже не в этом, не находит - да и ладно бы, пусть бы писал в массив ошибку, но он вываливается в фатальную ошибку.

Что с этим делать? InnI, я снова обращаюсь к Вам с просьбой о помощи...
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
пусть бы писал в массив ошибку, но он вываливается в фатальную ошибку
Дело в том, что я вам привёл пример кода. В данном примере нет проверок на ошибки выполнения функций. Функция _UIA_FindAllElements() в случае ошибки не возвращает массив. Вам нужно самостоятельно проверять ошибки выполнения функций. В случае ошибки все функции устанавливают @error отличный от нуля. Массивы дополнительно можно проверить при помощи IsArray()
Код:
; If Not @error Then ; или так
If IsArray($aAll) Then ; или так
  For $i = 1 To $aAll[0]
    _UIA_ElementSetFocus($aAll[$i])
    If Not _UIA_ElementGetPropertyValue($aAll[$i], "IsOffscreen") Then
      $aRect = _UIA_ElementGetBoundingRectangle($aAll[$i])
      MouseMove($aRect[0] + ($aRect[2] - $aRect[0]) / 2, $aRect[1] + ($aRect[3] - $aRect[1]) / 2, 0)
      ExitLoop
    EndIf
  Next
EndIf
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI [?]
Дело в том, что я вам привёл пример кода.
Что тут поделаешь, вероятно, все новички проходят эти этапы, когда из-за незнания, как применяются какие-то функции, задают глупые вопросы. ;) И я такой...

В скрипте я применил несколько другую конструкцию:

Код:
While IsArray($aAll)=0
        ; здесь вставил выбор другой ссылки
WEnd


Ну и потом уже:

Код:
For $i = 1 To $aAll[0]
    _UIA_ElementSetFocus($aAll[$i])
    If Not _UIA_ElementGetPropertyValue($aAll[$i], "IsOffscreen") Then
      $aRect = _UIA_ElementGetBoundingRectangle($aAll[$i])
      MouseMove($aRect[0] + ($aRect[2] - $aRect[0]) / 2, $aRect[1] + ($aRect[3] - $aRect[1]) / 2, 0)
      ExitLoop
    EndIf
  Next


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

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
применил несколько другую конструкцию
Не знаю, как вы делаете "выбор другой ссылки", но учтите... Если поиск окна FireFox находится вне этого цикла, то его тоже нужно проверить на ошибку. Потому что, если вы закроете FireFox или по какой-то причине он не будет обнаружен, то цикл поиска элементов будет бесконечным, т.к. всегда будет возникать ошибка в связи с отсутствием $oParent
Код:
$oParent = _UIA_GetElementFromHandle(WinWait("- Mozilla Firefox"))
If IsObj($oParent) Then ; проверка наличия окна FireFox
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
Если честно, начинает кипеть мозг... Пытаюсь хоть что-то найти самостоятельно и обязательно упираюсь в какую-нибудь хрень. Приведу функцию целиком:

Код:
Func GoTarget()
   $ssylka=FileOpen(@ScriptDir&"\ok_links.txt", 0)
   $urlstr1=FileReadLine(@ScriptDir&"\ok_links.txt", 1) ; В первой строке этого файла ссылка, по которой надо кликнуть
   FileClose($ssylka)

   Opt("WinTitleMatchMode", 2)
   ; Производим переход по целевой ссылке
   WinActivate("Mozilla Firefox")

   $oParent = _UIA_GetElementFromHandle(WinWait("Mozilla Firefox"))
   _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description", 0)
   $aAll = _UIA_FindAllElements($oParent, "Value.Value", $urlstr1)

   While IsArray($aAll)=0 ; Если ссылка для наведения фокуса "плавающая/искажающаяся", то из того же массива выбрать другую
	  URLFromArray() ; это функция, которая все ссылки страницы записывает в файл, выбирает случайную ссылку и пишет в строку 1 файла ok_links.txt
		 $ssylka=FileOpen(@ScriptDir&"\ok_links.txt", 0)
		 $urlstr1=FileReadLine(@ScriptDir&"\ok_links.txt", 1)
		 FileClose($ssylka)
		 Opt("WinTitleMatchMode", 2)
		 ; Производим переход по целевой ссылке
		 WinActivate("Mozilla Firefox")
		 $oParent = _UIA_GetElementFromHandle(WinWait("Mozilla Firefox"))
		 _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description", 0)
		 $aAll = _UIA_FindAllElements($oParent, "Value.Value", $urlstr1)
   WEnd

   For $i = 1 To $aAll[0]
	 _UIA_ElementSetFocus($aAll[$i])
	 If Not _UIA_ElementGetPropertyValue($aAll[$i], "IsOffscreen") Then
	   $aRect = _UIA_ElementGetBoundingRectangle($aAll[$i])
				  $x=Random(50,1000)
				  $y=Random(200,700)
				  MouseMove($x,$y, Random(5,30))
				  Sleep(200)
	   MouseMove(($aRect[0] + ($aRect[2] - $aRect[0]) / 2) + Random(-10, 10, 1), ($aRect[1] + ($aRect[3] - $aRect[1]) / 2) + Random(-1, 1, 1), 10)
	   ExitLoop
	 EndIf
   Next
   MouseClick("left")

   _FFLoadWait()
   Sleep(10000)

   $urlstr=0
EndFunc


В итоге скрипт перебирает ссылки, справедливо отбрасывая "неправильные", причем может перейти по другой, по правильной, а может целый час перебирать и не переходить по правильным. Я делал логирование ссылок, там вперемешку правильные и неправильные. Интересное наблюдение: если во время перебора навести мышку на значок скрипта, а потом на окно FF, то скрипт тут же кликает даже по неправильной ссылке. Как так???

И забыл сказать - проверку на наличие $oParent делал, все на месте, а по правильным ссылкам не кликается...
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
Если я правильно понял код, то как-то так
Код:
Func GoTarget()
   URLFromArray() ; это функция, которая все ссылки страницы записывает в файл, выбирает случайную ссылку и пишет в строку 1 файла ok_links.txt
   $urlstr1=FileReadLine(@ScriptDir&"\ok_links.txt", 1) ; В первой строке этого файла ссылка, по которой надо кликнуть

   Opt("WinTitleMatchMode", 2)

   $oParent = _UIA_GetElementFromHandle(WinActivate("Mozilla Firefox"))
   If Not IsObj($oParent) Then Return
   _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description", 0)
   $aAll = _UIA_FindAllElements($oParent, "Value.Value", $urlstr1)
   If Not IsArray($aAll) Then Return

   For $i = 1 To $aAll[0]
     _UIA_ElementSetFocus($aAll[$i])
     If Not _UIA_ElementGetPropertyValue($aAll[$i], "IsOffscreen") Then
       $aRect = _UIA_ElementGetBoundingRectangle($aAll[$i])
       $x=Random(50,1000)
       $y=Random(200,700)
       MouseMove($x,$y, Random(5,30))
       Sleep(200)
       MouseMove(($aRect[0] + ($aRect[2] - $aRect[0]) / 2) + Random(-10, 10, 1), ($aRect[1] + ($aRect[3] - $aRect[1]) / 2) + Random(-1, 1, 1), 10)
       ExitLoop
     EndIf
   Next
   MouseClick("left")

   _FFLoadWait()
   Sleep(10000)

   $urlstr=0
EndFunc
Если что-то не так - объясните словами, что вы хотите сделать.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
Вероятно, я действительно косноязычно говорю о том, что надо, и о том, что происходит. Попробую сначала.

Задача такая: функция должна кликать по случайной ссылке на странице в FF, при этом адрес этой ссылки она берет из первой строки файла ok_links.txt (результат работы другой функции URLFromArray() - она работает без сбоев, поэтому речь не о ней, просто для пояснения). Но, как выяснилось, форма некоторых ссылок, которые мы получаем с помощью функции _FFLinksGetAll() библиотеки FF.u3, отличается от той, которая имеется в коде страницы по факту, я это описывал ранее (опущены http:// и домен, вставляются спецсимволы и т.д.). Я такие ссылки условно называю неправильными. При помощи IsArray() проверка на правильность работает, и, если ссылка неправильная, нужно снова вызвать URLFromArray(), чтобы получить новую случайную ссылку, и снова попробовать на правильность. Не прошло - снова и снова, пока не найдется правильная ссылка и скрипт не перейдет к клику по ней. Собственно, это все и имеется в том коде, который я привел:

Код:
Func GoTarget()
   $ssylka=FileOpen(@ScriptDir&"\ok_links.txt", 0)
   $urlstr1=FileReadLine(@ScriptDir&"\ok_links.txt", 1) ; В первой строке этого файла ссылка, по которой надо кликнуть
   FileClose($ssylka)

   Opt("WinTitleMatchMode", 2)
   ; Производим переход по целевой ссылке
   WinActivate("Mozilla Firefox")

   $oParent = _UIA_GetElementFromHandle(WinWait("Mozilla Firefox"))
   _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description", 0)
   $aAll = _UIA_FindAllElements($oParent, "Value.Value", $urlstr1)

   While IsArray($aAll)=0 ; Если ссылка для наведения фокуса "плавающая/искажающаяся", то из того же массива выбрать другую
      URLFromArray() ; это функция, которая все ссылки страницы записывает в файл, выбирает случайную ссылку и пишет в строку 1 файла ok_links.txt
         $ssylka=FileOpen(@ScriptDir&"\ok_links.txt", 0)
         $urlstr1=FileReadLine(@ScriptDir&"\ok_links.txt", 1)
         FileClose($ssylka)
         Opt("WinTitleMatchMode", 2)
         ; Производим переход по целевой ссылке
         WinActivate("Mozilla Firefox")
         $oParent = _UIA_GetElementFromHandle(WinWait("Mozilla Firefox"))
         _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description", 0)
         $aAll = _UIA_FindAllElements($oParent, "Value.Value", $urlstr1)
   WEnd

   For $i = 1 To $aAll[0]
     _UIA_ElementSetFocus($aAll[$i])
     If Not _UIA_ElementGetPropertyValue($aAll[$i], "IsOffscreen") Then
       $aRect = _UIA_ElementGetBoundingRectangle($aAll[$i])
                  $x=Random(50,1000)
                  $y=Random(200,700)
                  MouseMove($x,$y, Random(5,30))
                  Sleep(200)
       MouseMove(($aRect[0] + ($aRect[2] - $aRect[0]) / 2) + Random(-10, 10, 1), ($aRect[1] + ($aRect[3] - $aRect[1]) / 2) + Random(-1, 1, 1), 10)
       ExitLoop
     EndIf
   Next
   MouseClick("left")

   _FFLoadWait()
   Sleep(10000)

   $urlstr=0
EndFunc

Но вот на этом участке:

Код:
While IsArray($aAll)=0 ; Если ссылка для наведения фокуса "плавающая/искажающаяся", то из того же массива выбрать другую
      URLFromArray() ; это функция, которая все ссылки страницы записывает в файл, выбирает случайную ссылку и пишет в строку 1 файла ok_links.txt
         $ssylka=FileOpen(@ScriptDir&"\ok_links.txt", 0)
         $urlstr1=FileReadLine(@ScriptDir&"\ok_links.txt", 1)
         FileClose($ssylka)
         Opt("WinTitleMatchMode", 2)
         ; Производим переход по целевой ссылке
         WinActivate("Mozilla Firefox")
         $oParent = _UIA_GetElementFromHandle(WinWait("Mozilla Firefox"))
         _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Reload current page", "LegacyIAccessible.Description", 0)
         $aAll = _UIA_FindAllElements($oParent, "Value.Value", $urlstr1)
   WEnd


скрипт может надолго зациклиться, даже встречая правильную ссылку (встречает, не находит ее на странице и ищет другую), а может неожиданно после часа перебирания ссылок (правильных и неправильных) сделать переход. Проверку If IsObj($oParent) я ставил. Она показывает - да, объект присутствует, однако по встреченной правильной ссылке скрипт не кликает. Такое впечатление, что ищет не с исходного объекта, поэтому не находит. Что не так, я не могу понять. Код этого участка тот же самый, что и используемый ранее для правильных ссылок. Предполагаю, что вызванный повторно код ищет объект не с начала страницы, а с какого-то другого участка (может, с того, на котором остановился в предыдущий раз).
 
Верх