スキップしてメイン コンテンツに移動

Excel VBAでAmazon Product Advertising API を使う

Excelで蔵書リストを作りたい。

多いといっても数千冊の蔵書、改善されたといってもウェブ画面よりExcelが断然入力しやすいし、既存ウェブサービスはAmazonにない本を登録できないという残念仕様により不可。

昔作った Amazon Advertising API でISBNから本の情報を取得するVBAプログラム、署名が必要になったAPI仕様変更に対応できずお蔵入りしてたけどホコリを払って再挑戦した。はぁ~めんどかった。
みんな苦労してるようで、いろんな方のブログ等に助けられました。ありがとうございます。一式揃ってすぐ動く、というコード・説明は見当たらなかったので、ここにまとめてみます。


完成品

マクロを含むExcel(2010)ファイルをGithubで公開しています。ISBNを入力してマクロを実行するとタイトル等をAmazonから取得して書き出します。好きに使ってください。
https://github.com/anarchiStraw/excel/blob/master/BookList.xlsm
bas単体も置きました。2010でないバージョンでもインポートすれば動くと思います(未確認)。

ただし、使うためにはAmazon.comのアカウント、アフィリエイト・タグが必要です
  1. Amazon.com(米国)にアカウント作成。日本とは別管理なのでややこしい。https://affiliate-program.amazon.com/
  2. 続けて Affiliate account を作る。WebサイトのURLや用途、どう収益をあげるつもりか、とか聞かれるけど適当に答える。
  3. VBAエディタでmainモジュールを開き、アクセス・キー、シークレット・アクセス・キー、アフィリエイト・タグ を自分のものに書き換える。

お世話になったページ

みなさまありがとうございます。
  1. VBAからAmazon Product Advertising API - 来月から本気出す。
    必要な情報源がリストアップされています。おかげで以下のページにたどりつけました。
  2. 【Access】vbaでhmacが正しく計算できた!! - プラプラ式技術系 Access流!
    困りごと(SHA256での署名作成)どんぴしゃのソースコード。ほぼそのまま取り込み。
    hmacがクリアできれば、AccessVBAからamazonのapiが使えると思います。
    (あと、base64エンコード、URLエンコード等の情報はネットで入手できます。)
    が私には高いハードルでその後半日かかりました、、、。
  3. スーの道具箱/VBでハッシュを求める
    SHAのハッシュ値を計算するモジュール。ほんとありがたい。そのままコピーさせていただきました。
  4. How do I base64 encode a string efficiently using excel vba - StackOverflow
    Base64エンコードのソースコード。Stringを受け取って関数内でバイト配列を作っていますが、2の関数からは16進数が返るので、16進数からバイト配列を作って渡すように変えました。
  5. 日本語URLをExcelで手軽にURLエンコードする方法 - Colo-ri.jp
    URLエンコードのソースコード
  6. VBA XMLデータをDOMで扱う方法 - smilejapan.net
    DOMのとっかかり。
  7. Signed Requests Helper - Amazon.com
    リクエストしたいURLから、署名対象文字列、署名、署名付きURLを生成してくれる。検算用に。

ソースコード、ちょっと説明

main、SHA、testの3モジュールあって、使うのは main.setBookInfo です。
、、、説明どころが思い当たらない、、、質問がもしきたら答えよう。
いちおう、AmazonへのリクエストURL生成箇所だけ載せておきましょう。
期待した結果が得られないときはイミディエイト・ウィンドウに出力されるURLをブラウザで見てみるといいです。
' asinに対するデータ取得URL
' optional引数はテスト用。
' 実際使うときは yourAccessKey, yourSecretKey, yourAssociateTag を正しい値に書き換えてください。
Function signedUrlFor(asin As String, _
        Optional accessKey As Variant, Optional secretKey As Variant, _
        Optional associateTag As Variant, Optional timestamp As Variant) As String
    
    Dim endpoint As String
    endpoint = "ecs.amazonaws.jp"
    
    Dim path As String
    path = "/onca/xml"
    
    Dim params As String
    params = "AWSAccessKeyId=" & IIf(IsMissing(accessKey), "yourAccessKey", accessKey) _
        & "&AssociateTag=" & IIf(IsMissing(associateTag), "yourAssociateTag", associateTag) _
        & "&ItemId=" & asin _
        & "&Operation=ItemLookup" _
        & "&ResponseGroup=ItemAttributes" _
        & "&Service=AWSECommerceService" _
        & "&Timestamp=" & urlEncode(IIf(IsMissing(timestamp), Format(Now, "yyyy-mm-ddThh:MM:ss+0900"), timestamp)) _
        & "&Version=2011-08-01"
    
    Dim stringToSign As String
    stringToSign = "GET" & vbLf & endpoint & vbLf & path & vbLf & params
    
    signedUrlFor = "http://" & endpoint & path & "?" & params _
                & "&Signature=" & getSignature(stringToSign, IIf(IsMissing(secretKey), "yourSecretKey", secretKey))
    Debug.Print signedUrlFor

End Function

コメント

  1. けっこうな数の本の情報をまとめて欲しいと知り合いに頼まれて
    途方に暮れていたので、ほんとに助かりました!!
    ありがとうございました。

    返信削除

コメントを投稿

このブログの人気の投稿

GAS 同一カラムを複数条件でfilterできない件

Google Apps Script でSpreadsheetをデータベース代わりにwebアプリをポチポチ作ってて、スクリプトからSpreadsheetにフィルタかける場合、同一カラムに複数条件を設定できないことを知って残念……。 フィルタのかけ方はこんな感じ。 日付を範囲指定したいけど、After、Before片方しかつけられない。 var dataFile = SpreadsheetApp.openById(DATA_FILE_ID); var sh = dataFile.getSheetByName(LOG_SHEET_NAME); var criteriaDateAfter = SpreadsheetApp.newFilterCriteria().whenDateAfter(new Date(targetDate)).build(); var criteriaUserEqual = SpreadsheetApp.newFilterCriteria().whenTextEqualTo(user.id).build(); if (sh.getFilter()) { sh.getFilter().remove(); } var r = sh.getRange(1, 1, sh.getLastRow(), sh.getLastColumn()) .createFilter() .setColumnFilterCriteria(DATE_COL, criteriaDateAfter) .setColumnFilterCriteria(USER_ID_COL, criteriaUserEqual) .getRange(); FilterCriteriaに2回条件設定してみたり var criteriaDateRange = SpreadsheetApp.newFilterCriteria() .whenDateAfter(new Date(date1)) .whenDateBefore(new Date(date2)).build(); 同じカラムに2回条件設定してみたり var r = sh.getRange(1, 1, sh.get...

ジップロックで堆肥づくり

2012/11/02『家庭でできる堆肥づくり百科』を見てビニール袋と生ゴミで堆肥づくりに初挑戦。 ・生ごみ 250ml (細かく刻む) ・庭の土 120ml ・水 大さじ2 ・アルファルファ粉末 大さじ1 (ウサギのペレットを砕いた) 袋はジップロック大を使用。 毎日揉む(切り返し)、1日おきに空気を入れ替える。4~8週間でできるらしい。 保温のことは書いてなかったけど発砲スチロール箱に入れてみた。うまく行くといいなあ。 2012/11/07 道路掃除の方に落ち葉をもらったので一掴みいれてみる。生ゴミは窒素やや多めらしく、炭素系の落ち葉を足したらいいかなと。 2012/11/12 10日経ってニオイが落ちついてきたかも。腐ってる臭いではないけどツンとする臭いがずっとしてた。発泡スチロール箱を蓋すれば気にならない(ジップロックには全く遮断されないので、袋だけで室内に置くのは避けたい)。材料がネギとミカンなせいかなあ。見た目は一向に変わらず。

その4 Excel VBAでAmazon Product Advertising API

引っ越すためついに本気で書籍リストを作っていると、どれほど少しでも省力化したくなり、しつこくバージョンアップ。 ISBNのない外国の本も検索したい ISBNのない本が思ったより多かった。フランス語のアクサンとか入力したくない。ISBNでの検索はamazon.com, amazon.frなど検索先を切り替えているように、タイトル等での検索も各国サイトを利用したい。 最初は「jpで見つからなければcom、見つからなければfr、、、」と思ったけど、だいぶ待たされちゃうし、その本のデータをどこで探したいかは決まってるので、それぞれ別のプロシージャを定義して実行できるようにした。 Public Sub searchBookInfoFromAmazonFr(dummy As Integer) searchBookInfo (amazonFr) End Sub さて、クイックアクセスツールバーに登録するのだけど、用意されてるアイコンじゃわかりづらい。各国の旗がいいんじゃないか。と思ってからが長かった・・・が、まとめれば: 旗アイコンは ここ で入手。 Ribbon Editor でリボンに自前のタブ・ボタンを登録 対象のExcelファイルを開く 右のDocument Explorerペインで「CustomUI Parts」を追加 表示される編集ペインのImageタブを開き、好きな画像を追加(From File System) Codeタブに下記Xmlを書いて保存、終了 Excelを開くとカスタム・ボタンが登録されているので、ふつうにクイックアクセスツールバーにも登録 <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"> <ribbon startFromScratch="false"> <tabs> <tab id="customMacro" label="custom macro"> <group id="custo...