środa, 31 sierpnia 2011

Pobieranie informacji o książce/płycie o podanym numerze UPC/EAN z amazon.com

Jest gotowa aplikacja służąca do katalogowania książek za pomocą czytnika kodów kreskowych opisana w artykule A Perl script catalogs books and CDs... (tu jest wersja HTML z likiem do kodu źródłowego opisanego skryptu).

Od pierwsze strzału aplikacja nie działa. Żeby w ogóle Perl chciał program wykonać należy z przodu pliku dodać wiersz:


## http://perlmeister.com/forum/viewtopic.php?t=3596&sid=59d9cb0bda64235bda70315d6e9031e8
use POE::Loop::Tk ;

Teraz działa ale nie zawsze. Ponadto program Schilli'ego w zamierzeniu obsługuje tylko kody UPC a moje książki/płyty są oznaczane kodem UPC i/lub EAN.

Kody EAN są 13 cyfrowe a UPC 12 cyfrowe. Żeby było śmieszniej amazon.com nie rozumie kodów EAN -- trzeba odpytywać jakąś europejską filię, np. amazon.co.uk.


## moja wersja procedury amzn_fetch:
sub amzn_fetch {
my($upc_or_ean) = @_;
my $resp;

my $amz_locale = 'us'; # default is US
if ( length ("" . $upc_or_ean ) > 12) {
$amz_locale = 'uk';
print STDERR "*** $upc_or_ean looks like EAN code\n";
} else {
$amz_locale = 'us';
print STDERR "*** $upc_or_ean looks like UPC code\n";
}

my $amzn = Net::Amazon->new(
token => $amz_token,
secret_key => $amz_secret,
locale => $amz_locale,
ua => $UA,
);

my $req ;
if ( $amz_locale eq 'uk') {
print STDERR "*** Fetching from $amz_locale with mode $current_amz_cat ***\n";
$req = Net::Amazon::Request::EAN->new(
ean => $upc_or_ean,
mode => $current_amz_cat,
);
} else {
print STDERR "*** Fetching from $amz_locale with mode $current_amz_cat ***\n";
$req = Net::Amazon::Request::UPC->new(
upc => $upc_or_ean,
mode => $current_amz_cat,
);
}

$resp = $amzn->request($req);

## ... itd ...

Skrypt Schilli'ego zakłada ponadto, że zapytanie zawiera UPC/EAN oraz nazwę kategorii (books, music DVD), bo tak kiedyś działał Amazon. Teraz wydaje się, że działa inaczej. Podanie np. kodu książki + kategorii music, daje błąd. Nie zamierzałem grzebać w pakiecie Net::Amazon, więc zmieniłem skrypt w ten sposób, że kategoria jest deklarowana explicite przez operatora:


my @MODES = qw(books music dvd);

## ... itd ...

## cf. http://www.ibm.com/developerworks/aix/library/au-perltkmodule2/
my $MODE = $top->Label();

my $current_amz_cat = $MODES[0]; ## domyślną jest pierwsza kategoria
foreach(@MODES) {
$MODE->Radiobutton(
-text => $_,
-value=> $_,
-variable => \$current_amz_cat,
-command => sub {
print STDERR "*** Current mode is: $current_amz_cat \n";
} )->pack(-side => 'left', -expand => '1', -fill => "x" )
}

Na wypadek gdyby operator zapomniał kliknąć w co trzeba:


if($mode eq "books") {

eval { $resp->properties()->isbn(); } ; ## bez eval będzie krasz

if ($@) {## błąd jeżeli `item' nie zawiera isbn, tj. nie jest książką...
print STDERR "*** ERROR: $@\n";
$PRODUCT->configure( -text => "NOT BOOKS TYPE ITEM / REENTER"); return 1; }
## ... itd ...

Opis książki różni się od opisu CD (np. książka ma element isbn a płyta tracks). Schilli ominął ten problem ignorując elementy specyficzne, definiując jeden typ rekordu i jedną tabelę. Ostatnia zmiana w porównaniu do skryptu Schilli'ego, to dodanie do bazy pola przechowującego opis książki/CD w formacie XML (zamiast definiowania różnych tabel dla książek, płyt CD i filmów). W zależności od typu danych ten opis XML zawiera to co trzeba (czyli specyficzne dla opisywanego obiektu atrybuty). Np:


Edward R. Tufte
Edward R. Tufte
The Visual Display of Quantitative Information
Graphics Press USA
2nd edition
2001-01-31
0961392142

]]>

Tak działającym skryptem skatalogowałem jakieś 30--40% zawartości mojej biblioteki. Stare książki nie mają kodu kreskowego. Część polskich książek jest w zasobach Amazona ale części nie ma (np. książki wyd. Readme -- i słusznie bo to prawie w całości badziewie:-)

Tu jest corpus delicti. Moja biblioteka jest tutajtutaj -- jakby ktoś był ciekaw.

Skrypty można znaleźć tutaj.

Dopisane 1 września 2011: Zapomniałem napisać o istotnej sprawie. Żeby móc odpytywać Amazon trzeba się zapisać do Product Advertising API, tj. założyć konto. Aby móc korzystać z ww. API trzeba wypełnić odpowiedni formularz i zgodzić się na licencję, która jest mówiąc oględnie taka sobie.

To begin the enrollment process, you must submit a complete and accurate enrollment form. In your enrollment form, you must describe the application you intend to develop and use with the Product Advertising API or on which you intend to display Product Advertising Content. We will evaluate your enrollment form and notify you of its acceptance or rejection. We may reject your enrollment form if we determine that your application is unsuitable. Unsuitable applications include those that:

do not have as their principal purpose advertising and marketing the Amazon Site and driving sales of products and services on the Amazon Site

Wygląda groźnie ale wystarczy podać -- jako opis aplikacji -- URL, pod którym będziemy ,,promować'' Amazon. Proces koncesyjny jest (póki co?) uproszczony -- nikt niczego nie rozpatruje. Ale to się może zmienić...

In addition, we may terminate or suspend your license to access and use the Product Advertising API, Data Feed, or any part of or all Product Advertising Content at any time without terminating this License Agreement by giving you written notice.

Jednym słowem do poważnych zastosowań to się nie nadaje. Ale do katalogowania własnej biblioteczki może być...

Po założeniu konta, pod adresem Manage Your AccountAccess IdentifiersClick here w rubryce Access Credentials tworzymy/zarządzamy Access Key ID/Secret Access Key -- niezbędnymi do korzystania z opisywanego wyżej skryptu:


my $amz_token = '???'; ## Access Key ID
my $amz_secret = '???'; ## Secret Access Key

Brak komentarzy:

Prześlij komentarz