Home > IE, Powershell > [PL] #PowerShell and Regular Expressions

[PL] #PowerShell and Regular Expressions

Euro za pasem, a tutaj trzeba się zabrać do roboty! Nie ma co przedłużać i przejdę do rzeczy – wyrażenia regularne nie są takie straszne, a użycie ich w PowerShellu jest bardzo proste i przyjemne  (pomijam tutaj już samą w sobie zawiłość wyrażeń regularnych).

Problem

Wyciągnij ze strony web, zawierającej kilka tabelek dane  z tabelki posiadającej styl data. Następnie zapisz te dane do pliku CSV. W skrócie, czy jak to niektórzy piszą – po ludzku (I do not know who/what a human is, I am just a developer) – sparsuj HTMLa.

Rozwiązanie

Jedno z rozwiązań bazuje na wyrażeniach regularnych. Problem powyżej może dotyczyć każdego innego dokumentu tekstowego, także nie-HTMLowego. Pomijając zadanie ściągnięcia HTML strony z podanego urla (mozna użyć dowolnego skryptu symulującego wgeta) musimy jedynie załadować plik HTML:

$html = cat -raw -encoding utf8 page.html

I użyć wyrażeń regularnych.  Do wyciągnięcia pojedynczego/pierwszego spełnienia wyrażenia lub też do sprawdzenia czy w przekazanym łańcuchu dane wyrażenie regularne jest spełnione służy -match. Zwraca on nic innego jak true lub false, które może być od razu użyte w warunku if.

if ($cat -match '<table>(?<rows>((?!</table>).)*)</table>') { }

W wyrażeniu tym szukam tekstu, które dopasuje się do wzorca tabelki  w HTML z klasą data. Wnętrze tej tabeli zapamiętam w grupie o nazwie rows. W przypadku, gdy wyrażenie jest spełnione, możemy wyciągnąć dopasowanie , a także poszczególne nazwane grupy z używając zmiennej $matches.

$innerTable= $matches["rows"]

W ten sposób udało się znaleźć tabelę i wyciągnąć jej wnętrze. Do wyciągania danych z poszczególnych wierszy tabeli można użyć już cmdleta Select-String, który pozwala już na więcej

$innerTable | Select-String "<tr((?!>).)*>((?!</tr>).)*</tr>" -AllMatches -List |  %{ }

Przekazując go na zewnątrz do kolejnej funkcji (czy też naszego bloku skrytpu) możemy wyciągnąć wiele ciekawych rzeczy odwołując się do listy poszczególnych dopasowań znajdujących się w propercji Matches. Użycie samego $_ zwróci nam analizowany tekst.

foreach ($match in $_.Matches) {
  # dla każdego dopasowania (wiersza tr)
  # zbuduj obiekt csvRow
  $csvRow # wurzuć na zewnątrz, a tam użyj Export-Csv
}

Dalej nic nie stoi na przeszkodzie, aby w podobny sposób wyciągnąć dane z komórek i utworzyć obiekt PS, dodać propercje, wyrzucić obiekt na zewnątrz, a następnie przechwycić i zapisać do CSVki.

Sposób drugi

Można pobawić się odwołując do poszczególnych elementów HTML za pomocą przeglądarki. Ale to już wykracza poza temat postu.

$ie = new-object -com InternetExplorer.Application
$ie.Navigate('http://mypage.com')
$ie.Document
Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: