We rise up for the things we believe in over and over again

Смотрелка - Браузер, если по-нашему, по айтишному.
А началось все... с Initial.D: читать дальше

Что-то вспомнился мне этот диалог, решил, что надо бы эту задачу расколоть.
Исследуем выдачу от Mail.ru. Все ссылки не прямые, а ведущие на отдельные страницы, уже с которых можно вытащить ссылку на сами файлы. Следовательно, вариант, который я использовал в прошлый раз, отпадает. Придется как-то ходить по ссылкам из выдачи поисковика.
Ключевой момент - как можно в Powershell пойти куда-то в вебе в режиме смотрелки? Правильно, "оседлать" смотрелку!


Вот вокруг этого скрипт и будет крутиться. Погнали!



А теперь по складам.
Первый блок ничем не примечателен, обычное объявление объектов да одной переменной. Во втором уже любопытнее, происходит, собственно "автоматизация смотрелки". Мы скармливаем подопытному браузеру исходную ссылку, заставляем его перейти по ней, вытаскиваем из исходного кода этой страницы все элементы типа "якорь", а затем при помощи хитрой магии регулярного выражения из всех этих якорей получаем ссылки, ведущие на страницы загрузки нужных файлов. Эти ссылки в виде хэш-таблицы передаются в переменную $elements.
Дальнейшее уже является повторением ранее изученного. В цикле та же автоматизация смотрелок плюс "хитрая магия" плюс загрузка файла при помощи wget.

Отдельно стоит сказать по зубодробительной конструкции
@([System.__ComObject].InvokeMember(“getElementsByTagName”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $ie.document, 'A'))
которая все якоря из исходника и выбирает. Вообще есть более изящное $ie.document.GetElementsByTagName('A'), но, как выяснилось, у нее есть большие проблемы с разными версиями IE. В актуальных для Windows 7, это не работает, потому пришлось идти через запасной ход.
C хэш-таблицей тоже все весело. Изначально я вообще не планировал ее использовать, ибо зачем плодить сущности. Хотелось в переменную $elements загнать непосредственно то, что будет отдано парсером GetElementsByTagName. Не тут-то было. Парсер эти данные отдал, но как только дело доходило до третьего блока, который уже загружал отдельные страницы, переменная $elements теряла все значения. Не коллекцию элементов, а именно значения. И, естественно, третий блок валился с ошибкой и многими строками красного текста, ненавистного большинству повершелльщиков. Пришлось отделить мух от котлет, после этого все заработало.

А засада этого скрипта в том, что на его отладку было потрачено больше времени, чем на ручное скачивание всех этих 40+ файлов. Ну и ладно, зато плюс одна любопытная задачка в активе :)

P.S> Но насколько же неторопливо идет парсинг кода при помощи GetElementsByTagName...

UPD. В топку internetexplorer.application, Invoke-WebRequest же!

Важно! - из &_amp нужно убрать символ подчеркивания, парсер - нехороший человек.

@музыка: The Offspring - Secrets from the Underground

@темы: PowerShell, Scripting

Комментарии
25.05.2015 в 15:59

Тотальная неудачница и убийца жёстких дисков.
P.S> Но насколько же неторопливо идет парсинг кода при помощи GetElementsByTagName...

Я обычно делаю поиск по тексту регулярками.
25.05.2015 в 16:04

We rise up for the things we believe in over and over again
Можно и так. И возможно, так оно будет и быстрее. Но это усложнит регулярку, которая и без того общепризнана хитрым колдунством :)
Ну и опять же - как было написано, практической пользы в этом скрипте - вовсе не результат в виде 40+ мр3 файлов. Польза в другом :)
26.05.2015 в 07:34

Тотальная неудачница и убийца жёстких дисков.
Можно и так. И возможно, так оно будет и быстрее. Но это усложнит регулярку, которая и без того общепризнана хитрым колдунством :)

Начнём с того, что когда ты пихаешь страницу (или ссылку) в COM объект IE, то он грузит всё, что там есть, выполняет скрипты и всё такое прочее. Оттуда и тормоза. Плюс нехилый риск для безопасности. Так что, лучше написать регулярное выражение.
26.05.2015 в 08:57

We rise up for the things we believe in over and over again
Ну так понятное дело, что грузится все. Ты же фактически открываешь браузер, и рулишь им при помощи PSH. Визуально такая работа ничем не отличается от ручного управления смотрелкой.

лучше написать регулярное выражение
Ок, но регурярку нужно писать на основании уже загруженного исходника страницы. Поделись, как ты его получишь? :)
26.05.2015 в 10:19

Тотальная неудачница и убийца жёстких дисков.
Сейчас гляну...

Кстати, рекомендую мою RegExp Playground ^_^
26.05.2015 в 10:33

Тотальная неудачница и убийца жёстких дисков.
Например:


26.05.2015 в 10:36

Тотальная неудачница и убийца жёстких дисков.
А, поняла ^^

Берёшь wget, берёшь параметр -O и качаешь туда. Смотришь код завершения и читаешь указанный файл.



Путь и имя файла можно генерировать динамически. Например, через GetTempPath(), создание GUID и проверку существования файла.
26.05.2015 в 10:37

Тотальная неудачница и убийца жёстких дисков.
Если тебя не возбуждает wget, то можешь юзать WinHTTPServeices. Сейчас придумаю пример.
26.05.2015 в 10:40

Тотальная неудачница и убийца жёстких дисков.
Самый каркас на VBS. Должно быть что-то подобное в PoSH.


26.05.2015 в 10:49

We rise up for the things we believe in over and over again
рекомендую мою RegExp Playground
Да мне regex101.com/ нравится :)

wget
Во! Вот про wget я и забыл. Будет свободное время - попробую переработать скрипт :)
26.05.2015 в 10:56

We rise up for the things we believe in over and over again
Нафиг wget!
Invoke-webrequest же!
26.05.2015 в 12:30

Тотальная неудачница и убийца жёстких дисков.
Да мне regex101.com/ нравится :)

А потом интернет вырубают за неуплату...
Плюс мой вариант совместим с тем, что используется у Microsoft.

^^'