先月から,このAPIのバージョン4.0は3月9日までですよ,早く移行してくださいよというメールが,たびたびやって来ました.古いAPIと思われるものを,これまで,活用していました.
バージョン5.0 (v5)について,SDKほかを見たところ,Ruby版はありません.JavaとJavaScriptの実装を読んだものの,これをRubyに書き換えるのは面倒です.
そこでJavaScript (Node.js)で動かすこととし,自分用に大幅に書き換えました.ファイル名をpaapi5search.jsとしまして,コードはGistに置いています.
nodeコマンドで動かしますが,いくつか準備が必要です.ファイルのはじめのほうに書いたように,依存するパッケージが2つありまして,npm installでインストールしておきます.
次に,このAPIを使うには「Access Key」「Secret Key」「Partner Tag」が必要なのですが,jsファイルに直書きするのは何かと危険ですので,ruby-aaws*1と同じ,~/.amazonrcから読み出すことにしました.ただし移行ガイドにあるとおり「新しい認証情報を取得する」必要もあります.「Partner Tag」は,~/.amazonrcでは「associate=」のあとに指定する文字列となります.
昨日付の記事で取り上げた書籍のISBNを,入力に与えたときの,実行コマンドと結果は以下のとおりです.
$ node paapi5search.js 9784393376034 <ASIN> 439337603X <ISBN> 9784393376034 <DetailPageURL> https://www.amazon.co.jp/dp/439337603X?tag=(略) <SimpleURL> https://www.amazon.co.jp/dp/439337603X <Title> これからの大学 <Author> 松村圭一郎 <Manufacturer> 春秋社 <Publication Date> 2019-12-20T00:00:01Z <Buying Price> ¥2,090 松村圭一郎: これからの大学, 春秋社 (2019). [isbn:9784393376034]
最後は書誌情報です.端末でこの行をトリプルクリックしてコピーし,テキストエディタに貼り付けることを意図しています.
いくつかコマンドラインオプションをとります.-tオプションで検索語を指定できますが,このオプションがない場合,コマンドライン解析をして残った最初の引数が検索語となります.-mオプションには数値を指定し,項目数の上限を指定します(デフォルトは1),出力のオプションとして,-jをつけると,問い合わせ結果のJSON形式を出力し,-Sをつけると,上記の結果(要約)を出力しません.デバッグオプションは-dです.
JSONだけの出力は,次のようにします.
$ node paapi5search.js -t 9784393376034 -j -S { "SearchResult": { "TotalResultCount": 1, "SearchURL": (略), "Items": [ { "ASIN": "439337603X", "DetailPageURL": (略), "ItemInfo": { "ByLineInfo": { "Brand": { "DisplayValue": "春秋社", "Label": "Brand", "Locale": "ja_JP" }, "Contributors": [ { "Locale": "ja_JP", "Name": "松村 圭一郎", "Role": "著" } ], "Manufacturer": { "DisplayValue": "春秋社", "Label": "Manufacturer", "Locale": "ja_JP" } }, "Classifications": { "Binding": { "DisplayValue": "単行本", "Label": "Binding", "Locale": "ja_JP" }, "ProductGroup": { "DisplayValue": "Book", "Label": "ProductGroup", "Locale": "ja_JP" } }, "ContentInfo": { "Languages": { "DisplayValues": [ { "DisplayValue": "日本語", "Type": "発行済み" } ], "Label": "Language", "Locale": "ja_JP" }, "PagesCount": { "DisplayValue": 240, "Label": "NumberOfPages", "Locale": "en_US" }, "PublicationDate": { "DisplayValue": "2019-12-20T00:00:01Z", "Label": "PublicationDate", "Locale": "en_US" } }, "ExternalIds": { "EANs": { "DisplayValues": [ "9784393376034" ], "Label": "EAN", "Locale": "en_US" }, "ISBNs": { "DisplayValues": [ "439337603X" ], "Label": "ISBN", "Locale": "en_US" } }, "Title": { "DisplayValue": "これからの大学", "Label": "Title", "Locale": "ja_JP" } }, "Offers": { "Listings": [ { "Id": (略), "Price": { "Amount": 2090, "Currency": "JPY", "DisplayAmount": "¥2,090" }, "ViolatesMAP": false } ] } } ] } }
上記の結果は,プログラム内では変数siRespに代入されます(それを「JSON.stringify(siResp, null, 1)」により文字列にして,出力しています).
このときsiResp["SearchResult"]["Items"][0]["ItemInfo"]["Title"]["DisplayValue"]またはsiResp.SearchResult.Items[0].ItemInfo.Title.DisplayValueがタイトル(評価値は"これからの大学")となるのですが,このアクセスを簡潔に記述できるよう,oという名前の関数を自作しました.具体的にはo(siResp, "SearchResult.Items.0.ItemInfo.Title.DisplayValue")と書きます*2.どこかで「切れる」場合には(例えばo(siResp, "SearchResult.Items.0.Title.DisplayValue")については),undefinedを返します.また途中の「0」について(0に限らず数字列の場合には),まずsiResp["SearchResult"]["Items"]["0"]を調べ,この結果がundefinedになるときには,siResp["SearchResult"]["Items"][0]に切り替えて配列のアクセスを行います.
上記でリンクしたもの以外で,コーディングにおいて何度か参照したページです.
- 4.0から大きく変わった「PA-API v5.0(Amazon API)」の使い方! | HPcode
- JavascriptでオプションのパースをするOptparse-js
- paapi5-nodejs-sdk - npm
- optparse - npm
- Book & Product Searcher with Ruby/AWS - GitHub Gist
*1:https://rubygems.org/gems/ruby-aawsによると最新版が0.7.0で,10年以上も前とのこと.しかしRuby 2.8.0devで,問題なく検索できるのでした....
*2:実際にはsiResp["SearchResult"]["Items"][0]を変数itemに代入し,printItemSummary内のo(item, 'ItemInfo.Title.DisplayValue')で獲得しています.