ホーム

OFF-SOFT.net

OFF-SOFT.net

ウェブやソフトウェアに関するサポート&情報サイトです。サイト構築からソフトウェアの作成、利用まであなたの助けになるかも・・・・しれません。たぶん・・。

PHPでAmazon Web APIを使ってカテゴリツリー表示してみる

公開日| 2010年10月04日 | コメントはまだありません。
概要:

今回は、Amazon のWeb API(※Amazonでは、Product Advertising APIと言いますが、一般的にはWeb APIと言うことが多いので、ここでは、Web APIで通します。)を使って、先にやってみた楽天のカテゴリリストと同じようにカテゴリリストページを作ってみたいと思います。 また、以前に「PHPでAmazon Product Advertising APIを使う」については書いていますので、それを理解されていれば、それほど難しい話ではありません。

では、早速、AmazonのWEB APIで使うカテゴリID(※Amazonでは、ノードIDと言いますが、一般的にはカテゴリIDと言うことが多いので、ここでは、カテゴリIDで通します。)を出力する簡単なページを作ってみましょう。

参照ページ : http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/
ここで使用したサンプルソースコード:


まず、準備をしましょう。

必要なIDを取得しましょう。
AmazonのWEB APIを利用するには、以下のIDで必要です。
  • Access Key ID(アクセスキー)
  • Secret Access Key(秘密アクセスキー)
  • Affiliate Key(アフィリエイトキー) ※アフィリエイトをやる方のみ必要です。
各IDの取得方法については、「PHPでAmazon Product Advertising APIを使う」で詳しく説明していますので、そちらを参照してください。

必要なIDを使って、簡単なWEB APIを使ってみましょう。
取得できたら、一応、ちゃんと使えるか確認しておきましょう。
※詳しい説明は、「PHPでAmazon Product Advertising APIを使う」を参照してください。

Amazonの場合は、以下のURLでWEB APIでアクセスするURLを編集します。
http://associates-amazon.s3.amazonaws.com/signed-requests/helper/index.html
この画面の
  • Access Key ID(アクセスキー)
  • Secret Access Key(秘密アクセスキー)
  • Unsigned URL欄
をそれぞれ設定し、"Dispaly Signed URL"ボタンクリックで欄に出力されるURLがWEB API用のURLです。
これをコピーして、WEBブラウザから直接入力します。
以下のような検索結果が表示されることと思います。(※以下の画面イメージは、WEBブラウザがFirefoxでの検索結果イメージです。)

出力結果は、XML形式なので、Firefoxでは、上記のように表示されます。

ここで大事なのは、ItemSearchResponseタグが、ちゃんとリアクションのXMLに入っていることです。
もし失敗しているなら、以下のようにItemSearchErrorResponseタグが設定されて戻ってきます。
<?xml version="1.0"?>
<ItemSearchErrorResponse xmlns="http://ecs.amazonaws.com/doc/2009-03-31/">
<Error>
	<Code>RequestExpired</Code>
	<Message>Request has expired. Timestamp date is 2010-10-03T02:56:35.000Z.</Message>
</Error>
<RequestID>xxxxxxxxxxxxxxxxxxxxxxxxx</RequestID>
</ItemSearchErrorResponse>

このような場合、IDが間違っている可能性が大きいので、まずは、IDの確認を行い、問題を解決しましょう。
以降の作業を行っても、ここでエラー出力される場合は、正しく動作しません。

※Amazonは、タイムスタンプをURLに指定するようになっています。そのタイムスタンプで、古いWEB APIの要求や、異常な時間設定の場合は、その要求をエラーとして処理するようになっています。


PHPの動作環境を確認しましょう。

PHPが動作可能か確認します。
以下は、Windowsのコマンドプロンプトで確認した例です。
UNIXでも同様のコマンドを入力して確認できます。

1
2
3
4
C:\> php -v
PHP 5.1.2 (cli) (built: Jan 11 2006 16:40:00)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies

今回の記事では、バージョンがPHP5以上でなければなりません。

これで準備が整いました。 次に、PHPのサンプルコードを元に、試してみましょう。


PHPのサンプルソースを使って、試してみましょう。

以下は、簡単なカテゴリIDのツリーページを作成するためのPHPのサンプルソースです。

[amazon_sample.php]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
<?php
 
 
//!	RFC3986 形式で URL エンコードする関数
//!	
//!	@param $str 変換前URL文字列
//!	@return sring 変換後URL文字列
function urlencode_rfc3986($str)
{
    return str_replace('%7E', '~', rawurlencode($str));
}
 
//!	URL(文字列)を編集する関数
//!	
//!	@param $params WEB APIに渡すパラメータリスト
//!	@param $base_param WEB APIに渡す基本パラメータ
//!	@param $baseurl WEB APIの基本URL
//!	@param $id カテゴリID
//!
//!	@return sring 編集後URL文字列
function getURL(&$params,$baseurl,$id = -1)
{
	if(isset($id) && $id>=0){
		$params['BrowseNodeId']    =$id;   // category (pc/software)
	}
 
	// パラメータの順序を昇順に並び替えます
	ksort($params);
 
	// canonical string を作成します
	$canonical_string = '';
	foreach ($params as $k => $v) {
	    $canonical_string .= '&'.urlencode_rfc3986($k).'='.urlencode_rfc3986($v);
	}
	$canonical_string = substr($canonical_string, 1);
 
	// 署名を作成します
	// - 規定の文字列フォーマットを作成
	// - HMAC-SHA256 を計算
	// - BASE64 エンコード
	$parsed_url = parse_url($baseurl);
	$string_to_sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$canonical_string}";
 
	//	証明書をエンコードする
	$signature = base64_encode(hash_hmac('sha256', $string_to_sign, '**********************', true));	//	ここで秘密キーを設定して暗号化する
 
	// URL を作成します
	// - リクエストの末尾に署名を追加
	return  $baseurl.'?'.$canonical_string.'&Signature='.urlencode_rfc3986($signature);
 
}
//!	親カテゴリを探索・編集する関数
//!	
//!	@param $current WEB APIで取得した親カテゴリ情報
//!	@param $URI 階層ページへのリンク用基本アドレス
//!	@param $re_count 現在の階層番号 - 入出力情報
//!
//!	@return sring 親カテゴリ情報 HTML
function getParent(&$current,$URI,&$re_count)
{
	$cat_html = '';
	if(isset($current)){
		if(isset($current->Ancestors) && isset($current->Ancestors->BrowseNode)){
			$cat_html.= getParent($current->Ancestors->BrowseNode,$URI,$re_count);
		}
		$cat_html .= '<ul>';
		$cat_html .= '<li>階層 - '.($re_count+1).' : <a href="'.$URI.'?id='.$current->BrowseNodeId.'">'.$current->Name.' : '.$current->BrowseNodeId.'</a></li>';
	//	$cat_html .= '</ul>';
		$re_count++;
	}
	return $cat_html;
}
//!	初期画面を編集する関数
//!	
//!	@param $URI 各ページへのリンク用基本アドレス
//!
//!	@return sring 初期画面情報 HTML
function getTopCategory($URI)
{
	$cat_html = '';
 
	$cat_html .= "\n<h4>本・漫画・雑誌</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=465392">本</a> : 465392</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=52033011">洋書</a> : 52033011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=466280">漫画</a> : 466280</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=13384021">雑誌</a> : 13384021</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=255460011">古本</a> : 255460011</li>';
 
	$cat_html .= "</ul>\n<h4>DVD・ミュージック・ゲーム</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=561958">DVD</a> : 561958</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=403507011">ブルーレイ</a> : 403507011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=561956">ミュージック</a> : 561956</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=637394">TVゲーム</a> : 637394</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=689132">PCゲーム</a> : 689132</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=2123629051">楽器</a> : 2123629051</li>';
 
	$cat_html .= "</ul>\n<h4>家電&カメラ</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=16462091">カメラ・デジタルカメラ</a> : 16462091</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=3477381">テレビ・レコーダー</a> : 3477381</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=16462081">オーディオ</a> : 16462081</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=124048011">生活家電</a> : 124048011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=3895751">理美容家電</a> : 3895751</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=699913011">携帯電話</a> : 699913011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=3210981">すべての家電&カメラ</a> : 3210981</li>';
	$cat_html .= "</ul>\n<h4>パソコン・オフィス用品</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=3371341">パソコン・周辺機器</a> : 3371341</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=637392">PCソフト</a> : 637392</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=689132">PCゲーム</a> : 689132</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=86731051">文房具・オフィス用品</a> : 86731051</li>';
 
	$cat_html .= "</ul>\n<h4>ホーム&キッチン</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=13938481">キッチン&テーブルウェア</a> : 13938481</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=13938531">インテリア・収納・寝具</a> : 13938531</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=13938541">生活雑貨・ペット用品</a> : 13938541</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=124048011">生活家電</a> : 124048011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=3828871">すべてのホーム&キッチン</a> : 3828871</li>';
 
	$cat_html .= "</ul>\n<h4>食品&飲料</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=70903051">食品</a> : 70903051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=71314051">スイーツ・お菓子</a> : 71314051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=71442051">ドリンク</a> : 71442051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=71588051">お酒</a> : 71588051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=57239051">すべての食品&飲料</a> : 57239051</li>';
	$cat_html .= "</ul>\n<h4>ヘルス&ビューティー</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=52374051">コスメ</a> : 52374051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=170039011">フェイス&ボディケア</a> : 170039011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=169911011">ヘルスケア</a> : 169911011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=344024011">サプリメント</a> : 344024011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=14315501">フィットネス・トレーニング</a> : 14315501</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=160384011">すべてのヘルス&ビューティー</a> : 160384011</li>';
 
	$cat_html .= "</ul>\n<h4>ベビー・おもちゃ・ホビー</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=344845011">ベビー&マタニティ</a> : 344845011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=13299531">おもちゃ</a> : 13299531</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=13321861">ホビー</a> : 13321861</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=2123629051">楽器</a> : 2123629051</li>';
	$cat_html .= "</ul>\n<h4>ファッション・時計</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=352484011">服&ファッション小物</a> : 352484011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=2016926051">シューズ&バッグ</a> : 2016926051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=85895051">ジュエリー</a> : 85895051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=324025011">時計</a> : 324025011</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=2113178051">すべてのファッション&時計</a> : 2113178051</li>';
	$cat_html .= "</ul>\n<h4>スポーツ&アウトドア</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=15337751">自転車</a> : 15337751</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=14315411">アウトドア</a> : 14315411</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=14315501">フィットネス・トレーニング</a> : 14315501</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=14315441">ゴルフ</a> : 14315441</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=14304371">すべてのスポーツ&アウトドア</a> : 14304371</li>';
 
	$cat_html .= "</ul>\n<h4>DIY・工具・車用品</h4>\n<ul>";
	$cat_html .= '<li><a href="'.$URI.'?id=2016929051">DIY・工具</a> : 2016929051</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=13945231">ガーデン</a> : 13945231</li>';
	$cat_html .= '<li><a href="'.$URI.'?id=2017304051">カー・バイク用品</a> : 2017304051</li>';
 
	return $cat_html;
}
 
 
 
//	-----------------------------
//	main 
//	-----------------------------
//	パラメータをチェック
 
if(isset($_REQUEST['id'])){
	$id = trim($_REQUEST['id']);
	if($id==''){
		$id = -1;
	} else {
		$id =(int)$id;
	}
} else {
	$id = -1;
}
$URI = $_SERVER['REQUEST_URI'];
if(stripos($URI,'?')!==false){
	$URI = substr($URI,0,stripos($URI,'?'));
}
 
$cat_html = '';
 
if($id<0){
	$cat_html = getTopCategory($URI);
 
} else {
 
	$baseurl = 'http://ecs.amazonaws.jp/onca/xml';
 
	$params = array();
 
	$params['Service']        = 'AWSECommerceService';	//	サービス名
	$params['AWSAccessKeyId'] = '**********************';	//	あなたの WEB API ID を設定します。
	$params['AssociateTag']   = '**********************';    // ← アソシエイトID
	$params['ResponseGroup']  = 'BrowseNodeInfo,TopSellers';    // 取得する情報グループ名 ここでは、属性情報、価格情報、イメージ情報、ユーザコメント情報
	$params['Version']        = '2010-06-01';          //	バージョン情報
	$params['Operation']      = 'BrowseNodeLookup';    // ← ItemSearch オペレーションの例
 
	$params['BrowseNodeId']      = $id;    //カテゴリーID
 
	// Timestamp パラメータを追加します
	// - 時間の表記は ISO8601 形式、タイムゾーンは UTC(GMT)
	$params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
 
 
	// create URL strings.
	$url = getURL($params,$baseurl);	//	service = itemSearch 
 
	// request to amazon !!
	$response = file_get_contents($url);
 
	// response to strings.
	$parsed_xml = null;
	if(isset($response)){
		$parsed_xml = simplexml_load_string($response);
	}
 
	$cat_html = '';
	if(
	    $response==false || !isset($parsed_xml) || 
	   (!isset($parsed_xml->BrowseNodes) || !isset($parsed_xml->BrowseNodes->BrowseNode)) || 
	   (isset($parsed_xml->BrowseNodes->Request->Errors) && !empty($parsed_xml->BrowseNodes->Request->Errors))
	   ){
		//	error
		$cat_html .= "******Error(Amazon)*******  <br />\n";
		$cat_html .= " 指定されたID = $id は、存在しないカテゴリのようです。<br />\n<br />\n";
		$cat_html .= getTopCategory($URI);
	} else {
		if(isset($parsed_xml->BrowseNodes)){
			$current = $parsed_xml->BrowseNodes->BrowseNode;
			if(isset($current)){
				$cat_html .= '<br />';
				$cat_html .= '<a href="'.$URI.'?id=">TOPのカテゴリ一覧へ</a><br />';
				$cat_html .= '<br />';
				$cat_html .= '現在のカテゴリ情報:<br />';
				$cat_html .= '<a href="'.$URI.'?id='.$current->BrowseNodeId.'">'.$current->Name.'</a> : '.$current->BrowseNodeId.'<br />';
 
				$cat_html .= '<br />';
				$cat_html .= 'カテゴリツリー:<br />';
 
				//	親カテゴリ
				$re_count  = 0;
				$cat_html .= '<ul>';
				$cat_html .= '<li>階層 - 0 : <a href="'.$URI.'?id=">root</a> : 0</li>';
				$re_count++;
 
				if(isset($current->Ancestors) && isset($current->Ancestors->BrowseNode)){
					$cat_html.= getParent($current->Ancestors->BrowseNode,$URI,$re_count);
				}
				$cat_html .= '<ul>';
				$cat_html .= '<li>階層 - '.($re_count+1).' : <a href="'.$URI.'?id='.$current->BrowseNodeId.'">'.$current->Name.'</a> : '.$current->BrowseNodeId.'</li>';
				$re_count++;
 
				//	子カテゴリ
				if(isset($current->Children)){
					$cat_html .= '<ul>';
					foreach($current->Children->BrowseNode as $cate_child){
						$cat_html .= '<li><a href="'.$URI.'?id='.$cate_child->BrowseNodeId.'">'.$cate_child->Name.'</a> : '.$cate_child->BrowseNodeId.'</li>';
					}
					$cat_html .= '</ul>';
				}
				for($ni=0;$ni<$re_count;$ni++){
					$cat_html .= '</ul>';
				}
 
			}
		} else {
			$cat_html = '**** DEBUG ***<br />';
			$cat_html .= print_r($parsed_xml,true);
		}
	}
}
 
 
?>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf8"> 
  <title>Amazon カテゴリID</title> 
</head>
<body>
 
<form action="<?php echo $URI; ?>" name="searchCategoryID" method="post">
<b>ID検索 :</b><input type="text" name="id" value="<?php echo ($id<0? '':$id); ?>" /><input type="submit" value="検索" />
</form>
<br clear="left" />
<?php
	echo $cat_html;
?>
</body>
</html>

もし、そのまま利用する場合は、以下の3項目を設定すれば、カテゴリIDリストを確認することができると思います。

45行目:あなたのSecret Access Key(秘密アクセスキー)を設定します。
192行目:あなたのAccess Key ID(アクセスキー) を設定します。
193行目:あなたのAffiliate Key(アフィリエイトキー)を設定します。※アフィリエイト不要の場合は、削除しましょう。


設定したphpファイルをあなたのWEBサーバ上でアクセスできるところへアップロードします。
WEBブラウザから、アップロードしたphpへアクセスしてみてください。
例えば、WEBサーバのカレントの直下へアップロードした場合は、以下のようなURLでアクセスします。

http://www.example.com/amazon_sample.php


以下のような画面が表示されるはずです。



ソースコードの構成は、大きく以下の構成でならんでいます。
  1. php サブルーチン
  2. php メイン
  3. html
ちょっと、メインルーチンが、中央にあるので、わかりにくいかもしれません。
でも、やってることは、本当に簡単です。

メインで、画面から受け取ったパラメータを元にWEB APIのアドレス&パラメータでURLを編集し、 実際にアクセスし、返信情報(XML)を解析して、画面にカテゴリツリーを表示する。

こんな流れです。

唯一、注意すべき点は、Amazonでは、rootカテゴリIDがありません。そのため、デフォルトのページを自分こさえてあげる必要があります。 ここでのデフォルトページは、http://www.amazon.co.jp/gp/site-directory/ref=topnav_sadのカテゴリ一覧を改版したものです。
78行目のgetTopCategoryがそれに相当します。


簡単な説明でしたが、こんな感じでカテゴリIDを調べることができます。
Amazonのカテゴリは、異常なほど多いですし、複雑です。 AmazonのカテゴリIDで、絞りこむには、それなりに経験が必要かもしれませんね。 日本企業のようにきっちりとしたカテゴリのようには見えません。そのためか、同種の製品もセットされているカテゴリは、まちまちで、カテゴリIDで絞り込むには、ちょっと、リスクがあるような感じです。

たぶん、Amazonの場合は、複数のカテゴリIDのORをとるべきなんでしょうね。

でも、この複雑怪奇なカテゴリIDを見つけるには、このカテゴリページは、案外、役に立つかと思います。

上記のサンプルをそれなりに変更して作成したページを以下のアドレスに設けましたので、それも活用いただけたら嬉しく思います。
http://www.off-soft.net/categories/amazon/



コメント

コメントをどうぞ







  • はてなブックマークへ追加する
  • Facebookでシェアする
  • twitter でつぶやく
  • Google Plusでシェアする
  • Pocketでシェアする
ページトップへ