Что нового

сбор и сохранение ссылок со страницы

JohnWind

Новичок
Сообщения
34
Репутация
0
Доброго времени суток,

имеется страница, на которой существует н-ское кол-во линков: каждый уникальный, но вот названия могут совпадать.

задача:
необходимо просканировать данную страницу, и получить допустим первые 10 линков на странице и сохранить их, например в .txt файле.

для примера задачи можно взять mail.ru - с его меню: от Mail.ru до Все проекты.

заранее большое спасибо за помощь.
 

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
Браузер-то какой? Вот для хрома первые 10 ссылок.
Хром должен быть запущен с параметром --force-renderer-accessibility и открыт на странице mail.ru
Код:
#include <UIAutomate.au3> ; https://autoit-script.ru/threads/uiautomate-avtomatizacija-nestandartnyx-ehlementov-gui.16780/

$oParent = _UIA_GetElementFromHandle(ControlGetHandle("[RegexpTitle:.* - Google Chrome]", "", "Chrome_RenderWidgetHostHWND1"))
$aLinks = _UIA_FindAllElements($oParent, "ControlType", $UIA_HyperlinkControlTypeId)
$sText = ""
For $i = 1 To 10
  $sText &= _UIA_ElementGetPropertyValue($aLinks[$i], "Value.Value") & @CRLF
Next
FileWrite("links.txt", $sText)
 
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
охохоюшки хохо! отличное попадание именно в нужный браузер...

но увы, 1й же запуск выдал ошибку в строке внутри цикла...

==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$sText &= _UIA_ElementGetPropertyValue($aLinks[$i], "Value.Value") & @CRLF
$sText &= _UIA_ElementGetPropertyValue(^ ERROR
Сообщение автоматически объединено:

нашёл пример запуска хрома с параметрами и добавил ваш код... всё работает на УРА!
спасибо за помощь!!
Сообщение автоматически объединено:

проблема с ошибкой выше - продолжает повторятся
; находим все ссылки на странице
$aLinks = _UIA_FindAllElements($oParent, "ControlType", $UIA_HyperlinkControlTypeId)


; открываем четыре ссылки c 2 по 34 в новых вкладках
For $i = 2 To 10 Step 2
FileWrite($fileLinks1, _UIA_ElementGetPropertyValue($aLinks[$i], "ValueValue"))
FileWrite($fileLinks1, "" & @CRLF)
Next

==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
FileWrite($fileLinks1, _UIA_ElementGetPropertyValue($aLinks[$i], "ValueValue"))
FileWrite($fileLinks1, _UIA_ElementGetPropertyValue(^ ERROR


вот эта ошибка возникает достаточно регулярно... причём повторный запуск этого же скрипта (скажем 5 раз) можно запросто выдать 3 удачных результата и 2 фейла (см выше)
 
Последнее редактирование:
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
вопрос в том, почему это происходит?
ссылки 100% есть на странице...

почему при повторении этого же сценария - то результаты есть то их нет?
Сообщение автоматически объединено:

похоже что проблема в проверке на то что страница загружена.

стоило добавить 5 сек паузу ПЕРЕД проверкой что страница загружена, и больше ошибок не возникает.

; Создание элемента с использованием дескриптора окна
$oParent = _UIA_GetElementFromHandle($hWnd)

Sleep (5000)

; Ожидание загрузки страницы по наличию текста "zzzzzzz"
_UIA_WaitControlTypeElement($oParent, "UIA_TextControlTypeId", "zzzzzzz")
If @error Then Exit

только что произвёл 15 повторов запуска сценария - 0 ошибок.
не самое изящное решение - но рабочее...
Сообщение автоматически объединено:

Это выход за пределы массива. Проверяйте сколько найдено ссылок в $aLinks[0].
и ещё 2 вопроса:
------
1. может у вас есть документация с описанием возможных значений параметров библиотеки - UIAutomate.au3
  1. ; Имя функции : _UIA_FindAllElements
  2. ; Описание : Находит все элементы, соответствующие заданному свойству и его значению
  3. ; Синтаксис : _UIA_FindAllElements($oElementFrom[, $vProperty = 0[, $vPropertyValue = ""]])
  4. ; Параметры : $oElementFrom - элемент (объект), от которого начинается поиск
  5. ; : $vProperty - свойство искомого элемента (по умолчанию 0 - любое)
  6. ; : $vPropertyValue - значение свойства искомого элемента (по умолчанию пустая строка)

пример:
; находим все ссылки на странице
$aLinks = _UIA_FindAllElements($oParent, "ControlType", $UIA_HyperlinkControlTypeId)

мягко говоря - не очевидная строка, даже для человека с некоторым опытом автоматизации (например: java+selenium)
-------------
2. скрипт который вы предложили - вылавливает "лишние" линки из кода, а именно:

<script src="https://partner.

пока такой линк на странице был в начале - я просто начинал работу начиная со 2го найденного линка
но в последнее время, эти (рекламные) линки находятся и внутри списка обычных (искомых) линков.

нет ли возможности указать что добывать надо лишь те линки у которых формат <a href=

заранее спасибо за помощь.
Сообщение автоматически объединено:

-------------
update:

с пунктом №2 разобрался - добавил проверку наличия НУЖНОЙ подстроки в текуще-найденом линке через StringInStr
в рекламных линках НЕТ повторяющегося фрагмента который есть во всех НУЖНЫХ линках.

при результате StringInStr = 0 (в текущем линке НЕТ ожидаемой подстроки) - линк определяется как не нужный и пропускается.
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
документация с описанием возможных значений параметров
Все константы описаны в UIAConstants.au3
Документация на сайте разработчика. Например здесь
Утилита Inspect отображает возможные параметры и значения для элементов.
Также можете попробовать UIASpy
 
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
Все константы описаны в UIAConstants.au3
Документация на сайте разработчика. Например здесь
Утилита Inspect отображает возможные параметры и значения для элементов.
Также можете попробовать UIASpy
простите... я видимо не ясно выразил мысль.

Дано: $aLinks = _UIA_FindAllElements($oParent, "ControlType", $UIA_HyperlinkControlTypeId)

Разбираем:

1. _UIA_FindAllElements - открываем #include <UIAutomate.au3> и читаем описание, которое мягко говоря не вполне очевидно
2. $oParent - учитывая что выше по коду мы вызывали другую функцию, чей результат записали сюда - смысл более или менее понятен
3. "ControlType" - а что это? если это тип объекта - где можно прочесть про то, какие другие типы применяются и что конкретно данный тип определяет?
4. $UIA_HyperlinkControlTypeId - тут вопросов больше всего:

а) если это константа - отчего бы не указать в коде (комментарием) что это и зачем именно это?
б) да я понимаю, что укажи мы фактическое значение константы - код стал бы менее гибким, но КАК ЧАСТО меняются системные константы, чтоб заводить специальную для какого-либо особого случая? если кол-во случаев когда понадобиться изменить (более гибко в файле где указана эта константа) - бесконечно мало - то зачем заводить таковую?

в моём понимании это как заводить константу на числа: 0-9, а вдруг вместо 1 надо будет использовать 2...

с) главный момент - название константы - может я предвзято разбираю - но в имени переменной/константе/функции - должен быть смысл

тут у нас: Hyperlink-ControlType-Id
допустим Hyperlink - это отсылка что работа над линком
ControlType - что означает это в привязке к Hyperlink? то что у линка может быть определён тип - который по сути скажет что это и есть линк (что мы знали из 1й части)
Id - уникальный идентификатор чего-либо...

и как "прочесть" такую переменную/константу?

Линк - типа_Объекта/Класса_Линков - с_некоторым_уникальным_номером

а учитывая что это ещё и константа - то смысл вообще уходит вникуда...
-------

это тоже самое что описывать MsgBox с использованием констант:

MsgBox($defaultMsgBoxType, $userLabelMsgBox, $userTextMsgBox, $userMsgBo:rofl:elay)

где все 4 значения в скобках - константы
--------------

подводя итог - жаль что описанный функционал настолько не-дружествен к кодеру.
 

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
Данная UDF предоставляет функционал для работы с интерфейсом UI Automation
Если вы не знаете о возможностях этого интерфейса, что такое элемент, какие существуют типы элементов, какие у элемента свойства и значения, не понимаете структуру дерева элементов, то вы просто не сможете пользоваться этой UDF. Именно по причине непонимания параметров функций.

А если у вас действительно есть опыт работы с java+selenium, то лучше посмотреть в сторону WebDriver
Потому что работа с UIAutomation - это принципиально другой подход к работе с элементами страницы (если говорить о браузерах). WebDriver работает непосредственно с кодом страницы. А UIAutomation - с деревом элементов, которые создаёт браузер из кода страницы. И каждый браузер строит своё уникальное дерево, потому что поддержка UIAutomation у каждого разработчика реализована по разному.
 
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
Данная UDF предоставляет функционал для работы с интерфейсом UI Automation
Если вы не знаете о возможностях этого интерфейса, что такое элемент, какие существуют типы элементов, какие у элемента свойства и значения, не понимаете структуру дерева элементов, то вы просто не сможете пользоваться этой UDF. Именно по причине непонимания параметров функций.

А если у вас действительно есть опыт работы с java+selenium, то лучше посмотреть в сторону WebDriver
Потому что работа с UIAutomation - это принципиально другой подход к работе с элементами страницы (если говорить о браузерах). WebDriver работает непосредственно с кодом страницы. А UIAutomation - с деревом элементов, которые создаёт браузер из кода страницы. И каждый браузер строит своё уникальное дерево, потому что поддержка UIAutomation у каждого разработчика реализована по разному.
похоже вы правы...
проще будет используя Java+Selenium(selenide) выдернуть линки в текстовик, создать exe-шник, и запустить его через ShellExecute в начале моего AutoIT скрипта

я всё же надеялся на возможность адекватной/интуитивно понятной реализации любой задачи в AutoIT.
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
я всё же надеялся на возможность адекватной/интуитивно понятной реализации любой задачи в AutoIT
То есть работать с IE.au3 не имея представления об html? Или использовать функционал GdiPlus.au3 не зная отличий Bitmap от Image, что такое Graphics и для чего нужны Pen и Brush? Ну-ну. Удачи.
 
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
То есть работать с IE.au3 не имея представления об html? Или использовать функционал GdiPlus.au3 не зная отличий Bitmap от Image, что такое Graphics и для чего нужны Pen и Brush? Ну-ну. Удачи.
переведите на русский интуитивно и понятно такую строку:

UIA_FindAllElements($oParent, "ControlType", $UIA_HyperlinkControlTypeId)

чтоб не париться сильно - можете взять каждый отдельный элемент и перевести его...
или для того чтоб использовать готовую функцию - мне надо сначала изучить ВСЁ ТО из-за чего она была написана?

чтоб вам было проще, вот пример простой функции который сможет разобрать любой кто понимает английский:

Func LogINCheck($logFile, $currentLogin) - и это не высшая математика... а всё ясно, интуитивно и понятно:

- функция
- проверки успешности логина (в чём именно проверка в данном случае не важно)
- переменная лог файла
- переменная текущего логина

попробуйте так же интуитивно понятно разложить пример выше...
и незачем ну-ну-кать... если вам лень/не хочется/прочее (подчеркнуть нужное, или всё сразу) отвечать на вопрос - незачем тратить силы на бесполезный ответ.
 

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
для того чтоб использовать готовую функцию - мне надо сначала изучить ВСЁ ТО из-за чего она была написана?
Именно!

а всё ясно, интуитивно и понятно
Естественно. Потому что вы знаете, что такое логин, что такое лог и то, что лог можно сохранить в файл. Кстати, что такое файл тоже нужно знать.
Здесь бывают такие новички, которые текстовые файлы называют "файл блокнота". Для них эта ваша функция будет такой же непонятной, как вам UIA_FindAllElements.

переведите на русский интуитивно и понятно такую строку:
UIA_FindAllElements($oParent, "ControlType", $UIA_HyperlinkControlTypeId)
Найти все элементы, начиная от элемента-родителя $oParent, имеющих свойство "ControlType" ($UIA_ControlTypePropertyId), со значением свойства равным $UIA_HyperlinkControlTypeId. Или так: найти все ссылки в дереве элемента $oParent. Что вам непонятно? Дерево? Элемент? Свойство? Значение? Изучайте UIAutomation, чтобы было понятно.

и незачем ну-ну-кать...
Какой полезный совет. Ну-ну... советуйте ещё.
 
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
т.е. прежде чем сесть за руль машины, нужно изучить ДЕТАЛЬНО все этапы проектирования, производства деталей и затем сборки автомобиля? ню-ню...
Естественно. Потому что вы знаете, что такое логин, что такое лог и то, что лог можно сохранить в файл. Кстати, что такое файл тоже нужно знать.
Здесь бывают такие новички, которые текстовые файлы называют "файл блокнота". Для них эта ваша функция будет такой же непонятной, как вам UIA_FindAllElements.
я исхожу что тот кто пытается программировать имеет хотя бы базовые понятия о том ЧТО такое программирование...
Найти все элементы, начиная от элемента-родителя $oParent, имеющих свойство "ControlType" ($UIA_ControlTypePropertyId), со значением свойства равным $UIA_HyperlinkControlTypeId. Или так: найти все ссылки в дереве элемента $oParent. Что вам непонятно? Дерево? Элемент? Свойство? Значение? Изучайте UIAutomation, чтобы было понятно.
1. открыл google.com, вбил Пушкин, нажал поиск
2. на полученной странице - куча ссылок на различные ресурсы
3. нажал F12 и в поле кода, задал поиск "ControlType" - результатов 0.
4. $UIA_HyperlinkControlTypeId - насколько я понял - это константа, которая определяет что искомый объект - линк (ещё вопрос это будет a или поиск непосредственно по href)

другими словами - само описание компонентов функции - НЕ наводит на мысль о том, что это и как его найти, например в ручном режиме.

итог: нужно было задать вопрос, узнать что $UIA_HyperlinkControlTypeId = это константа... которая (скорее всего) привязана к типу объекта на странице типа линк.... и сделать вывод, что ControlType - это внутреннее определение, которое мало помогает
------------
изучать - это круто... жаль что автор не озаботился об интуитивности описания, чего тут увы, не наблюдается.

для примера - оболочка написанная на базе Selenium - > Selenide

поиск элемента на странице:
$("#loginBtn") или
$(".active")

вроде выглядит ещё более ужасно и не понятно.
но в описании поясняется:

$ = Find Element (by some condition)
# - search by ID = By.id ("loginBtn")
. - search by class = By.class ("active")

т.е. достаточно в случае страницы Гугул - Пушкин - найти нужный мне линк, узнать (например) его ID, и задать поиск: $("#requiredLinkID")

как видно - авторы озаботились о том, чтоб ЕЩЁ более НЕ ОЧЕВИДНЫЙ код - тем не менее читался и понимался адекватно.... чего тут увы, и не наблюдается.


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

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
т.е. прежде чем сесть за руль машины
Нужно научиться ей управлять. Вам не нужно изучать реализацию интерфейса (этапы проектирования, производства деталей и затем сборки), но нужно уметь им пользоваться (различать педали автомобиля, уметь переключать передачи, включать фары...).

я исхожу что тот кто пытается программировать имеет хотя бы базовые понятия о том ЧТО такое программирование...
А я, при написании этой UDF, исходил из того, что пользователь имеет хотя бы базовые понятия об UIAutomation.

нажал F12 и в поле кода, задал поиск "ControlType" - результатов 0.
Ещё раз:
Потому что работа с UIAutomation - это принципиально другой подход к работе с элементами страницы (если говорить о браузерах). WebDriver работает непосредственно с кодом страницы. А UIAutomation - с деревом элементов, которые создаёт браузер из кода страницы. И каждый браузер строит своё уникальное дерево, потому что поддержка UIAutomation у каждого разработчика реализована по разному.
Чтобы увидеть ControlType вам нужна утилита Inspect.exe (в архиве с UDF) или её аналог, например

жаль что автор не озаботился об интуитивности описания
Автор - я. И эта UDF сделана максимально понятно для тех, кто знаком с UIAutomation. Если не верите, сравните с
или

зачем и почему этот код ТАК оформлен - одной интуиции и знаний программирования недостаточно...
Верно. Необходимы специфические знания о работе UIAutomation.
Но, если вам так нравится интуиция, запустите Inspect.exe. Слева дерево элементов. Справа свойства этих элементов, значения свойств и возможные шаблоны работы с элементами. Возможно, из названий свойств и значений вам что-то станет понятнее.

не добавляет программисту существенных знаний
Знания - это теория. UDF - это практика. Не нужно их смешивать. UDF не даёт знаний, но позволяет имеющиеся знания применять на практике.
 
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
Автор - я. И эта UDF сделана максимально понятно для тех, кто знаком с UIAutomation. Если не верите, сравните с
или
если я знаю что должен сделать инструмент, то его изобретатель должен сделать понимание КАК им работать одним из 2х путей:

или дать подробную и точную инструкцию, поясняющую всё возможные варианты применения(по прямому назначению) данного инструмента
или сделать так, чтоб "понимание" инструмента было интуитивным и очевидным.

пример: инструмент механиков - трещётка.

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

просто... понятно... очевидно... даже если вы 1й раз взяли - просто потыкаясь разберётесь.

в вашем коде - без изучения ВАШЕГО кода - нельзя разобраться и понять что куда и ГЛАВНОЕ - ПОЧЕМУ.

хотите обижайтесь.. .хотите нет... ваше дело.
но пока (если опустить ваш подход глубокого изучения) - ваш код можно или тупо копи-пастить... или не использовать.

со 2м всё очевидно
а с 1м - а если мне надо будет чуть другой запрос... мне придётся снова спрашивать как сделать не так а эдак... и ждать когда кто-то предоставит очередной фрагмент для тупого копи-паста... как по мне - вариант не лучше 2го.
 

SealAlbinos

Знающий
Сообщения
64
Репутация
15
Не совсем понимаю, но не проще ли обратиться к сайту и получить все ссылки через HTML DOM
а до этого если прям нужно, сделать небольшой перехват текущей открытой ссылки или просто ее копировать в буффер
Код:
$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$oHTTP.Open("GET", "https://mail.ru/")
$oHTTP.Send()

$oHTML = ObjCreate("HTMLFILE")
$oHTML.Write($oHTTP.Responsetext)
For $i = 0 to $oHTML.links.length - 1
    ConsoleWrite($oHTML.links($i).href & @LF)
Next
 
Последнее редактирование:
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
Выберите этот вариант и закончим уже эту дискуссию.
дискуссия это попытка найти понимание... у нас же было нечто иное:

я задаю вопрос - а вы мне своё мнение... я вам ещё вопрос - а вы повторяете тоже самое.

последняя попытка:
Нужно научиться ей управлять. Вам не нужно изучать реализацию интерфейса (этапы проектирования, производства деталей и затем сборки), но нужно уметь им пользоваться (различать педали автомобиля, уметь переключать передачи, включать фары...).

в вашем коде нет ни педалей ни переключений ни фар...
есть "если хочешь ехать: жми только ЭТО и только ВОТ ТАК"...
а если вдруг решишь поехать назад, то не рассчитывай что угадаешь что надо Это(же) - И наоборот... потому что для движения назад надо совсем другое и в другую сторону...

когда я гляжу на нечто - что выглядит как руль, а мне говорят что это педаль - сори... это больше похоже на "я художник (автор) - я так вижу - я так сделал"... я не исключаю что бывают педали выглядящие как руль... но не надо заявлять, что тут всё ясно и понятно...

подытоживая - мне пришлось воспользоваться вашим кодом УВЫ без какого-либо понимания: тупой копи-паст работающего фрагмента кода... просто так есть и работает...
и ЕСЛИ вдруг мне понадобиться нечто другое (но из той же области) - моего опыта и интуиции НЕ хватит на то, чтоб понять самостоятельно КАК ЖЕ с вашим кодом это можно реализовать... если в ВАШЕМ понимании - это ясно и понятно - чтож.. да будет так.
 

InnI

AutoIT Гуру
Сообщения
4,784
Репутация
1,377
если в ВАШЕМ понимании - это ясно и понятно
Уважаемый "автолюбитель". Удобство работы с данной UDF подтверждено десятками пользователей, потому что я добавлял и улучшал функционал именно по заявкам и предложениям участников форума (см. тему UDF). Да, были такие, которые, как вы, заявляли: "Эта UDF плохая, потому что мне непонятно, как с ней работать". Но вы пришли, не поняли, и ушли. А UDF останется и, поверьте, ей будут пользоваться. Потому что в новых Windows практически не осталось элементов GUI, с которыми AutoIt может работать нативными функциями. Подтверждением тому - значительно возросший интерес по работе с UIAutomation на официальном форуме.
 
Последнее редактирование:
Автор
J

JohnWind

Новичок
Сообщения
34
Репутация
0
Уважаемый "автолюбитель". Удобство работы с данной UDF подтверждено десятками пользователей, потому что я добавлял и улучшал функционал именно по заявкам и предложениям участников форума (см. тему UDF). Да, были такие, которые, как вы, заявляли: "Эта UDF плохая, потому что мне непонятно, как с ней работать". Но вы пришли, не поняли, и ушли. А UDF останется и, поверьте, ей будут пользоваться. Потому что в новых Windows практически не осталось элементов GUI, с которыми AutoIt может работать нативными функциями. Подтверждением тому - значительно возросший интерес по работе с UIAutomation на официальном форуме.
уважаемый автор (я в отличии от вас хамить не стану)...

вы написал - супер
написали как хотели - не супер но сойдёт
раздали тем кому НАДО - они пользуются потому что иного решения нет - не супер, не сойдёт - но выбора нет.

лично я НЕ буду советовать ваш код... как минимум по причине - не очевидности.
как сказал выше - юзаю ваш код как black-box... но помните - блэк-бокс кодинг - это дурной тон.

удачи вам.
 
Верх