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])
前掲のコードの最後の方をこんな感じにします。
そして、「.htaccess」に下記のように書きます。... $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);
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]
この記事に言及しているこのブログ内の記事