スポンサーリンク

Amazon APIで並列処理っぽい実装する方法

libraryWEBアプリ
スポンサーリンク

Amazon APIは並列呼び出しNG

404 NOT FOUND | Findelight
find delight!

の中では、Twitter APIにてツイートを呼び出し、ツイートの内容からキーフレーズを抽出し、キーフレーズをキーワードにしてAmazon APIにて商品検索というのをやっています。ツイートの内容からキーフレーズを抽出という部分に関しては、以下の記事にて並列処理を行って高速化する方法を紹介しました。

curl_multiでYAHOOキーフレーズ抽出APIを並列呼び出し
並列処理で高速化 つい書。の中で、複数のツイートからそれぞれキーフレーズを抽出するために、YAHOOキーフレーズ抽出APIを複数回呼び出しています。並列呼び出しにすることで処理時間が短縮され...

その記事の中で、Amazon APIの処理が結局一番時間がかかっているという事も書いていて、じゃあそこを高速化しようという話なんですが、それが単純には行かないのです。

というのも、AmazonのAPIはcurl_multiなどで並列同時呼び出しをするとエラーになるのです。アマゾン側から制限がかけられていて、1秒に1回しか呼び出してはいけないのです。

でも、これにしたがってやっているだけだと一つのキーワードでの検索になってしまうので、出てくる結果がどれも同じ単語に関連する本になってしまって面白くない。「次はどんな本が並ぶんだろう、ワクワク!」っていうのが大事なのである。

疑似並列処理的アプローチ

何か方法はないかという事で考えたのが以下の作戦。複数のキーワードのor検索にしています。 AmazonのProduct Advertising API (PAAPI)では、”|”で区切ってあげると複数のキーワードでのOR検索になります。

$access_key_id = '******';
$secret_access_key = '******';
$AssociateTag='******';//←これを追加


// RFC3986 形式で URL エンコードする関数
function urlencode_rfc3986($str)
{
    return str_replace('%7E', '~', rawurlencode($str));
}

// 基本的なリクエストを作成します
// - この部分は今まで通り
$baseurl = 'https://ecs.amazonaws.jp/onca/xml';
$num = count($_SESSION['Keywords']);
$params = array();
$params['Service']        = 'AWSECommerceService';
$params['AWSAccessKeyId'] = $access_key_id;
$params['Version']        = '2011-08-01';
$params['Operation']      = 'ItemSearch'; // ← ItemSearch オペレーションの例
$params['SearchIndex']    = 'Books';
$params['Condition']	= 'New';
$params['Keywords']       = '';
for($i=0;$i<8;$i++){//or検索のキーワードを作る
		$rans = rand(0,$num-1);
		$params['Keywords'] .= $_SESSION['Keywords'][$rans];
		if($i<7){
			$params['Keywords'] .=  "|";
		}
		$_SESSION['Keywords'][$rans]="";
}
$_SESSION['Keywordstmp']=$params['Keywords'];
rsort($_SESSION['Keywords']);
array_splice($_SESSION['Keywords'], $num-8);
$params['AssociateTag']=$AssociateTag;//自分のアソシエイトIDを追加
$params['ResponseGroup']='Offers,Medium';//取得したい情報の種類に合わせ追加

// Timestamp パラメータを追加します
// - 時間の表記は ISO8601 形式、タイムゾーンは UTC(GMT)
$params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');

// パラメータの順序を昇順に並び替えます
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, $secret_access_key, true));

// URL を作成します
// - リクエストの末尾に署名を追加
$url = $baseurl.'?'.$canonical_string.'&Signature='.urlencode_rfc3986($signature);

$amazon_xml=simplexml_load_string(@file_get_contents($url));//XMLをオブジェクトに代入
$json = json_encode($amazon_xml);

これによって、複数のキーワードから得られる本が並ぶようになったので、程よくカオス状態になって次にどんな本が出てくるのかが予測できないようになりました。いつまでもワクワク見ていられるようになって満足です。
ぜひ、興味を持った方は一度試してみてください、ホント見ているだけで面白いですよ。

404 NOT FOUND | Findelight
find delight!
WEBアプリ
スポンサーリンク
スポンサーリンク
良いなと思ったら、シェアしてください
このブログをフォローする
Findelight

コメント