Download: Programowanie_Perl
Transkrypt
Download: Programowanie_Perl
PROGRAMOWANIE
Perl
Automatyczny dostęp do stron WWW
Wysysanie informacji
Czasami bywa tak, że przekopanie
się przez złożoną strukturę serwisu
WWW w celu wyszukania kilku prostych informacji, staje się prawdziwą mordęgą. Moduł Perla o nazwie
WWW::Mechanize::Shell ułatwia
tworzenie narzędzi, które działają
jak przeglądarki i automatyzują dostęp do stron WWW.
MICHAEL SCHILLI
W
Kalifornii można za niewielką
opłatą umieścić dowolny napis
na tablicach rejestracyjnych pojazdów. To wyjaśnia, dlaczego napis na tablicach mojej 13-letniej Integry Acura ma
postać „PERL MAN” (Rysunek 1).
Kalifornijski Departament Pojazdów
Silnikowych postanowił iść z duchem czasu i udostępnił stronę WWW, na której
można sprawdzić możliwość zarejestrowania danej nazwy. Niestety większość klientów narzeka na bardzo wolny dostęp do
strony. Artykuł opisuje, w jaki sposób można zastosować skrypt Perla do emulacji wywołań WWW.
Rysunek 1: Wspaniały PERL MAN: Chociaż
13-letni, ale ciągle do wyścigów na światłach
ulicznych, w jakich biorą udział samochody
sportowe w San Francisco.
78
Kwiecień 2004
Napiszemy program działający podobnie
jak przeglądarka WWW, swobodnie nawigujący po stronach WWW, ale bez konieczności
interakcji z użytkownikiem, tzn. klikania myszą czy pisania na klawiaturze.
Moduły CPAN
przychodzą na ratunek
jest automatycznie konwertowana na trwały
skrypt Perl.
Opis sesji jest logiczną abstrakcją (na przykład: „podążaj za odsyłaczem zawierającym
łańcuch 'xxx' na bieżącej stronie”), co gwarantuje, że skrypt nie zawiesi się z powodu zwykłej modyfikacji formatu strony WWW.
Najwygodniejszym sposobem instalacji
potrzebnych modułów WWW::Mechanize
i WWW::Mechanize::Shell jest wykorzysta-
Moduł WWW::Mechanize Andy Lester'a udostępnia struktury do kodowania automatycznego przeglądania stron WWW
w Perlu. Ostatnie
uzupełnienie
WWW::Mechanize::Shell,
dodane
przez Maxa Maischein'a, rozszerza
funkcjonalność
o podobny do powłoki interpreter,
co znacznie ułatwia
sterowanie wirtualną przeglądarką.
Programista może
dzięki temu pracować z sesją interaktywnie – sekwencja
Rysunek 2: Strona powitalna Kalifornijskiego Departamentu Pojazdów
poleceń, np. naciSilnikowych. Zaznaczony link prowadzi do strony, na której można
skanie przycisków,
utworzyć osobiste tablice rejestracyjne.
www.linux-magazine.pl
Perl
proces ten powinien być bardziej abstrakcyjny, co pozwoli uniknąć nam błędów
w przypadku zmian na stronie WWW. Poniższe polecenie wyszukuje link zawierający łańcuch tekstowy Personalized i następnie podąża za odsyłaczem:
Rysunek 3: Powłoka udostępniana przez mo-
>open /Personalized/
duł WWW::Mechanize::Shell działa jak przeglądarka WWW. W tym przypadku użytkownik
właśnie wypełnił formularz w interaktywnym
dialogu, korzystając z polecenia fillout.
nie powłoki CPAN. Obydwa wymagają dodatkowych modułów, które są instalowane
dzięki automatycznemu rozwiązywaniu zależności. W celu umożliwienia obsługi
stron HTTPS, należy dodatkowo zainstalować moduł IO::Socket::SSL. Po zainstalowaniu modułów możemy wywołać powłokę
emulującą przeglądarkę, np. w sposób
przedstawiony poniżej:
perl -MWWW::Mechanize::Shell U
-eshell
Polecenie to wyświetla znak zachęty, oczekując na wprowadzenie poleceń przez użytkownika. W celu pobrania strony WWW
Kalifornijskiego Departamentu Pojazdów
Silnikowych możesz wprowadzić: get
http://www.dmv.ca.gov. Powłoka odpowie
komunikatem http://www.dmv.ca.gov(200)
wskazującym, że skrypt pomyślnie pobrał
stronę (kod 200 HTTP).
Wygląd strony w przeglądarce jest pokazany na Rysunku 2, a zaznaczony link „Personalized Plates” jest tym, czego szukamy.
Możemy teraz wprowadzić polecenie links
w celu sprawdzenia, jakie linki zostały odnalezione na stronie i wyświetlenia ich listy:
>links
...
[14] Vehicle Industry & U
Commercial Permits
[15] Personalized Plates
[16] Disabled Placards
...
Wyrażenia regularne
w obsłudze odsyłaczy
Użytkownik może podążyć za odsyłaczem
o numerze 15, wpisując open 15. Podawanie
tego typu wartości numerycznych może
jednak okazać się zgubne, jeśli strona zostałaby uaktualniona i liczba lub kolejność
odsyłaczy uległaby zmianie. Innymi słowy,
Jeśli wyrażenie regularne dopasuje kilka odsyłaczy na stronie, powłoka wyświetli menu
wyboru. W naszym przypadku dopasowany
jest tylko jeden link. Powoduje to wyświetlenie następującego komunikatu:
Found 15
(200)
Polecenie to przenosi wirtualną przeglądarkę
do następnej strony, posiadającej m.in. odsyłacz zawierający łańcuch tekstowy order Special Interest and Personalized licence plates. Odszukanie tego łańcucha za pomocą open „/order Special Interest/” prowadzi nas do innej
strony zawierającej kilka formularzy HTML.
Należy pamiętać, aby wyrażenie regularne podane wraz z poleceniem open zamknięte było
w cudzysłowach, jeśli tekst wyszukiwanego
łańcucha zawiera znaki spacji. W przeciwnym
wypadku prowadzi to do zamieszania w interpretatorze, który traktuje spacje jako znaki
oddzielające polecenia od argumentów. Użytkownik może wyświetlić formularz z bieżącej
strony za pomocą polecenia forms:
>forms
...
Form [2]
POST https://vrir.dmv.ca.gov/U
ipp/ PerLicensePlateServlet U
[personalized]
page=Select (hidden)
Submit2=Order Personalized U
(submit)
...
Formularz #2, nazwany etykietą personalized, jest tym, czego szukamy. Możemy go
wybrać poleceniem form „personalized”, wpisując następnie submit. Na kolejnej stronie
użytkownik może uzyskać dostęp do innego
formularza z rozwijalnym menu i przyciskami radiowymi do wybrania typu pojazdu, wyglądu tablic i innych elementów. Polecenie powłoki fillout okazuje się bardzo
przydatne właśnie dla takich skomplikowanych formularzy, pozwalając użytkownikowi interaktywnie definiować wartości dla
PROGRAMOWANIE
poszczególnych pól formularza. Ilustruje to
dialog pokazany na Rysunku 3. W celu wybrania domyślnej opcji, np. odznaczenia
przycisku radiowego kidpic, wystarczy po
prostu nacisnąć Enter. Po wypełnieniu formularza wprowadzone wartości przesyłane
są do serwera poleceniem submit.
Twoje własne
tablice rejestracyjne
Następna strona pozwala użytkownikowi na
ostateczny wybór tablic. Strona WWW, którą
widzimy w przeglądarce na Rysunku 4, zawiera jeszcze jeden formularz. Formularz używa
indywidualnych pól (!) do pobrania liter wchodzących w skład napisu na tablicy. W tym
przypadku jeszcze raz korzystamy z polecenia
fillout i później submitw do wypełnienia formularza i przesłania danych do serwera.
Skrypt
na naciśnięcie przycisku
W tym miejscu zaczyna się wreszcie dziać
coś interesującego. Naszym celem jest przerobienie sesji powłoki na skrypt do wielokrotnego wykorzystania, uruchamiany zwykłym poleceniem script.
Listing 1 prezentuje, w jaki sposób stworzyłem skrypt dmv. Zastosowałem kilka
modyfikacji. Użytkownik może teraz wprowadzić szczegóły tablicy rejestracyjnej z linii poleceń np.: dmv PERLMAN. Jeśli parametr nie zostanie podany, skrypt kończy
działanie w linii 13. Konstruktor obiektu
WWW::Mechanize ma uaktywnioną opcję
autocheck i uruchamia symulator przeglądarki w trybie, który kończy działanie programu, jeśli strona nie zostanie znaleziona.
Gotowy do użycia skrypt pojawi się natychmiast na standardowym wyjściu. Skopiuj
go za pomocą polecenia kopiuj-wklej lub
wpisując script nazwa_pliku w celu zapisania pliku na dysku.
Linia 26 wskazuje symulatorowi stronę po-
Rysunek 4: Gdy rejestrujesz samochód w Kalifornii, możesz utworzyć osobiste tablice rejestracyjne (włączając w to nawet stylowe tło)
za pośrednictwem specjalnej strony WWW
Departamentu Pojazdów Silnikowych.
www.linux-magazine.pl
Kwiecień 2004
79
Perl
witalną. Metoda follow() w linii 28 wykorzystuje wyrażenie regularne do odszukania odsyłacza zawierającego łańcuch znakowy Personalized. Linia 30 wykonuje jeszcze jedno dopasowanie wyrażenia regularnego. W linii 32
wybrany zostaje formularz o etykiecie personalized, a występująca następnie metoda submit() aktywuje przycisk Submit formularza.
Zadaniem obiektu modułu WWW::Mechanize::FormFiller, utworzonego w 22 linii,
jest obsługa wypełniania formularza, który
pojawia się później. Metoda add_filler()
określa nazwę każdego pola, metodę wejściową i wartość:
$fi->add_filler('leased' U
=> Fixed => 'N');
Fixed oznacza przypisanie twardo zakodowanych wartości, podczas gdy Interactive oznacza podstawienie wartości pobranej podczas
interakcji z użytkownikiem. Gdy wszystkie
wartości formularza zostaną zebrane, form filler może przystąpić do pracy. Metoda
fill_form, działająca w odniesieniu do agenta
bieżącego obiektu WWW::Mechanize, zajmuje się następnie wypełnieniem formularza.
Skrypt łączy się ze stroną powitalną DMV,
nawiguje używając linków oraz formularzy
i ostatecznie wykorzystuje pętlę for, zaczynającą się w linii 55, do wprowadzenia wysłanych łańcuchów tekstowych w polach wyboru. Metoda submit w linii 75 używa protokołu
SSL do przesłania danych do serwera
i wreszcie powłoka przyjmuje sformatowaną
w HTML stronę wynikową.
w tym przypadku ostrzeżenie. Przyjmując, że
napis na tablicach nie był zastrzeżony, wyświetlony zostanie formularz zamówienia.
Skrypt sprawdza wystąpienie łańcucha tekstowego Complete Order Form i odpowiada
wyświetlając XXX: available. Odpowiedź
PERLMAN: not available oznacza, że PERL
MAN jest już używany i będzie jeszcze używany przez jakiś czas w przyszłości. Może
być tylko jeden!
■
Michael Schilli jest
inżynierem aplikacji
WWW, pracuje dla
firmyAOL/
Netscape
w Mountain View
w Kalifornii.
Niedawno napisał również książkę
„Perl Power” dla wydawnictwa
Addison-Wesley. Można się z nim
kontaktować pod adresem
[email protected]. Jego
strona domowa znajduje się pod
adresem http://perlmeister.com
Może być tylko jeden
Jeśli na stronie wynikowej pojawia się napis
typu not available, możesz przypuszczać, że
kombinacja jest już w użyciu, albo że język
nie jest akceptowalny. Skrypt wyświetla
INFO
AUTOR
PROGRAMOWANIE
[1] Listingi do artykułu:
http://www.linux-magazine.pl/
Magazine/Downloads/2004/03/Perl
[2] Kalifornijski Departament Pojazdów
Silnikowych: http://www.dmv.ca.gov
Listing 2. Konwersja do typu zmiennoprzecikowego.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
80
#!/usr/bin/perl
#############################
# dmv -- Check CA plates
# Mike Schilli, 2003
# ([email protected])
#############################
use strict;
use warnings;
use WWW::Mechanize;
use WWW::Mechanize::FormFiller;
die "usage: $0 XXXXXXX"
unless defined $ARGV[0];
$ARGV[0] =~ s/\s+//g;
my $agent =
WWW::Mechanize->new(
autocheck => 1);
my $fi =
WWW::Mechanize::FormFiller->
new();
$agent->get(
'http://www.dmv.ca.gov');
$agent->follow(
qr(Personalized));
$agent->follow(
Kwiecień 2004
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
www.linux-magazine.pl
qr(order Special Interest));
$agent->form("personalized");
$agent->submit();
$fi->add_filler(
'vehicletype' =>
Fixed => 'AUTO' );
$fi->add_filler(
'leased' =>
Fixed => 'N' );
$fi->add_filler(
'platetype' =>
Fixed => 'R' );
$fi->add_filler(
'kidpic' =>
Fixed => '' );
$fi->add_filler(
'Submit2' =>
Fixed => '' );
$fi->fill_form(
$agent->current_form);
$agent->submit();
for(0..6) {
$fi->add_filler(
"LicPltCharAry$_" =>
Fixed =>
$_ > length $ARGV[0] ?
"" : substr($ARGV[0],
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
$_, 1));
}
for(0..6) {
$fi->add_filler(
"HalfSpace$_" =>
Fixed => '');
}
$fi->add_filler(
'Submit2' => Fixed => '');
$fi->fill_form(
$agent->current_form);
$agent->submit();
if($agent->content() =~
/not available/) {
print "$ARGV[0]: " .
"not available\n";
} elsif($agent->content() =~
/Complete Order Form/) {
print "$ARGV[0]: " .
"available\n";
} else {
print "Unexpected: ",
$agent->content(),
"\n";
}