W książce Flickr Hacks Paula Bauscha i Jima Bumgardnera
do manipulowania danymi w formacie XML
przesyłanymi z flickr.com
używa się XML::Simple
. Jakoś XML::Simple
nie wydaje mi się specjalnie
simple w tym wypadku. Zdecydowanie wolę XML::LibXML
,
który pozwala przede wszystkim na dotarcie do poszczególnych fragmentów dokumentów XML
w prosty sposób bez używania karkołomnych referencji.
Przykładowo poniższy skrypt (fragment) wykonuje zapytanie flickr.photos.search
[najistotniejszą częścią skryptu -- zaznaczoną odmiennym kolorem tła --
jest pętla do { ... }
]:
use XML::LibXML;
use LWP::Simple;
use Getopt::Long;
require 'login2flickr.rc';
our $api_key;
our $my_flickr_id;
my $tags_txt;
my $show_help;
my ($user_id, $all_users, $report_views);
my @Photos;
GetOptions( "all" => \$all_users,
"user=s" => \$user_id, "views" => \$report_views,
"tags=s" => \$tags_txt);
unless ( $user_id ) { $user_id = $my_flickr_id; }
if ( $all_users ) { $user_id = ''; } ## search all photos
my $parser = XML::LibXML->new;
my $pageno;
my $method = 'flickr.photos.search';
my $max_per_page = 500;
my ($total_pages, $current_page);
my $search_query = "&extras=geo,views"; # http://www.flickr.com/services/api/flickr.photos.search.html
if ( $user_id ) { $search_query .= "&user_id=$user_id"; }
if ( $tags_txt ) { $search_query .= "&tags=$tags_txt" }
do {
$pageno++;
my $resp = get ( "http://www.flickr.com/services/rest/?" .
"method=$method&api_key=$api_key&per_page=$max_per_page&page=$pageno" .
$search_query );
## sprawdź czy jest OK:
my $photos = $parser->parse_string($resp);
unless ( $photos->getElementsByTagName('rsp' )->[0]->getAttribute( 'stat' ) eq 'ok') {
die "Problems with retriving photo list!\n" }
push @Photos, $photos->getElementsByTagName('photo' );
$total_pages = $photos->getElementsByTagName('photos' )->[0]->getAttribute('pages' );
$current_page = $photos->getElementsByTagName('photos' )->[0]->getAttribute('page' );
# Dla dużych zbiorów zdjęć może długo trwać, więc wypisz że coś robisz:
printf STDERR " *** Page %d of %d retreived...\n", $current_page, $total_pages;
} while ( $current_page lt; $total_pages );
## Lista @Photos zawiera wszystkie zdjęcia...
## ... dalsza część skryptu ...
Pętla jest niezbędna ponieważ flickr API
organicza wielkość zwracanego dokumentu do maksymalnie 500 zdjęć.
Jeżeli zdjęć jest więcej, to zapytanie należy zadać wielokrotnie, zmieniając wartość parametru
page
. Przy czym liczbę wszystkich stron określa wartość atrybutu pages
.
Po ściągnięciu dokumentu skrypt sprawdza czy wszystko jest OK. Jeżeli tak, to za pomocą
getElementsByTagName
pobiera wszystkie elementy photo
i dodaje
je do listy @Photos
. Teraz pobierane są wartości atrybutów pages
/page
w celu ustalenia czy wszystko już ściągnięto. Jeżeli pages
< page
to pętla działa dalej...
Zwracam uwagę, że od jakiegoś czasu zapytanie może zawierać parametr extras
, dzięki
któremu zwracany dokument XML zawiera dodatkowe informacje, takie jak: tagi, współrzędne geograficzne,
liczbę odsłon, itd...
Jest to opisane w API na flickr.com a także
tutaj.
W wyżej przedstawionym skrypcie deklaracja:
my $search_query = "&extras=geo,views";
Oznacza, że do standardowych opisów zdjęć będą dodane także współrzędne geograficzne (oczywiście
tylko wtedy gdy zdjęcia będą nimi oznaczone) oraz liczba odsłon. BTW dodanie extras=views
powoduje, że kiedyś niemożliwy do wykonania poprzez API problem ustalenia ile razy zdjęcie było
oglądane teraz jest jak najbardziej wykonalny. Zatem skrypty -- opisane
w Nowa usługa na flickr.com
oraz Czy flickr umie liczyć -- lepsze rozwiązanie
-- są już niepotrzebne.
Kompletny skrypt pobierający zdjęcia z flickr.com i wypisujący plik GPX dla tych, które zawierają współrzędne geograficzne jest tutaj. Ale uwaga: próba wykonania zestawienia wszystkich wież ciśnień z flickr.com:
flickr_photo_gsearch.pl -a -t 'wieżaciśnień,wasserturm,watertower' > wasserturme-alles.xml
Skończyła się pobraniem ponad 23 tysięcy zdjęć (z tego około 6 tys. było geokodowane). Plik GPX pn. wasserturme-alles.xml miał 1,8 Mb i za nic nie szło tego wyświetlić w przeglądarce. Za duże... Mniejsze pliki są ok: kaplice [mapa ] albo moje wieże ciśnień [mapa ].