Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Парсим сайты и веб-страницы с помощью Powershell / Invoke-WebRequest / getElementsByTagName и боремся с производительностью

Автор: Super User. Категория: ИТ.

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

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

В Powershell есть специальный коммандлет Invoke-WebRequest, который собственно и разбирает HTML-страницу на тэги и содержимое. На выходе этот коммандлет выдает объект страницы с полем ParsedHtml. К этому полю можно применять методы по выборке нужных данных.

Допустим, что вам нужно выбрать все ссылки на странице. Вот как это работает.

Для сложных сайтов строим более сложные фильтры:

Производительность Invoke-WebRequest и getElementsByTagName

Я не знаю, в чем причина такого поведения. Погуглив, я вышел на это обсуждение: http://stackoverflow.com/questions/14202054/why-is-this-powershell-code-invoke-webrequest-getelementsbytagname-so-incred. Из текста я понял, что getElementsByTagName дает нам некоторое количество COM-объектов, и мы отдаем эти COM-объекты в другой коммандлет. Это ужасно медленный процесс, который отнимает до 86% всего времени.

У этой проблемы я пока нашел только одно решение: пользуйтесь 32-битным Powershell в таких случаях. Не знаю почему, но это действительно дает результат.

Источник

Invoke-WebRequest: Обработка содержимого веб-страниц и HTML сайтов в Powershell

В PowerShell версии 3.0 появилась возможность напрямую обращаться и работать с HTML веб-страницам в Интернете. Для этого был разработан специальный командлет Invoke-WebRequest. Данный командлет позволяет реализовать множество сценариев: начиная от возможности скачать/ загрузить файл с/на любого веб-сайта по HTTP/ HTTPS/ FTP, заканчивая возможностями парсинга HTML страниц, мониторинга состояния веб серверов, заполнения и отправкой веб-форм. В целом, новый командлет предоставляет все необходимые методы для навигации по DOM дереву HTML документа. В этой статье мы разберём базовые примеры работы с командлетом PowerShell Invoke-WebRequest.

Использование командлета Invoke-WebRequest

Командлет Invoke-WebRequest (псевдоним wget) может отправлять и получать HTTP, HTTPS и FTP запросы, обрабатывать возвращаемый сервером ответ. Полученный ответ представляет собой набор коллекции форм, ссылок, изображений и других важных элементов HTML документа.

Попробуем выполнить следующую команду:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Как вы видите, возвращенный ответ представляет собой не простой HTML код страницы. Вы видите различные свойства web-документа. Командлет Invoke-WebRequest, как и большинство других командлетов PowerShell оперирует объектами. Invoke-WebRequest возвращает объект типа HtmlWebResponseObject. Посмотрим все свойства данного объекта:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Чтобы получить сырой HTML код веб страницы, который содержится в данном объекте, выполните:

Вы можете вернуть HTML код вместе с HTTP заголовками, которые вернул веб сервер:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Вы можете проверить только код ответа веб-сервера и HTTP заголовки HTML страницы:

Как вы видите, веб сервер вернул ответ 200, т.е. запрос выполнен успешно и веб сервер доступен и работает корректно.

Получаем список всех HTML ссылок на странице

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

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

$HttpContent.Links | fl innerText, href

Можно выбрать только ссылки с определенным CSS классом:

Или определенным текстом в url:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Парсинг HTML страниц с помощью Powershell

Командлет Invoke-WebRequest позволяет довольно быстро и удобно парсить содержимое любых веб-страниц. При обработке HTML страницы из ее содержимого формируются коллекции ссылок (links), веб-форм (forms), изображений (images), скриптов (scripts) и т.д.

С помощью Powershell получим содержимое главной страницы нашего сайта:

$Img = Invoke-WebRequest “https://winitpro.ru/”

Затем выведем список всех изображений на данной странице:

Сформируем коллекцию из полных url путей к используемым изображениям:

Инициализируем новый экземпляр класса WebClient:

$wc = New-Object System.Net.WebClient

И скачаем все изображения со страницы (с оригинальными именами) в каталог c:\tools\:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметровВ качестве интересного примера использования командлета Invoke-WebRequest можно привести способ узнать внешнего IP адреса компьютера из PowerShell.

Как скачать файл по HTTP с помощью PowerShell

Invoke-WebRequest может работать как аналог Wget или cURL для Windows, позволяя скачать с веб-страницы или ftp сайта нужный файл или файлы. Допустим, нам нужно с помощью PowerShell скачать по HTTP некий файл (в нашем примере дистрибутив Mozilla Firefox). Выполним такую команду:

В результате выполнения командлета с указанного URL адреса будет скачан файл и сохранен в каталоге c:\tools\ под именем firefox setup 32.0.3.exe. Если нужно скачать файл с FTP сайта, просто замените http: // на ftp: //.

Таким образом вы с легкостью можете на определенной веб-странице найти все ссылки, попадающие под конкретные критерии (класс ссылки, разрешение в имени файла, url адрес), и скачать файлы по полученным ссылкам. Например, имеется некий сайт с кучей ссылок на PDF документы. Ваша задача скачать все эти файлы на ваш компьютер. Костяк PowerShell скрипта для массовой скачки файлов может выглядеть так:

В результате выполнения скрипта в целевом каталоге будут загружены все pdf файлы со страницы. Каждый файл сохраняется под произвольным именем.

Заполнение и отправка веб-форм на Powershell

Многие веб-сервисы для работы требуют ввода различных данных в HTML формы. С помощью Invoke-WebRequest можно получить доступ к любой HTML-форме, заполнить необходимые поля и передать заполненную форму обратно на сервер. В этом примере мы покажем, как с помощью Powershell авторизоваться в почтовом ящике популярного российского сервиса mail.ru через его стандартную веб форму.

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

С помощью следующей конструкции сохраним информацию о куках (Cookies) подключения в отдельной сессионной переменной:

Следующей командой отобразим список заполняемых полей в HTML форме авторизации (форма называется LoginExternal):

Присвоим нужные значения всем полям:

Чтобы передать заполненную форму на веб сервер, вызовем атрибут HTML-формы action.

Недостатки командлета Invoke-WebRequest

Одним из существенных недостатком командлета Invoke-WebRequest является довольно низкая скорость работы. При загрузке файла HTTP поток целиком буферизируется в память, и только после окончания полной загрузки сохраняется на диск. Таким образом, при закачке больших файлов можно столкнутся с нехваткой памяти.

Другая проблема – командлет Invoke-WebRequest тесно связан с Internet Explorer. Например, в редакциях Windows Server Core, в которых IE не установлен, командлет Invoke-WebRequest использовать нельзя.

Если на HTTP сайте используется самоподписанный сертификат, то командлет Invoke-WebRequest отказывается получать данные с него. Чтобы игнорировать некорректный SSL сертификат, используйте следующий код:

Источник

Скачиваем и распаковываем файл из Интернета при помощи Powershell

Для загрузки файлов из Интернета в Powershell предусмотрен метод DownloadFile, которому нужно передать два аргумента — что скачиваем и куда.

Скачать по HTTP или HTTPS

DownloadFile

* в данном примере мы скачаем файл http://download_ahyware/file1.zip и разместим его на компьютере по пути C:\Downloads\file1.zip.

Invoke-WebRequest

Данный командлет предназначен для загрузки содержимого html документа. Также с его помощью можно скачивать файлы:

* где URI — путь-источник (что скачиваем); outfile — путь-назначение (куда скачиваем).

Для удобства можно использовать команду wget — по сути, это алиас на Invoke-WebRequest.

Скачать с FTP

Принцип скачивания файлов с FTP-сервера такой же, за исключением того, что сначала необходима авторизация.

$download_url = “ftp://download_ahyware/file1.zip”
$local_path = “C:\Downloads\file1.zip”
$user = “myFtpUser”
$pass = “myPassword123”

* в данном скрипте мы авторизовываемся на FTP-сервере с учетной записью myFtpUser и паролем myPassword123. После, как в примере выше, мы скачали файл в папку C:\Downloads.

Распаковываем архив

Чаще всего, файлы в сети Интернет хранятся в сжатом виде. Поэтому, после загрузки файла есть необходимость его распаковать. Для этого в Powershell можно использовать следующую команду:

Однако, не все версии Powershell поддерживают командлет Expand-Archive. В таком случае можно вызвать стороннее приложение, например 7-zip. Пример скрипта:

Возможные ошибки

Исключение при вызове downloadfile с 2 аргументами исключение во время запроса webclient

Причина: как правило, неправильно указан путь для загрузки или отсутствие прав на папку, в которую должно идти скачивание.

Решение: проверяем путь или пробуем указать другой.

Источник

Как работать с Invoke-WebRequest в Powershell и алиасом Wget создавая запросы HTTP и HTTPS

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Навигация по посту

Создание запроса HTTP и HTTPS в Powershell

После выполнения простого запроса мы увидим полученную информацию:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Если вы имеете прямую ссылку на файл и хотите его скачать нужно дополнительно указать ключ OutFile:

Так же можно скачивать любой файл формата ZIP,MP4 и так далее.

Доступ к свойствам

Почти любая команда в Powershell по умолчанию выводит меньше информации чем имеет. Что бы вывести все можно использовать следующий подход:

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

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

И таким образом выводить данные:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Само содержимое веб документа может быть доступно по двум свойствам:

Использование заголовков

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

Заголовки указываются в формате хэш-таблиц. Для примера так будет выглядеть запрос с указанными заголовками:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Если вы будете испытывать сложности с составлением заголовков, то можно включить отладчик на F12 и открыть закладку Networks и скопировать их. Они находятся в выделенной части на скриншоте:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Кстати через это же меню в Chrome можно получить уже сформировавшийся запрос с командой нажав на нужный элемент и выбрав “Copy as Powershell”:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Команда получится достаточно длинной, но это поможет избавиться от долгих поисков нужных заголовков:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Вы можете увидеть вторую кнопку “Copy all as Powershell”, которая сформирует объект типа “[object Promise]”, но информацию как работать с этим я не нашел.

Такой способ не поможет пройти аутентификацию на сайте так как в Chrome Cookies устанавливаются в параметр Headers, но судя по документации они должны передаваться через параметр WebSession.

Cookies

Для входа на сайт, где используется аутентификация, понадобится использовать Cookies, которые можно увидеть на скриншоте выше. Cookies вводятся отдельно от заголовков и их можно указать двумя путями.

Во время выполнения аутентификации через Poweshell мы можем указать переменную куда будут сохранены данные, а затем передать ее для следующего запроса. В примере ниже такая переменная называется SavedSession:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Как вы можете увидеть в этой переменной хранятся и заголовки.

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Теперь мы должны добавить в поле Cookies данные и передать через командлет, я использовал алиас wget:

Cookie, которые мы передали соответствуют Password=123.

Работа с формами и загрузка

Когда мы заполняем какую-то форму на сайте или выполняем загрузку мы чаще используем метод POST, а не GET, который стоит по умолчанию. Метод можно увидеть в коде или в описании документации, если используете приложения или API:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Чаще всего используются методы описанные выше, но в Powershell доступно больше:

Ключ, в котором используются эти параметры так и называется Method:

Для заполнения форм, в версии Powershell 6 +, можно использовать следующий подход:

Кодировка

Если вы используете данные, которые отличаются от латиницы вы можете столкнуться с проблемой кодировок. Дело в том, что следующие данные будут отосланы не в UTF-8, хоть это и будет указано:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Если вы не хотите испытывать сложностей с этим командлетом я бы советовал использовать разные ключи для заголовков если у вас есть такие данные. Если указать кодировку в параметре ContentType, то все сработает нормально:

Вы так же можете посылать данные таким образом:

Аутентификация

Посмотрим на три способа аутентификации используя: базовую (Basic), с использованием сертификата, NTLM и Kerberos.

Базовая аутентификация

Обычно сервер передает дополнительные данные для аутентификации, но в примере ниже это выполнение без их использования:

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

Используя сертификат

Если у вас установлен сертификат, то вы можете его использовать только указав отпечаток (Thumbprint):

NTLM и Kerberos

Этот ключ не будет работать вместе с аутентификацией типа Basic.

Парсинг сайтов

Парсинг, то есть возможность собирать информацию с сайтов, в Powershell реализована достаточно просто. Если мы посмотрим какие свойства имеет объект команды Invoke-WebRequest, сможем увидеть теги:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Картинки

Для примера в HTML картинки хранятся в таком виде:

То есть все картинки имеют тег IMG и SRC. В Powershell часть тегов уже собрана в отдельные свойства и так мы получим список всех картинок:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Мы видим только ссылки на картинки, а значит нам нужно выполнить еще по запросу для каждой картинки. К тому же я хочу сохранить существующие имена для каждой картинки, так как у них разные форматы (PNG, JPG). Это будет выглядеть примерно так:

Обратите внимание, что если у вас не создана директория куда будут сохранятся картинки, появится ошибка. Iwr не создает директории.

Парсинг других тегов

Парсинг остальной части сайта мало чем отличается от примера с картинками. Так как Images и Links выведены как основные свойства, то поиск, например, заголовков должен делаться через свойство AllElements. Для примера так я найду все теги h2:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Кроме поиска по тегам часто приходится искать по классам. Например так я найду все заголовки h2, но используя класс:

По умолчанию мы не можем работать с JSON объектами. Они будут восприниматься как строки пока мы не конвертируем объект в PSCustomObject. Это делается так:

После этого мы можем обращаться к свойствам:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

После изменения мы возможно захотим отправить объект. Для этого мы конвертируем из PSCutomObject в JSON:

Как получать и изменять свойства файлов в Powershell

Работа с классом Net.WebClient

При работе в Powershell доступен еще один метод для доступа к веб страницам и скачивания файлов Net.WebClient. Этот класс имеет методы все из которых мы можем увидеть так:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Скачивание

Метод DownloadString() позволяет скачивать информацию. Так, например, мы получим содержимое главной страницы сайта:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Как вы видите есть проблема с кодировкой. Ее можно исправить так:

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Для скачивания файлов используем метод DownloadFile():

Источник

Вадим Стеркин

Я изучаю PowerShell по мере возникновения задач. Если надо что-то автоматизировать, я смотрю, как соотносится реализация в PowerShell с моими знаниями. И держу в уме, что мне есть к кому обратиться, если знаний не хватит 🙂

[+] Сегодня в программе

История вопроса и задача

Есть замечательный ресурс smartfiction.ru, публикующий по будням короткие рассказы. Для меня главная ценность в их автоматической доставке на Kindle. Работает это очень просто: на сайте даете почтовый адрес Kindle, а в настройках Amazon добавляете в разрешенные адрес рассылки, после чего книга скачивает отправленные рассказы автоматически.

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Точнее – работало, потому что в какой-то момент рассказы перестали приходить. Сервис подписки на другом домене, а он недоступен, как выяснилось. Я написал письмо на адрес обратной связи, но оно осталось без ответа. Однако рассказы на сайте публикуются, и под каждым есть ссылка для загрузки в mobi.

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Поэтому задача свелась к тому, чтобы автоматизировать закачку этих файлов. Первая мысль была расчехлить консольный wget, но тут же возникла ассоциация с PowerShell. Ведь wget – это псевдоним командлета Invoke-WebRequest.

Получение содержимого страницы и выбор нужных ссылок

Invoke-WebRequest умеет отправлять запросы HTTP/HTTPS/FTP, парсить ответ и возвращать наборы элементов HTML – ссылки, формы, изображения и т.д. Попробуйте любой сайт так:

Для каждой ссылки легко выводится набор атрибутов.

Выше показана только первая ссылка страницы, но нужна конкретная. В Chrome щелкните правой кнопкой мыши по ссылке – «Посмотреть код элемента» и сопоставьте с выводом PowerShell. Интересующие атрибуты – это innerText (текст ссылки) и href (URL).

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров

Передав запрос по конвейеру командлету Where-Object, можно получить список всех ссылок на книги в формате mobi (ниже показана только первая).

Загрузка файлов по ссылкам

Информации выше уже достаточно для первой версии скрипта.

Первые три строки вы уже видели, поэтому разберу четвертую. Список ссылок по конвейеру передается командлету ForEach-Object (псевдоним %). Он выполняет запрос для каждой ссылки ($_.href) и сохраняет ответ сервера в файл со случайным именем и расширением mobi. Таким образом, со страницы скачиваются все книги в формате mobi.

Случайное имя с числовым значением от 0 до 10001 генерирует командлет Get-Random. Это костыль, потому что имя файла в атрибутах ссылки не содержится. Но до него можно добраться!

Парсинг заголовков

В ответ на запрос о ссылке на книгу сервер выдает такую картину.

Имя файла тут есть: filename=”hot_and_cold_blood.mobi”. Но я сразу приуныл, потому что извлечь его можно только регулярным выражением, которые я исторически не осилил. Однако меня быстро утешил в Телеграме Вадимс Поданс 🙂

Регулярное выражение берет из ответа заголовки (Headers) и вытаскивает имя файла из секции content-deposition.

В результате получается такой скрипт.

Экономия на запросах

Код выше вполне рабочий, но перфекциониста не устроит. Каждая ссылка на книгу запрашивается с сервера дважды: сначала для получения имени файла, затем для загрузки. Убрать лишний запрос из цикла несложно – достаточно присвоить ему переменную. Но я не мог сообразить, как это дело вывести в файл.

Вадимс подсказал командлет Set-Content. В данном случае он сохраняет содержимое ответа в файл с именем, полученным с помощью регулярного выражения.

Иногда серверы блокируют слишком частые запросы с одного хоста. Поэтому в качестве последнего штриха я добавил в цикл трехсекундную паузу командлетом Start-Sleep.

Если хотите потренироваться, вот тут масса бесплатных книг Microsoft. А у вас возникают подобные задачи? Как решаете?

Метки: PowerShell, скрипты Информация в статье применима к Windows 7 и новее

Об авторе

Вас также может заинтересовать:

Я в Telegram

Подпишитесь на канал и читайте интересные записи чаще! Есть вопросы? Задайте их в чате.

комментариев 13

Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Смотреть картинку Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Картинка про Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметров. Фото Командлет invoke webrequest в конвейере команд в позиции 1 укажите значения для следующих параметровnett00n

Сначала хотел написать, что при помощи Bash и curl/wget получилось бы проще, потом смоделировал скрипт в голове и понял, что нет, не проще.

Думаю, что это можно было сделать с помощью MS Flow (аналог IFTTT, но более мощный) без программирования. Но у них ограничение на количество бесплатных запусков — 75. Хотя в данном случае — этого хватит. 🙂

MS Flow умеет парсить веб-страницы?

nett00n:
Сначала хотел написать, что при помощи Bash и curl/wget получилось бы проще, потом смоделировал скрипт в голове и понял, что нет, не проще.

Лучше на другом сайте тренироваться, а то сломаем хороший сайт окончательно.

Вот тут куча бесплатных книг Microsoft.

Публикуется не более одного рассказа в день. Если скрипт запускать ежедневно, и качать только последний, то Start-Sleep не нужен. Иначе нужно вести учет скачанного или проверять существование файла, для исключения повторной закачки. Для перфекциониста это как серпом по :).
И зачем запрашивать заголовки, если имя файла можно получить сразу из url-а? А так как читалка берет инфу из тегов, и ей имя по-барабану, то можно и суррогатным обойтись. Только не случайное число а дату.

Lecron: Иначе нужно вести учет скачанного или проверять существование файла, для исключения повторной закачки.

Я, конечно, думал об этом, но решил не уводить скрипт в сторону, потому что этот момент все-таки специфичен для мой конкретной задачи.

Lecron: И зачем запрашивать заголовки, если имя файла можно получить сразу из url-а? А так как читалка берет инфу из тегов, и ей имя по-барабану, то можно и суррогатным обойтись.

Цель поста — показать приемы на конкретной задаче. В данном случае имя файла не имеет значения, конечно. Но в каком-то другом — скорее да, чем нет.

Можно парсить URL, но парсинг заголовков полезнее. Например, для задачи, где в URL — linkID=45105045.

Lecron: Только не случайное число а дату.

🙂 Дата была в исходном варианте скрипта, но я уже разбирал Get-Date в блоге, а Get-Random — нет.

Vadim Sterkin: Я, конечно, думал об этом, но решил не уводить скрипт в сторону, потому что этот момент все-таки специфичен для мой конкретной задачи.

ОК. Тогда строго по теме. Доступ не только к ссылке, но и извлечение информации из произвольного селектора (div). Итерация по блокам, например книгам «div.post» и обращение к селекторам только внутри него. Пара примеров доступа по классу, id, произвольному свойству, css query.
Это не выйдет за рамки простого примера, но и не окажется настолько примитивным. Понимаю, что есть книги, но эта информация скорее нужна не для обучения, а для оценки перспектив. Прикинуть, насколько стоит использовать штатный инструмент и когда станет пора расчехлять нечто по-мощнее.

Я написал на примере практической задачи, причем вполне распространенной (см. ссылку в конце статьи). Примитивно? Нет, но просто.

А для ваших хотелок у меня практических задач нет. И даже если будут, вряд ли стану писать для 2.5 человек.

Хотите оценить перспективы — попробуйте сами сделать то, что вы попросили.

Такой же подход, изучаю по мере выполнения задач. Накатал скриптов, начиная от задач, связанных с музыкой — рип, конвертация, прослушивание, в основном, как скриптовый фронт-енд к lame, vorbis, упорядочивания встроенных тэгов и т.д. Для загрузки rss-лент, анекдотов, цитат и прочей погоды. Ну и конечно для выполнения повседневных задач, связанных с администрированием личного ноутбука.

Источник

Leave a Reply

Your email address will not be published. Required fields are marked *