ASIN入りアマゾン商品画像URLリダイレクトCGIの雛形
2009-03-18-1
[Programming]
アマゾンの商品画像のURLについて。
昔はアマゾンの商品ページにある商品画像URLには下記のようにASINが入っていました。
例:
しかし、最近(って、もう何年もだけど)はASINが入らなくなりました。そのうえ、このURLをコピーして使っているとときどき無効になってしまったりします。
例:
そこで、このブログで使うためにASINを渡すと商品画像URLへリダイレクトするCGIつくりました。CGIの雛形(テンプレート)を載せておきます。
アクセスURLは「http://..amaimg.cgi?a=[ASIN]&s=[SIZE(s|m|l)]」です。ASINさえ分かれば「<img src="...">」にこのURLを入れ込むだけなので、ブログシステム(私の場合は chalow)からいちいちアマゾンAPIを呼ばなくて済むのです。
(※なお、ブログシステム本体とAPIを使うモジュールは分離するというのが私のポリシーです。むしろ別サーバで良い。)
しかし、今度はこのCGIが毎回呼ばれるたびに、内部でアマゾンAPIを呼ばなくてはならなくなります。それも無駄なので、実際の運用ではキャッシュして効率化しています。つまり画像をサーバにDLして、一定期間はそれを使うという形です。
(※わざわざ画像をDLしなくてもURLだけキャッシュすれば良いのですが、将来的にこれも考慮しているので…→[2005-05-26-1])
前掲のコードの最後の方をこんな感じにします。
これらにより、「http://..../img/4822245772-m.jpg」に初めてアクセスしたらCGIが呼ばれ(RewriteCond の「!-f」)、CGI内部で商品画像が img/4822245772-m.jpg としてセーブされるので(mirror 関数)、次からはCGIが呼ばれなくて済みます。
なお、あくまでキャッシュなので img/*.jpg は cron で一定期間ごとに削除します。
この RewriteCond を使ったキャッシュ手法は強力で、さくらの500円サーバなどの安価なサーバ上で同時に複数のネットサービスを公開している私にとってはなくてはならないものです。
これがなかったら負荷で簡単に死ぬサービスもいっぱいやってますし。
ref.
- [を] 私が管理しているサイトとサーバの状況(2008年8月現在)[2008-08-24-3]
- [を] 2007年にひとりで作ったネットサービス[2008-01-27-2]
- [を] 2008年にひとりで作ったネットサービス[2009-01-30-2]
昔はアマゾンの商品ページにある商品画像URLには下記のようにASINが入っていました。
例:
http://ec2.images-amazon.com/images/P/4822245772.01.MZZZZZZZ.jpg
しかし、最近(って、もう何年もだけど)はASINが入らなくなりました。そのうえ、このURLをコピーして使っているとときどき無効になってしまったりします。
例:
http://ec2.images-amazon.com/images/I/311qdsd1JaL._AA140_.jpg
そこで、このブログで使うためにASINを渡すと商品画像URLへリダイレクトするCGIつくりました。CGIの雛形(テンプレート)を載せておきます。
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use LWP::Simple;
my $q = new CGI;
my $asin = $q->param('a');
my $size = $q->param('s') || "s";
my $aurl = "http://webservices.amazon.co.jp/onca/xml?".
"Service=AWSECommerceService&".
"AWSAccessKeyId=[キー]&".
"Operation=ItemLookup&ItemId=$asin&ResponseGroup=Images";
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);
(※あくまで「雛形」なので、セキュリティとかエラー処理とかはご自分でどうぞ。)アクセスURLは「http://..amaimg.cgi?a=[ASIN]&s=[SIZE(s|m|l)]」です。ASINさえ分かれば「<img src="...">」にこのURLを入れ込むだけなので、ブログシステム(私の場合は chalow)からいちいちアマゾンAPIを呼ばなくて済むのです。
(※なお、ブログシステム本体とAPIを使うモジュールは分離するというのが私のポリシーです。むしろ別サーバで良い。)
しかし、今度はこのCGIが毎回呼ばれるたびに、内部でアマゾンAPIを呼ばなくてはならなくなります。それも無駄なので、実際の運用ではキャッシュして効率化しています。つまり画像をサーバにDLして、一定期間はそれを使うという形です。
(※わざわざ画像をDLしなくてもURLだけキャッシュすれば良いのですが、将来的にこれも考慮しているので…→[2005-05-26-1])
前掲のコードの最後の方をこんな感じにします。
...
$url = "http://...1x1.jpg(1x1画像のURL)" unless $url;
my $cache_dir = "/home/hoge/www/foobar/img";
if (-d $cache_dir) {
mirror($url, "$cache_dir/$asin-$size.jpg");
}
print qq(Location: $url\n\n);
そして、「.htaccess」に下記のように書きます。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^img/([A-Z0-9]+)-([sml])\.jpg$ /amaimg.cgi?a=$1&s=$2 [L]
これらにより、「http://..../img/4822245772-m.jpg」に初めてアクセスしたらCGIが呼ばれ(RewriteCond の「!-f」)、CGI内部で商品画像が img/4822245772-m.jpg としてセーブされるので(mirror 関数)、次からはCGIが呼ばれなくて済みます。
なお、あくまでキャッシュなので img/*.jpg は cron で一定期間ごとに削除します。
この RewriteCond を使ったキャッシュ手法は強力で、さくらの500円サーバなどの安価なサーバ上で同時に複数のネットサービスを公開している私にとってはなくてはならないものです。
これがなかったら負荷で簡単に死ぬサービスもいっぱいやってますし。
ref.
- [を] 私が管理しているサイトとサーバの状況(2008年8月現在)[2008-08-24-3]
- [を] 2007年にひとりで作ったネットサービス[2008-01-27-2]
- [を] 2008年にひとりで作ったネットサービス[2009-01-30-2]
この記事に言及しているこのブログ内の記事
