ASINからAmazonの商品画像のURLを取得する

現在のAmazonの商品画像のURLは、必ずしもASINから導くことができません
(昔はできたため、できるものも結構あるようです)

そこで、ASINからAmazonの商品画像のURLを取得する方法を探しました。




ASIN→Amazonの商品画像のURLのリダイレクトCGI

一度URLを取得したら変更しない類のものであれば、ASINを使って商品のhtmlを参照し、画像のURLを記録してもいい?わけです。
しかし、変更がありうる(だからこそASINから導くことができない仕様になった)のですから、これでは済みません。


頻繁に参照することを前提に、Amazon Product Advertising APIを使うことになります。


参考になるのは以下のページ。


▽ASIN入りアマゾン商品画像URLリダイレクトCGIの雛形(たつをの ChangeLog
 http://chalow.net/2009-03-18-1.html


リダイレクトCGIという発想が素晴らしいですね。
URLを取得して表示したいだけなので、こういう形にしておくと汎用性があって便利。


ただしAmazon Product Advertising APIの仕様が変わり、署名をつけないといけなくなったので、「たつをの ChangeLog」さんのソースのままでは動きません。


そこでこれを元に署名部分の処理を付け加えた「左脳Script」さんのソースを参考にします。


Amazon API 認証について(左脳Script)
 http://n-yagi.0r2.net/script/2009/09/amzimg_making.html



Digest::SHA::PurePerlのインストールと設定

さくらインターネット
でこのソースを動かすには、Digest::SHAのインストールが必要です。
(インストールしていない状態で上記ソースを開いてもInternal Server Errorになります)


ただし私はシェルを使えないプランを契約しているので(telnet.cgiを使えばいいんですけど)、コンパイルは避けたいところ。
Digest::SHA::PurePerlを使えばいいことがわかったので、こちらに置き換えます。


Digest::SHA::PurePerlをホームディレクトリのpmディレクトリ以下に設置して、

use Digest::SHA qw(hmac_sha256_base64);

use lib qw( /home/****/pm );
use Digest::SHA::PurePerl qw(hmac_sha256_base64);

に置き換えればOK。


詳細は以下のページの4項目目で。


Amazon APIの新仕様に対応すべく、PAPAXYを「さくらインターネット」で動かしたメモ(にししふぁくとりー)
 http://www.nishishi.com/blog/2009/08/amazon_api_papa.html



で、以下のソースがうちの環境で動くようになったもの。
左脳ScriptさんのはURLを取得するように書き換えられていたので、その箇所はたつをの ChangeLogさんのソースに戻しました。

#!/usr/bin/perl
# http://chalow.net/2009-03-18-1.html
# http://n-yagi.0r2.net/script/2009/09/amzimg_making.html
# http://d.hatena.ne.jp/mitaina/20100119

use strict;
use warnings;
use CGI;
use LWP::Simple;

use strict;
use POSIX qw(strftime);
use URI::Escape;
use Encode qw/decode_utf8/;
use base 'URI::http';
#use Digest::SHA qw(hmac_sha256_base64);
use lib qw( /home/*****/pm );
use Digest::SHA::PurePerl qw(hmac_sha256_base64);

my $q = new CGI;
my $asin = $q->param('a');
my $size = $q->param('s') || "s";

my  $secret_key =   '*****';

sub getParam
{
    my  $uri    =   URI->new(@_);
    my  %eq =   map{    split /=/, $_   }   split /&/, $uri->query();
    my  %q  =   map{    $_ => decode_utf8(uri_unescape($eq{$_}))    }   keys    %eq;
    #   add timestamp parameter
   $q{Timestamp}   ||= strftime( "%Y-%m-%dT%TZ", gmtime() );    # 2009-01-01T12:00:00Z
#    $q{Timestamp}   ||= strftime( "%Y-%m-%dT%H:%M:%SZ", gmtime() );
# 2009-01-01T12:00:00Z for Windows
    $q{Version} ||= '2009-01-06';
    #   sort paramaters
    my  $sq =   join '&',map{   $_ . '=' . uri_escape_utf8($q{$_})  }   sort keys %q;
    #   make request
    my  $tosign =   join "\n", 'GET', $uri->host, $uri->path, $sq;
    #
    my  $signature  =   hmac_sha256_base64( $tosign, $secret_key );
    $signature  .=  '=' while length($signature) % 4;   # padding required
    #
    $q{Signature}   =   $signature;
    $uri->query_form(   \%q );
    #
    return  $uri->as_string();
}

my $aurl = "http://webservices.amazon.co.jp/onca/xml?".
    "Service=AWSECommerceService&".
    "AWSAccessKeyId=*****&".
    "Operation=ItemLookup&".
    "ItemId=$asin&".
    "ResponseGroup=Images";
$aurl   =   getParam($aurl);

my $res = get($aurl);
my  $url="";

if ($size eq "s") {
    ($url) = $res =~ /<SmallImage><URL>(.+?)</;
} elsif ($size eq "m") {
    ($url) = $res =~ /<MediumImage><URL>(.+?)</;
} elsif ($size eq "l") {
    ($url) = $res =~ /<LargeImage><URL>(.+?)</;
}
$url = "http://...1x1.jpg(1x1画像のURL)" unless $url;
print qq(Location: $url\n\n);


以上で動作したので、たつをの ChangeLogさんの記事を参考に画像をキャッシュするように書き換えました。ばっちり。


html上には以下のように画像ファイルを直接呼んでいる形で書けるのでいいですね。

http://****.sakura.ne.jp/img/B00005HV6H-m.jpg


<追記>2010/01/27 23:20

(n) お客様は、画像で構成される商品関連コンテンツを格納またはキャッシュしてはいけませんが、画像で構成される商品関連コンテンツへのリンクを、24時間まで格納することができます。お客様は、画像で構成されていないコンテンツを、データキャッシュの目的で、24時間まで格納することができますが、それをした場合は、その後直ちに Product Advertising API にリクエスト送信を行うか、または新しいデータフィードを取り込み、お客様のアプリケーション上の商品関連コンテンツを刷新することにより、商品関連コンテンツを直ちに刷新し、再表示しなければなりません。別途当方より通知されない限り、お客様は、個別の Amazon Standard Identification Number (以下、「ASIN」といいます)を、本ライセンス契約の終了まで、期間の制限なく格納することができます。前述に拘わらず、お客様のアプリケーションがクライアント アプリケーションを含む場合、かかるクライアントアプリケーションは、商品関連コンテンツを格納またはキャッシュしてはいけません。当方の要求があれば、お客様は、当方の要求から3営業日以内に、お客様が本ライセンス契約を遵守しているかを確認できるよう、かかるクライアントアプリケーションのコピーを当方に提供するものとします。

Amazon.co.jp Product Advertising API ライセンス契約 更新2010/1/5より


ですので、画像のキャッシュは禁止されていますので、ご注意を。
キャッシュをするなら、あくまでURLのだけに留めなくてはいけませんね。



<追記>2010/01/31 20:20

http://ec2.images-amazon.com/images/P/

な旧形式?の画像URLであれば、javascriptだけでできますね、という例。
blog等で使うには便利ですよね、この記法&js。


javascript - URIのasin:スキームを実装する(404 Blog Not Found)
 http://blog.livedoor.jp/dankogai/archives/50790015.html


<追記>2010/05/31 15:47
親戚の記事を書きました。


Twitterのユーザー名からTwitterのアイコン画像のURLを取得し、キャッシュする方法
 http://d.hatena.ne.jp/mitaina/20100531/1275288110


<追記>2010/07/04
ブックマークレットを使って画像を取得する方法が解説されてます。
トラックバックされて知りました。
1回こっきりblog等で使うというならこちらで十分ですね。