Invoke-WebRequest Обробка вмісту веб-сторінок і HTML сайтів в Powershell

У PowerShell версії 3.0 з'явилася можливість безпосередньо звертатися і працювати з HTML веб-сторінок в Інтернеті. Для цього був розроблений спеціальний командлет Invoke-WebRequest. Даний командлет дозволяє реалізувати безліч сценаріїв: починаючи від можливості скачати / завантажити файл з / на будь-якого веб-сайту по HTTP / HTTPS / FTP, закінчуючи можливостями парсинга HTML сторінок, моніторингу стану веб серверів, заповнення та відправкою веб-форм. В цілому, новий командлет надає всі необхідні методи для навігації по DOM дереву HTML документа. У цій статті ми розберемо базові приклади роботи з Командлети PowerShell Invoke-WebRequest.

зміст:

  • Використання командлета Invoke-WebRequest
  • Отримуємо список всіх HTML посилань на сторінці
  • Парсинг HTML сторінок за допомогою Powershell
  • Як завантажити файл з HTTP за допомогою PowerShell
  • Заповнення і відправка веб-форм на Powershell
  • Недоліки командлет Invoke-WebRequest

Порада. Командлет Invoke-WebRequest доступний в Windows PowerShell 3.0, тому перед початком роботи переконайтеся, що у вас використовується ця або більш свіжа версія. Якщо на комп'ютері встановлено кілька версій Posh, переключитися між ними можна так.

Використання командлета Invoke-WebRequest

командлет Invoke-WebRequest (Псевдонім wget) може відправляти і отримувати HTTP, HTTPS і FTP запити, обробляти повертається сервером відповідь. Отримана відповідь являє собою набір колекції форм, посилань, зображень та інших важливих елементів HTML документа.

Спробуємо виконати наступну команду:

Invoke-WebRequest -Uri "http://winitpro.ru"

Порада. Якщо ви підключені до Інтернет через проксі-сервер то для коректної роботи командлетів PoweShell, скористайтеся порадами зі статті: Як налаштувати PowerShell для доступу через проксі-сервер.

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

$ WebResponseObj = Invoke-WebRequest -Uri "http://winitpro.ru"
$ WebResponseObj | Get-Member

Щоб отримати сирої HTML код веб сторінки, який міститься в даному об'єкті, виконайте:

$ WebResponseObj.content

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

$ WebResponseObj.rawcontent

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

$ WebResponseObj.Headers

Як ви бачите, веб сервер повернув відповідь 200, тобто запит виконаний успішно і веб сервер доступний і працює коректно.

Отримуємо список всіх HTML посилань на сторінці

Звернемося до головній сторінці нашого сайту і отримаємо список посилань, наявних на ній:
$ SiteAdress = "http://winitpro.ru"
$ HttpContent = Invoke-WebRequest -URI $ SiteAdress
$ HttpContent.Links | Foreach $ _. Href

Щоб отримати і сам текст посилання (міститься в елементі InnerText), можна скористатися такою конструкцією:

$ HttpContent.Links | fl innerText, href

Можна вибрати тільки посилання з певним CSS класом:

$ HttpContent.Links | Where-Object $ _. Class -eq "page-numbers" | fl innerText, href

Або певним текстом в url:

$ HttpContent.Links | Where-Object $ _. Href -like "* exchange *" | fl innerText, href

Парсинг HTML сторінок за допомогою Powershell

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

За допомогою Powershell отримаємо вміст головної сторінки нашого сайту:

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

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

$ Img.Images

Сформуємо колекцію з повних url шляхів до використовуваних зображень:

$ Images = $ Img.Images | select src

Ініціалізіруем новий екземпляр класу WebClient:

$ Wc = New-Object System.Net.WebClient

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

$ Images | foreach $ wc.DownloadFile ($ _. src, ( "c: \ tools \" + [io.path] :: GetFileName ($ _. src)))

Як цікавий приклад використання командлет Invoke-WebRequest можна привести спосіб дізнатися зовнішнього IP адреси комп'ютера з PowerShell.

Як завантажити файл з HTTP за допомогою PowerShell

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

Invoke-WebRequest "https://download.mozilla.org/?product=firefox-32.0.3-SSL&os=win&lang=ru" -outfile "c: \ tools \ firefox setup 32.0.3.exe"

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

Так само ви можете завантажити файли з веб-сервера за допомогою BITS в синхронному режимі.

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

$ OutDir = "C: \ Downloads \ docs \ PDF"
$ SiteAdress = "https://www.site.ru/free-pdf-books/"
$ HttpContent = Invoke-WebRequest -URI $ SiteAdress
$ HttpContent.Links | Where-Object $ _. Href -like "* .pdf" | % Invoke-WebRequest -Uri $ _. Href -OutFile ($ OutDir + $ (Get-Random 100000) + ". Pdf")

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

У PowerShell 6.1 команделт Invoke-WebRequest підтримує режим докачки. Таким чином за допомогою параметра Invoke-WebRequest -Uri $ Uri -OutFile $ OutFile -Resume ви можете відновити завантаження файлу в разі падіння каналу або сервера.

Заповнення і відправка веб-форм на Powershell

Багато веб-сервіси для роботи вимагають введення різних даних в HTML форми. За допомогою Invoke-WebRequest можна отримати доступ до будь-якої HTML-формі, заповнити необхідні поля і передати заповнену форму назад на сервер. У цьому прикладі ми покажемо, як за допомогою Powershell авторизуватися в поштовій скриньці популярного російського сервісу mail.ru через його стандартну веб форму.

За допомогою наступної конструкції збережемо інформацію про куках (Cookies) підключення в окремій сесійного змінної:

$ Mailru = Invoke-WebRequest https://e.mail.ru/login -SessionVariable session

Наступною командою відобразимо список заповнюваних полів в HTML формі авторизації (форма називається LoginExternal):

$ Mailru.Forms [ "LoginExternal"]. Fields

Дамо потрібні значення всім полям:

$ Mailru.Forms [ "LoginExternal"]. Fields [ "Login"] = "[email protected]"

$ Mailru.Forms [ "LoginExternal"]. Fields [ "Password"] = "Str0NgP $$ w0rd"

І т.д… .

Щоб передати заповнену форму на веб сервер, викличемо атрибут HTML-форми action.

$ Log = Invoke-WebRequest -method POST -URI ( "https://e.mail.ru/login" + $ mailru.Forms [ "LoginExternal"]. Action) -Body $ mailru.Forms [ "LoginExternal"]. Fields -WebSession $ session

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

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

Інша проблема - командлет Invoke-WebRequest тісно пов'язаний з Internet Explorer. Наприклад, в редакціях Windows Server Core, в яких IE не встановлено, командлет Invoke-WebRequest використовувати не можна.

Якщо на HTTP сайті використовується самоподпісанний сертифікат, то командлет Invoke-WebRequest відмовляється отримувати дані з нього. Щоб ігнорувати некоректний SSL сертифікат, використовуйте наступний код:

Ігнорувати SSL сертифікат можна так:
add-type @ "
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy: ICertificatePolicy
public bool CheckValidationResult (
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem)
return true;


"@
[System.Net.ServicePointManager] :: CertificatePolicy = New-Object TrustAllCertsPolicy
$ Result = Invoke-WebRequest -Uri "https://site.ru"