ECS4/RESTに切り換え

投稿日:

ココの「読みかけの本」とか「読んだ本」ってのは、入力にAmazon Webサービスを利用しています。BookmarkletでISBN番号を入れると書名/著者名/定価をAmazonから拾ってくれる、という非常に簡単なモノなのですが、やはりあると便利。とてもラクチンです(^_^)

ところが10月に入った頃から、Amazonが正常に応答を返してくれなくなっちゃいました。新しく本を買っても、うまくWEBサービスと通信出来ず、ラクチンに登録出来ません(^_^;) 他に同様の症状を報告されてる方も居られるので、どうも「こちら」の問題ではなく「あちら」の問題っぽく。

で、じーっと復旧を待ってたんですが、どうもこの症状は「ECS3をSOAPで使う場合限定」らしく、この手法でのアクセスは古くていまやマイナーらしい→なかなか対処されそうになかったんで、この機会にECS4をRESTで使うようにプログラムを変更してみました次第。

当方の使い方だと複雑な機能は必要なく、極めて小規模でメンテナンス性とかも特に気にしなくて良いので、実に荒っぽい方法で実装してます。

//AWSによる書籍情報取得
$url = $ecs4url;
$url .= '?dev-t=' . $devtag;
$url .= '&t=' . $amazon;
$url .= '&AsinSearch=' . $isbn;
$url .= '&type=lite&f=xml&locale=jp';

//リクエストを投げる
$result = file_get_contents($url);

//XMLを分解
$result = XML_unserialize($result);

//返り値をeucに変換
mb_convert_variables("euc-jp", "utf-8", $result);

ちょお安直(^_^;)

PHP4なので、XMLの分解にはPHP XML Library, version 1.2bを使わせてもらいました。file_get_contentsは古いPHP4には実装されてませんが、PEARPHP_Compatに入ってます。

リクエストパラメータについては貧乏だけど心は萌えさんのAmazon E-Commerce Service 4.0(和訳)Migration Guideを参考にさせていただきました。多謝!

で、

$ProductInfo = $result['ProductInfo'];
$i = $ProductInfo['Details'];

//情報が取得出来た場合
if(!$ProductInfo['ErrorMsg']) {

//書名
$title = $i['ProductName'];
$title = str_replace("~", "〜", $title); //チルダ置換

//出版社
$publisher = $i['Manufacturer'];

//価格
$price = (int) ereg_replace("¥| |,", "", $i['ListPrice']);

//取得に失敗してれば終了
if ($publisher == NULL || $price <= 0) exit("AWS failed.");

//著者名
$k = 0; //ローカルカウンタのリセット
$author = "";

$Authors = $i['Authors'];

if (count($Authors['Author']) <= 1) {

$author = $Authors['Author'];

} else {

for ($i=0; $i<count($Authors['Author']); $i++){

//著者が複数の場合区切り記号を挿入
if ($k > 0) $author .= "/";

$author .= $Authors['Author'][$i];
$k++;
}

}



} else{

//情報取得に失敗

echo "AWSでの情報取得に失敗しました<br>\n";

echo "<b>" . $ProductInfo['ErrorMsg'] . "</b><br>\n";

exit; //終了



}

とかやって著者名等を取得。

とりあえず、今のところはこんな感じのコードで、化けずにちゃんと取得出来てるみたいです(^_^)

著者名については、コレ

<Authors>
<Author>田村 尚也</Author>
<Author>金子 賢一</Author>
<Author>野上 武志</Author>
<Author>島田 フミカネ</Author>
<Author>西E田</Author>
<Author>じじ</Author>
<Author>宇佐見</Author>
<Author>重戦車工房</Author>
<Author>RAIDON</Author>
<Author>大藤 玲一郎</Author>
</Authors>

コレ

<Authors>
<Author>本田 透</Author>
</Authors>

が、それぞれ

Array ( [Author] => Array ( [0] => 田村 尚也 [1] => 金子 賢一 [2] => 野上 武志 [3] => 島田 フミカネ [4] => 西E田 [5] => じじ [6] => 宇佐見 [7] => 重戦車工房 [8] => RAIDON [9] => 大藤 玲一郎 ) )

Array ( [Author] => 本田 透 )

ってな感じになってしまい、各々結果の配列格納形式が違っちゃう(さらに配列が入れ子になる)みたいなので、このやり方だと要素数をカウントして「1つ以下」と「それ以外」で場合分けするしかなさそう。(テレパス・ラボさんの「配列を平滑化する関数(array_flatten)」とか使うと良いかもしれず。)

WEBサービスで返される「商品リンクのURL」とかも以前とは変わってるっぽいんですが、いまのところ後方互換を保ってくれてて旧URLも使えるようなので、今回は放置。