Table of Contents
概要
- 大きな画像を表示する
- ASINから大きな画像のURIを求めて存在するかどうか確認する。
- 「content-type」が「image/jpeg」なら存在する、「image/gif」なら存在しない。
動作サンプル
Bookmarklet
javascript:location='http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN='+(location.href.match(/\/(dp|ASIN|product)\/([\w]+)/))[2];
スクリプト
-
getImages.zip
#!/usr/bin/perl use strict; use warnings; use utf8; use Encode; use LWP::UserAgent; use URI::Amazon::APA; use XML::Simple; use YAML::Syck; use CGI::Pretty qw( -no_xhtml *table *ol ); # //HTML 4.01 Transitional//EN use URI::Escape; $YAML::Syck::ImplicitUnicode = 1; $CGI::POST_MAX = 1024; binmode( STDIN, ":utf8" ); binmode( STDOUT, ":utf8" ); binmode( STDERR, ":utf8" ); # 自動フラッシュ有効化 (バッファリングを無効化) $| = 1; my $confyaml = './ID.yaml'; my $conf = YAML::Syck::LoadFile( $confyaml ) or die( "$confyaml: $!\n" ); my $cginame = 'Amazon getImages-JP'; my $ImageUriBase = 'http://images-jp.amazon.com/images/P/%ASIN%.09.%SHOT%._SC%SIZE%ZZZZZZ_.jpg'; my $NoImageUri = 'http://images-jp.amazon.com/images/G/09/nav2/dp/no-image-no-ciu.gif'; my $DetailUri = 'http://www.amazon.co.jp/dp/%ASIN%/'; my $CustomerImageUri = 'http://www.amazon.co.jp/gp/customer-media/product-gallery/%ASIN%'; my @ShotsFixList = ( { 'name' => 'Main', 'key' => 'MAIN', }, { 'name' => 'Top', 'key' => 'TOPP', }, { 'name' => 'Bottom', 'key' => 'BOTT', }, { 'name' => 'Left', 'key' => 'LEFT', }, { 'name' => 'Right', 'key' => 'RGHT', }, { 'name' => 'Front', 'key' => 'FRNT', }, { 'name' => 'Back', 'key' => 'BACK', }, ); my @ShotsVarList = qw( PT IN ); my %ShotsTypeList = ( 0 => 'PIECE SHOTS / 書籍以外のその他の画像', 1 => 'INTERIOR SHOTS / 書籍のその他の画像', ); my @SizeList = ( { 'name' => 'Large', 'key' => 'RM' }, { 'name' => 'Medium', 'key' => 'L' }, # { 'name' => 'Small', 'key' => 'M' }, ); my $Step = 20; my %PageLabels = (); for( my $i=0; $i * $Step < 99; ++$i){ $PageLabels{ $i } = 'PT' . substr( '0' . ( $i * $Step + 1 ), -2 ) . '-PT'. substr( '0' . ( ( $i + 1 ) * $Step ), -2 ) } $PageLabels{ 0 } = 'Main, ' . $PageLabels{ 0 }; my $PageMax = @{ [ sort { $b <=> $a } ( keys( %PageLabels ) ) ] }[ 0 ]; $PageLabels{ $PageMax } =~ s/\d+$/99/; my $q = new CGI; $q->charset('utf-8'); my $cgipath = $q->url( -absolute => 1 ); my $URI = $q->param( 'URI' ) || ''; my $ASIN = ''; unless ( $ASIN = $q->param( 'ASIN' ) ){ # Perl 5.10 $URI =~ /\/(dp|ASIN|product)\/(?'asin'[\w]+)/; $ASIN = $+{asin}; # Perl 5.8 #$URI =~ /\/(dp|ASIN|product)\/([\w]+)/; #$ASIN = $2; } if ( $ASIN ){ $URI = $DetailUri; $URI =~ s/%ASIN%/$ASIN/; } my $SHOT = ( $q->param( 'SHOT' ) ) ? 1 : 0; my $shottype = $ShotsVarList[ $SHOT ]; my $PAGE = $q->param( 'PAGE' ) || 0; if ( $PAGE < 0 || $PageMax < $PAGE ){ $PAGE = 0; } my $MOD = $q->param( 'MOD' ) || 0; my $ua = LWP::UserAgent->new( keep_alive => ( 7 + $Step ) * 3 ); my @Anchors = (); printHeader(); if ( !$ASIN || $MOD ){ print $q->start_form( -action => $q->url ), $q->table( { -summary => 'enter ASIN and so on.', -border => 1 }, $q->Tr( $q->th( 'ASIN' ), $q->td( $q->textfield( -name => 'ASIN', -value => $ASIN ) ) ), $q->Tr( $q->th( 'URI' ), $q->td( $q->textfield( -name => 'URI', -value => $URI, -size => 80 ) ) ), $q->Tr( $q->th( 'SHOT' ), $q->td( $q->popup_menu( -name => 'SHOT', -values => [sort {$a<=>$b} keys(%ShotsTypeList)], -default => $SHOT, -labels => \%ShotsTypeList, ) ) ), $q->Tr( $q->th( 'PAGE' ), $q->td( $q->popup_menu( -name => 'PAGE', -values => [sort {$a<=>$b} keys(%PageLabels)], -default => $PAGE, -labels => \%PageLabels, ) ) ), $q->Tr( $q->td( { -colspan => 2, -align => 'center' }, $q->submit, " ", $q->reset ) ), ), $q->end_form; } else { my $u = URI::Amazon::APA->new( 'http://ecs.amazonaws.jp/onca/xml' ); $u->query_form( Service => 'AWSECommerceService', Operation => 'ItemLookup', ResponseGroup => 'ItemAttributes,Images', AssociateTag => $conf->{'ASSOCIATE_TAG'}, ItemId => $ASIN, ); $u->sign( key => $conf->{'AWS_ACCESS_KEY_ID'}, secret => $conf->{'SECRET_ACCESS_KEY'}, ); my $r = $ua->get($u); if ( $r->is_success ){ print $q->h2( 'Bibliography' ); my $content = XMLin( $r->content, ForceArray => [ 'Item', 'Error', 'DetailPageURL', 'SalesRank', 'ProductGroup', 'Title', ], KeyAttr => { 'Item' => '+ASIN', }, ); my( $title, $detailpageurl, $customerimage ); if ( my $errors = $content->{'Items'}->{'Request'}->{'Errors'}->{'Error'} ){ printErrors( $errors ); } else { my $items = $content->{'Items'}->{'Item'}; my $item = $items->{$ASIN}; $title = $item->{'ItemAttributes'}->{'Title'}; $detailpageurl = $item->{'DetailPageURL'}[0]; $detailpageurl = decode( 'utf8', uri_unescape( $detailpageurl ) ); # $detailpageurl =~ s#/[^/]+/(?=dp/)#/#; # $detailpageurl = uri_unescape( $detailpageurl ); $customerimage = $CustomerImageUri; $customerimage =~ s/%ASIN%/$ASIN/; } my $pagelabel = $PageLabels{ $PAGE }; $pagelabel =~ s/PT/$ShotsVarList[ $SHOT ]/g; print $q->table( { -summary => 'Bibliography', -border => 1 }, ( $title ) ? $q->Tr( $q->th( 'TITLE' ) , $q->td( $q->a( { -href => $detailpageurl || $URI . $conf->{'ASSOCIATE_TAG'} }, $title ), $q->br(), $q->a( { -href => $customerimage }, 'Customer Image' ) ) ) : '', $q->Tr( $q->th( 'ASIN' ), $q->td( $ASIN ) ), $q->Tr( $q->th( 'SHOT' ), $q->td( $ShotsTypeList{ $SHOT } ) ), $q->Tr( $q->th( 'PAGE' ), $q->td( $pagelabel ) ), ); print $q->h2( 'Search Results' ); $ImageUriBase =~ s/%ASIN%/$ASIN/; print $q->p( { -id => 'status' }, 'Now searching...' ); if ( $PAGE == 0 ){ foreach my $shot ( @ShotsFixList ){ my $ImageUri = $ImageUriBase; my $shotkey = $shot->{'key'}; $ImageUri =~ s/%SHOT%/$shotkey/; searchSize( $ImageUri, $shot->{'name'} ); } } for( my $i=$PAGE*$Step; $i<($PAGE+1)*$Step && $i<99; ++$i ){ my $ImageUri = $ImageUriBase; my $shotkey = $shottype . substr( '0' . ( $i + 1 ), -2 ); $ImageUri =~ s/%SHOT%/$shotkey/; searchSize( $ImageUri, $shotkey ); } if ( @Anchors ){ print $q->h2( $q->a( { -name => 'INDEX', -id => 'INDEX' }, 'Index' ) ), $q->start_ol(), $q->li( [ map { $q->a( { -href => '#' . $_ }, $_ ) } @Anchors ] ), $q->end_ol(); } else { print $q->p( $q->img( { -src => $NoImageUri, -title => 'No Image', -alt => 'No Image' } ) ); } print $q->p( $q->a( { -href => '#top', -name => 'bottom' }, 'Page Top' ) ); } else { print $q->p( $r->status_line ); } } printFooter(); exit; sub printHeader { my $jscript = qq{ function changeStatus(){ document.getElementById('status').innerHTML = 'Finished.' + ( ( document.getElementById( 'INDEX' ) ) ? '<br><a href=\"#INDEX\">Index<'+'/a>' : '' ); } }; print $q->header(), $q->start_html( -title => $cginame, -lang => 'ja-JP', -head => [ $q->meta( { -http_equiv=>'Content-style-type', -content=>"text/css" } ), $q->meta( { -http_equiv=>'Content-script-type', -content=>"text/javascript" } ), ], -style => { 'src'=>'/take.css' }, -script => $jscript, -onLoad => 'changeStatus()', ), $q->h1( $q->a( { -name => 'top' }, $cginame ) ), $q->ul( $q->li( $q->a( { -href => $cgipath }, 'CGI Top' ) ), ( $ASIN && !$MOD ) ? $q->li( [ $q->a( { -href => "$cgipath?ASIN=$ASIN&SHOT=$SHOT&PAGE=$PAGE&MOD=1&URI=" . uri_escape_utf8( $URI ) }, 'Modify' ), ] ) : '', ); } sub printFooter { print $q->end_html . "\n"; } sub printErrors { my( $errors ) = @_; # print $q->h2( 'Error' ); print $q->start_table( { -summary => 'Error Message', -border => 1 } ); foreach my $error ( @{$errors} ){ print $q->Tr( $q->th( $error->{'Code'} ), $q->td( $error->{'Message'} ) ); } print $q->end_table(); } sub searchSize { my( $ImageUriBase, $Shot ) = @_; foreach my $size ( @SizeList ){ my $ImageUri = $ImageUriBase; my $sizekey = $size->{'key'}; $ImageUri =~ s/%SIZE%/$sizekey/; my $title = $Shot . '_' . $size->{'name'}; #print $title . ': '; my $r = $ua->request( HTTP::Request->new( HEAD => $ImageUri ) ); if ( $r->header( 'content-type' ) eq 'image/jpeg' ){ #print 'Exist.' . $q->br(); print $q->p( $title, $q->a( { -name => $title, -href => '#INDEX' }, '*' ), $q->br(), $q->img( { -src => $ImageUri, -title => $title, -alt => $title, } ) ); push( @Anchors, $title ); last; } else { #print 'Not exist.' . $q->br(); } } } # EOF