プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
Amazon Product Advertising API(TIPS):検索結果をいっぱい取得する
AmazonさんのAPIを利用して何か作ろうと思ったのです。
ほんで最終的にはこんなのを作ってみましたφ(--)

Bookだなー

せっかくなので作る過程で調べたことをまとめておきますね。

そんな経緯で書き始めたこのカテゴリ。
おまけです。

AmazonさんのAPIから返ってくるデータ件数ってのは
基本的に1リクエスト10件(2012/05/13現在)です。

※「『SearchIndex=Blended』の場合も説明しろ」とか
 「マルチオペレーションなら倍いける」とかは勘弁して下さい(つд`)

「(´・д・`)ェー、一か月分のデータ全部欲しー」とかわがまま言っても
聞いてはくれないのです。

じゃあどうするか(--?
地道にえっちらおっちら取得するしかなさ気ですね。

幸い応答のXMLから全ページ数を取得することも
取得するページ番号を指定してリクエストを投げることもできるので
こんな感じでやってみましたφ(--)

■Util.php
    class Util {
        static public function urlencode_rfc3986($str) {
            return str_replace('%7E', '~', rawurlencode($str));
        }
    }


■BookInfo.php
    class BookInfo{
        public $ISBN;
        public $ASIN;
        public $Title;
        public $Author;
        public $Publisher;
        public $PublicationDate;
        public $DetailPageURL;

        /**
         * コンストラクタ
         *
         */
        public function __construct() {
            $this->ISBN = "";
            $this->ASIN = "";
            $this->Title = "";
            $this->Author = "";
            $this->Publisher = "";
            $this->PublicationDate = "";
            $this->DetailPageURL = "";
        }
    }


■test.php
    define("AWS_BASE_URL", "http://ecs.amazonaws.jp/onca/xml");
    define("AWS_ACCESS_KEY", ご自分のアクセスキーをどーぞ);
    define("AWS_SECRET_ACCESS_KEY", ご自分のシークレットアクセスキーをどーぞ);
    define("AWS_OPTION_SERVICE", "AWSECommerceService");
    define("AWS_OPTION_VERSION", "2011-08-02");
    define("AWS_OPTION_ASSOCIATETAG", ご自分のアソシエイトIDをどーぞ);
//    define("AWS_OPTION_SEARCHINDEX", "All");
    define("AWS_OPTION_SEARCHINDEX", "Books");
    define("AWS_OPTION_BROWSENODE", "466282");
    define("AWS_OPTION_RESPONSEGROUP", "Medium");

    require_once(dirname(__FILE__) ."/Util.php");
    require_once(dirname(__FILE__) ."/BookInfo.php");

    $baseurl = AWS_BASE_URL;
    $params = array();
    $params['Service'] = AWS_OPTION_SERVICE;
    $params['AWSAccessKeyId'] = AWS_ACCESS_KEY;
    $params['Version'] = AWS_OPTION_VERSION;
    $params['AssociateTag'] = AWS_OPTION_ASSOCIATETAG;
    $params['SearchIndex'] = AWS_OPTION_SEARCHINDEX;
    $params['BrowseNode'] = AWS_OPTION_BROWSENODE;
    $params['ResponseGroup'] = AWS_OPTION_RESPONSEGROUP;
    $params['Operation'] = 'ItemSearch';
    $params['ItemPage'] = 1;
    $params['Sort'] = 'salesrank';
    $params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
    $params['Power'] = 'pubdate:during ' . $date("m") . '-' . $date("Y");  //詳細条件(当月)

    ksort($params);

    $caStr = '';
    foreach ($params as $k => $v) {
        $caStr .= '&'.Util::urlencode_rfc3986($k).'='.Util::urlencode_rfc3986($v);
    }
    $caStr = substr($caStr, 1);

    // 署名を作成します
    // - 規定の文字列フォーマットを作成
    // - HMAC-SHA256 を計算
    // - BASE64 エンコード
    $parsedUrl = parse_url($baseurl);
    $strToSign = "GET\n{$parsedUrl['host']}\n{$parsedUrl['path']}\n{$caStr}";
    $signature = base64_encode(hash_hmac('sha256', $strToSign, AWS_SECRET_ACCESS_KEY, true));

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

    //XMLで情報を取得。
    $xml = @simplexml_load_file($url);

    $dataList = array();
    //検索結果データ展開
    foreach ($xml->Items->Item as $item) {
        $data = new BookInfo();

        $data->ISBN = (string) $item->ItemAttributes->ISBN;
        $data->ASIN = (string) $item->ASIN;
        $data->Title = (string) $item->ItemAttributes->Title;
        $data->Author = (string) $item->ItemAttributes->Author;
        $data->Publisher = (string) $item->ItemAttributes->Publisher;
        $data->PublicationDate = (string) $item->ItemAttributes->PublicationDate;
        $data->DetailPageURL = (string) $item->DetailPageURL;

        $dataList[] = $data;
    }

    //2ページ目以降も取得

    $totalPages = $xml->Items->TotalResults;
    if($totalPages > 1){
        for(
$i = 2; $i <= $totalPages; $i++){
            
//APIの制限(連続実行)待ち
            sleep(1);


            $baseurl = AWS_BASE_URL;
            $params = array();
            $params['Service'] = AWS_OPTION_SERVICE;
            $params['AWSAccessKeyId'] = AWS_ACCESS_KEY;
            $params['Version'] = AWS_OPTION_VERSION;
            $params['AssociateTag'] = AWS_OPTION_ASSOCIATETAG;
            $params['SearchIndex'] = AWS_OPTION_SEARCHINDEX;
            $params['BrowseNode'] = AWS_OPTION_BROWSENODE;
            $params['ResponseGroup'] = AWS_OPTION_RESPONSEGROUP;
            $params['Operation'] = 'ItemSearch';
            $params['ItemPage'] = $i;
            $params['Sort'] = 'salesrank';
            $params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
            $params['Power'] = 'pubdate:during ' . $date("m") . '-' . $date("Y");  //詳細条件(当月)
            ksort($params);

            $caStr = '';
            foreach ($params as $k => $v) {
                $caStr .= '&'.Util::urlencode_rfc3986($k).'='.Util::urlencode_rfc3986($v);
            }
            $caStr = substr($caStr, 1);

            // 署名を作成します
            // - 規定の文字列フォーマットを作成
            // - HMAC-SHA256 を計算
            // - BASE64 エンコード
            $parsedUrl = parse_url($baseurl);
            $strToSign = "GET\n{$parsedUrl['host']}\n{$parsedUrl['path']}\n{$caStr}";
            $signature = base64_encode(hash_hmac('sha256', $strToSign, AWS_SECRET_ACCESS_KEY, true));

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

            //XMLで情報を取得。
            $xml = @simplexml_load_file($url);

            //検索結果データ展開
            foreach ($xml->Items->Item as $item) {
                $data = new BookInfo();

                $data->ISBN = (string) $item->ItemAttributes->ISBN;
                $data->ASIN = (string) $item->ASIN;
                $data->Title = (string) $item->ItemAttributes->Title;
                $data->Author = (string) $item->ItemAttributes->Author;
                $data->Publisher = (string) $item->ItemAttributes->Publisher;
                $data->PublicationDate = (string) $item->ItemAttributes->PublicationDate;
                $data->DetailPageURL = (string) $item->DetailPageURL;

                $dataList[] = $data;
            }
        }
    }

    var_dump($dataList);


実際にはリクエストURL作るところは関数化してたりもしますが、
分かりづらくなるのでサンプルでは同じ処理を2回直接書いてみました。
ちなみにこっそり追加されている

  $params['Power'] = 'pubdate:during ' . $date("m") . '-' . $date("Y");

は詳細条件指定で意味は「今月発売」です。

  sleep(1);

でAPI実行毎にsleepを1秒入れているのはAPIの制限によるものです。
1秒間に1リクエストしか受け付けてくれないんだそーな。
なもんで、リアルタイム検索でってのは無理があるかと。
定期実行で自分とこのDBに情報引っ張ってきておいて
リアルタイム検索は自分のところのDBから検索する
・・とかしか無いんじゃないですかね(--?


Amazon Product Advertising API(1):事前準備
Amazon Product Advertising API(2):利用法
Amazon Product Advertising API(3):リクエストのパラメータ
Amazon Product Advertising API(4):応答のXMLについて
Amazon Product Advertising API(5):検索のサンプル
Amazon Product Advertising API(TIPS):取得するカテゴリを絞る
Amazon Product Advertising API(TIPS):売上ランキングを取得する
Amazon Product Advertising API(TIPS):検索結果をいっぱい取得する
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:Amazon Product Advertising API  thema:パソコンな日々 - genre:コンピュータ  Posted by ササキマコト 

  関連記事