amazon API (AWS) を試す PHP

このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリーをはてなブックマークに追加

更新をすっかり忘れていた@non_keysです…

今回はamazonのAPIを試してみようと思います。
以前書いたコードがAPI仕様変更に伴い全く使えなくなってたので書き換えです。
仕様変更は2009年だったので、どれだけ放置していたのか…

変更内容は、
RESTリクエストを送信する際、新たに「Timestamp」と「Signature」というパラメータが必要になりました。
仕様変更

では、早速。

■前提
AmazonWebServicesに登録し、アクセスキー情報を取得してください。

■環境
PHP 5.3.2
(PHP4以下だとhash_hmac関数が利用できないかも)

■解説
まず、必要なパラメータです。
ここを参考に、
配列のキー名も下記のとおりです。
今回は、本を検索します。
キーワードは実行する際にコマンドラインから入力値を受け取ります。

//アクセスキー、シークレットキー
$access_key_id = 'ACCESS_KEY';
$secret_access_key = 'SECRET_ACCESS_KEY';
 
// 必要なパラメータ
$baseurl = 'http://ecs.amazonaws.jp/onca/xml';
$params = array();
$params['Service']                 = 'AWSECommerceService';
$params['AWSAccessKeyId'] = $access_key_id;
$params['Version']                 = '2009-07-01';
$params['Operation']              = 'ItemSearch';
$params['SearchIndex']          = 'Books';
$params['Timestamp']            = gmdate('Y-m-d\TH:i:s\Z');
// 検索するキーワード 入力から取得
$params['Keywords']              = $argv[1];

次に、パラメータをパラメータ名(配列$paramsのキー)でソートし「&」で連結します。
その際、パラメータ名、値共に、RFC3986でURLエンコードします。(後述)

// パラメータをキーで並べ替え
ksort($params);
 
// パラメータを連結
$string = '';
foreach ($params as $k => $v) {
  $string .= '&'.rfc3986_urlencode($k).'='.rfc3986_urlencode($v);
}
//先頭の「&」を省く
$string = substr($string, 1);

次に、署名を作成します。
先に作成した文字列の先頭に以下の3行を追加します。
改行はそのまま使用してください
GET
webservices.amazon.com
/onca/xml
その文字列をシークレットキーを利用してHMAC-SHA256ハッシュアルゴリズムの計算を行います。
さらにエンコードも行います。
といっても、PHPの「hash_hmac」関数を利用するだけですが。

// 署名を作成
$parsed_url = parse_url($baseurl);
$str2sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$string}";
$signature = base64_encode(hash_hmac('sha256', $str2sign, $secret_access_key, true));

そして、ベースURLにURLエンコードした署名を追加するとリクエストURLが完成します。

// URL を作成
$url = $baseurl.'?'.$string.'&Signature='.rfc3986_urlencode($signature);

ここで、先に述べたRFC3986エンコードについてです。
本来RFC3986に準拠したURLエンコードでは「rawurlencode」関数を使用しますが、PHP 5.2.xまでは、「~」を「%7E」に変換するのでもとに戻します。
私の環境ではPHP5.3なので、必要ないですが、一応記述します。
また半角スペースを%20に変換します。

// RFC3986エンコード
function rfc3986_urlencode($str){
  return str_replace('%7E', '~', rawurlencode($str));
}

では実行しましょう。
今回ファイル名を「amazon.php」にしました。
コマンドに検索するキーワードを設定します。
■実行

php amazon.php "PHP ハンドブック"

■結果
実行すると、リクエストURLが表示されます。

http://ecs.amazonaws.jp/onca/xml?AWSAccessKeyId=00000000000 000000000&Keywords=HP%20%E3%83%8F%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF&Operation=ItemSearch&SearchIndex=Books&Service=AWSECommerceService&Timestamp=2011-02-11T13%3A15%3A19Z&Version=2009-07-01&Signature=pwqYQRc3RepIrf7m%2BVMRy%2FjFXx%2FZBSPsaSFFexIUoSI%3D

URLをブラウザで確認すると以下のようなxmlを取得できます。
一部抜粋します。

<Items><Request>
<IsValid>True</IsValid><ItemSearchRequest>
<Condition>New</Condition>
<DeliveryMethod>Ship</DeliveryMethod>
<Keywords>HP ハンドブック</Keywords>
<MerchantId>Amazon</MerchantId>
<ResponseGroup>Small</ResponseGroup>
<ReviewSort>-SubmissionDate</ReviewSort>
<SearchIndex>Books</SearchIndex>
</ItemSearchRequest>
</Request>
<TotalResults>7</TotalResults>
<TotalPages>1</TotalPages><Item>
<ASIN>4844302264</ASIN><DetailPageURL>
http://www.amazon.co.jp/HP95LX%E3%83%8F%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E8%97%A4%E6%A3%AE-%E6%B4%8B%E5%BF%97/dp/4844302264%3FSubscriptionId%3DAKIAJLNCIPV6KV4XVSJQ%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4844302264
</DetailPageURL><ItemLinks><ItemLink>
<Description>Add To Wishlist</Description><URL>
http://www.amazon.co.jp/gp/registry/wishlist/add-item.html%3Fasin.0%3D4844302264%26SubscriptionId%3DAKIAJLNCIPV6KV4XVSJQ%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4844302264
</URL>
</ItemLink><ItemLink>
<Description>Tell A Friend</Description><URL>
http://www.amazon.co.jp/gp/pdp/taf/4844302264%3FSubscriptionId%3DAKIAJLNCIPV6KV4XVSJQ%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4844302264
</URL>
</ItemLink><ItemLink>
<Description>All Customer Reviews</Description><URL>
http://www.amazon.co.jp/review/product/4844302264%3FSubscriptionId%3DAKIAJLNCIPV6KV4XVSJQ%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4844302264
</URL>
</ItemLink><ItemLink>
<Description>All Offers</Description><URL>
http://www.amazon.co.jp/gp/offer-listing/4844302264%3FSubscriptionId%3DAKIAJLNCIPV6KV4XVSJQ%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4844302264
</URL>
</ItemLink>
</ItemLinks><ItemAttributes>
<Author>藤森 洋志</Author>
<Author>小川 浩</Author>
<Manufacturer>ラジオ技術社</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>HP95LXハンドブック</Title>
</ItemAttributes>
</Item>

と、コードをごりごり書いたのですが、
リクエストURLを得るだけならここで確認できます。

以上、リクエストURLを得る方法です。

■ソースコード amazon.php

<?php 
$access_key_id = 'ACCESS_KEY'; 
$secret_access_key = 'SECRET_ACCESS_KEY'; 
 
// 必要なパラメータ 
$baseurl = 'http://ecs.amazonaws.jp/onca/xml'; 
$params = array(); 
$params['Service']           = 'AWSECommerceService'; 
$params['AWSAccessKeyId'] = $access_key_id; 
$params['Version']           = '2009-07-01'; 
$params['Operation']        = 'ItemSearch'; 
$params['SearchIndex']    = 'Books'; 
$params['Timestamp']      = gmdate('Y-m-d\TH:i:s\Z'); 
// 検索するキーワード 入力から取得 
$params['Keywords']       = $argv[1]; 
 
// パラメータをキーでソート
ksort($params);
$string = ''; 
foreach ($params as $k => $v) {
  $string .= '&'.rfc3986_urlencode($k).'='.rfc3986_urlencode($v);
}
$string = substr($string, 1);
 
// 署名を作成
$parsed_url = parse_url($baseurl);
$str2sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$string}";
$signature = base64_encode(hash_hmac('sha256', $str2sign, $secret_access_key, true));
 
// URL を作成
$url = $baseurl.'?'.$string.'&Signature='.rfc3986_urlencode($signature);
 
echo $url."\n";
 
// RFC3986エンコード
function rfc3986_urlencode($str)
{
  return str_replace('%7E', '~', rawurlencode($str));
}
?>

One Comment

  1. [...] 1.amazon API (AWS) を試す PHP (Knockin’on TechLog) 2.PHPで、「Bit.ly」のAPIを使ってURLを短縮する。(flatlabs) 3.プログラミングができなくても作れるTwitter botの作り方 [...]

Leave a Reply

Get Adobe Flash player