こんにちは!Ryoku(@ryoku_dev)です。
Keepa API連続記事、3回目の今回は具体的なAPIの中身を解説します。販売数などの商品情報を取得するRequest Productsを扱います。
3回目の記事にしてやっとソースコードが出てくる!
どんな情報が取得できる?
これが全部取れます
基本的にChrome拡張の「Data」タブの情報がデータ(JSON形式)として取れます。
出品情報とカート取得者履歴は別のリクエストRequest Seller Informationと組み合わせれば取れます。
各国の商品情報が取れます
MWSは契約している国・地域の情報しか取れませんが(MWSのために各国に大口アカウントを作るはめに・・・)、Keepaは1つの契約で以下の国の全ての商品にアクセスできます。
アメリカ、イギリス、ドイツ、フランス、日本、カナダ、イタリア、スペイン、インドの9ヶ国
MWS APIでは取れない情報たち
山ほどありますが、特にリサーチで役に立ちそうなのはこの辺りです。
- ランキングの降下回数 stats.salesRankDrops30など
- 平均価格 stats.avg30など
- 各種履歴データ(ランキング、カート価格、出品数など) csv[1]など
- ランキングの対象カテゴリ salesRankReference
- レビュー(レート、個数) csv[16], csv[17]
- EAN(JAN)、UPC eanList, upcList
- 商品説明(箇条書き、詳細) features, description
- Amazon本体の出品有無 availabilityAmazon, csv[0]
- バリエーション variationCSV
- この商品に関連するスポンサー プロダクト frequentlyBoughtTogether
個人的に嬉しいのは「7. 商品説明」。NGワードを登録しておいて、ASIN登録時に商品説明にNGワードがあるものを弾く、ということをずっとやりたかったのです。
逆に、欧米輸入の場合、意外とこのままでは使いづらいのが「2. 平均価格」です。月に数個だけ売れるロングテール商品は品切れの際にガンと値上がります。平均価格ではその期間の価格も計算に含めてしまうので、実際に売れた価格よりも高い価格が算出されてしまいがちです。
後は「5. レビュー」についても、ASINが一致している海外ページのレビューが多数占めているケースが多く、必ずしも日本での評価とリンクしていません。
ただしオプション料金になります
前回の記事でも散々愚痴りましたが、基本料金の1トークンで取れる情報には限りがあります。次の情報を取るにはオプションとしてさらなるトークンが必要です。
カート価格 | +2トークン |
レビュー(レート、個数) | +1トークン |
FBA手数料 | +1トークン |
出品情報 | 6トークン / 10件 |
出品情報はなかなか強烈です。出品情報は返ってきた件数が10件以下の場合は6トークンですが、20件以下では12トークン、30件以下では18トークンとオプション料金が勝手に増えていきます。一応リクエスト時に下限の件数を指定できるのですが、なぜかその指定が20件からになっています。ひどい!
その埋め合わせなのか出品情報を取得すると、カート価格とレビューは追加トークンなしで取れるようになります。
APIの実際の利用方法
では実際のプログラムの中でRequest Productsを呼び出すとしたらどんな具合なのか? まずはレスポンスのデータ構造を理解する方が分かりやすいと思うので先にそちらから。
Request Productsのレスポンス
Request Productsに限らず、Keepa APIは全てJSON形式でレスポンスを返します。
JSONの詳しい説明は他に譲りますが、その形式は、下の例のようにデータのキー(項目名)と値の組をコロンでつなぎ、それをカンマ区切りで並べたものです。それらをデータの固まりとして{…}で囲みます。データは入れ子にできます。
{
"asin": "B01D0XM98Y",
"domainId": 5,
"title": "Dyson Soft roller cleaner head ソフトローラークリーンヘッド [並行輸入品]"
"stats": {
"avg": [-1.0, 10823.0, 6490.0, -1.0, ...],
...
},
...
}
JSONは入れ子と言いましたが、Request ProductsのレスポンスのJSONも次のような入れ子構造をしています。
「products」は配列です。取得するASINに対応したProduct Objectが要素です。100個のASINの商品情報を取得する場合は、productsの中にProduct Objectが100個並びます。
Product Objectの中には前項で紹介した項目がずらっと並んでいます。ほとんどの項目はイメージ通り取得できると思いますが「csv」は要注意です。
独特な形式で履歴情報が詰まったcsv
csvには価格、ランキング、出品数などのKeepaのコアというべき履歴情報がぎっしり詰まっています。このcsvは下図のような二次元配列です。
行は価格、ランキングなどデータの項目軸です。例えば、csv[0]にはAmazon本体の価格が入っています。
列は時系列に並んだデータで、タイムスタンプと値の組が並びます(ただし、カート価格など一部の行は、タイムスタンプ、価格、送料と三値の組みが並ぶ)。例えば、一番古いランキング情報は次のように取得します。
const oldestRankValue = product.csv[3][1];
const oldestRankTime = product.csv[3][0];
よく使う行は
- 0 – AMAZON: アマゾン本体の価格履歴
- 1 – NEW: 新品の最安価格履歴 (送料は別なので注意!)
- 3 – SALES: ランキング変動
- 4 – LISTPRICE: 参考価格(定価?)の履歴
- 7 – NEW_FBM_SHIPPING: 出品者発送の最安価格履歴 (送料を加えた三値の組)
- 10 – NEW_FBA: FBA発送の最安価格履歴
- 11 – COUNT_NEW: 新品の出品数の履歴
- 16 – RATING: レビュー評価レートの履歴
- 17 – COUNT_REVEIWS: レビュー件数の履歴
- 18 – BUY_BOX_SHIPPING: カート価格の履歴 (送料を加えた三値の組)
csvの行の全項目については公式ドキュメントを参照してください。
なお、1-NEWを使うと最安が送料別だと送料が取れずやたら安くなってしまったりしまいます。なので、7-NEW_FBM_SHIPPING、10-NEW_FBA、18-BUY_BOX_SHIPPINGなどを使いたいところですが、これらを取得するには、前述の通りリクエスト時にオプションを指定し、トークンを支払う必要があります。オプションの指定がない場合、これらの値はnullになります。
ちなみにカート価格(18-BUY_BOX_SHIPPING)と取るのにはプラス2トークン、7-NEW_FBM_SHIPPINGや10-NEW_FBAを取るためにはプラス6-12トークン必要になります! なので、出品者出荷の送料激高マンのケースは諦めて、1-NEWを取得するのが現実解と思われます。
csvの中に出てくるタイムスタンプ、実は「Keepa time minutes」なる独自のものです。一般的に使われるUNIX時間に変換するには以下の計算をします。
csvと名のつく項目には、前出の「CSVをパースした二次元配列」の他に、「一次元配列」「(CSVの本来の意味での)カンマ区切りのテキスト」もあります。ややこしい。
- 二次元配列:csv
- 一次元配列:offerCSV
- カンマ区切りのテキスト: imagesCSV, variationCSV
imagesCSVから先頭画像のURLを取る場合、例えば以下のように取得します。
const imageId = imagesCSV ? imagesCSV.split(',')[0] : null;
const image = imageId ? `=IMAGE("https://images-na.ssl-images-amazon.com/images/I/${imageId}")` : 'NO IMAGE';
計算の手間が省けるよstats
stats(Statistic Object)には「30日間の平均価格」や「30日間でランキングが下がった回数」など、生データであるcsvを元にKeepaが計算してくれた値が入っています。もちろん便利ですが、平均の計算方法を変えたり、ランキングが下がったとするパラメーターを自分で決めたい場合などは、自分でcsvから計算する必要があります。
「商品が売れた価格」の「最頻値」が欲しい・・。自分で計算するしか・・・
なお、statsは配列で、各要素に「Amazon本体の○○」、「新品の○○」、…が入っています。そう、csvの行と同じ並びです。例えば「新品の30日間の平均価格」はavg30[1]となります。
高いけどすごいぞoffers
offersは出品一覧ページの情報そのものです。配列であるoffersは各出品情報offerを要素として含みます。そして、offer(Marketplace Offer Object)は「セラーID」「出品価格」「コンディション」などを持っています。
出品価格 offerCSVは一次元配列ですが、これは「タイムスタンプ」「価格」の組ではなく、「タイムスタンプ」「価格」「送料」の三組で並びます。なので最新の価格を取るには次のようにします。
const price = offerCSV[offerCSV.length -2]; //最後から2番目の値
const shipping = offerCSV[offerCSV.length -1]; //最後の値
特に注目すべきは、出品者の「セラーID」を取ることができる点です。MWSでは自分が出品登録中の商品からしかセラーIDを取れないのでこれは便利です。また、FBAかどうかだけでなく自己発送のマケプレプライムを含め「プライム」かどうかも分かります。これもMWSでは無理です。
ただし!前述の通りoffersを取得するには、最低6 or 12トークン必要になります。闇雲に取るわけには行きませんので、単に出品者数が欲しい場合は、MWSと併用するか、事前に販売数などでフィルタリングした結果に対してのみoffersを取る、という運用がおすすめです(次の記事で紹介しているサンプルツールはこの運用を前提に作りました)。
セラーIDが分かるとRequest Seller Informationというリクエストを用いて、セラー情報(Seller Object)が取得できます。この中には、セラー名やセラー評価、出品カテゴリ・ブランドの他に、isScammer(=詐欺師)なんていう項目もあったりします。誰がどうやって判定しているんだ?
ここまでならば1トークンで取れますが、追加9トークンでそのセラーのストアフロントが覗けてしまいます! ここまでの情報を使えば、セラーの定量評価ができ、自分に合致したセラーの出品リストを取るところまで自動化できてしまいそうです。ぜひやってみたい。
Request Productsのリクエスト
Keepa APIのリクエスト方法はとてもシンプルです。MWSと違って署名のためのハッシュ計算もタイムスタンプもいりません。APIキーだけあればOKです。
- Keepa APIのページ(“Private API access key:”の後)からAPIキーを取得
- エンドポイントを「https://api.keepa.com/product」とし、APIキーとカンマで繋いだASINを渡すだけ
- 1回のリクエストでASINは100まで渡せる
- GETでもPOSTでもOK
(公式ではGET推奨みたい。100個のASINをURLに付けるの何となく気が引けたので、個人的にPOSTにしています)
こちらがGoogle Apps Script(GAS)のサンプルコードです。payloadの中でこれまで説明してきたオプションを指定しています。
const key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
//本来はPropertyなどから読み出す
const asin = ["B0050GWV9C", "B00XB6666M", "B072MCSC1F", "B07SS8DLYJ", "B00MHXHL64", "B01D0XM98Y", "B00FA2RLX2", "B0132RXDII", "B005GEFE38", "B008LQZP6E"].join();
//本来はSpreadsheet上などから取得する
const endpoint = 'https://api.keepa.com/product';
const payload = {
key,
asin,
domain: '5', //1:com 2:co.uk 3:de 4:fr 5:co.jp 6:ca 8:it 9:es 10:in
stats: '90', //指定期間(日)の統計を取得する。期間で指定も可能:'2019-10-20,2019-12-24'
rating: '1', //1:レビューレート・個数を取得する(+1トークン) 0:取得しない
buybox: '1', //1:カート価格を取得する(+2トークン) 0:取得しない
offers: '20' //20-100:出品データを取得する(6トークン/10件)。 数字は最大取得する件数。offersを指定した場合、rating、buyboxが指定してあってもトークンを消費しない
};
//リクエスト実行
const response = UrlFetchApp.fetch(endpoint, { method: 'post', payload });
const content = response.getContentText();
//JSONデータのパース
const json = JSON.parse(content);
if (json.error) {
throw new Error(json.error.message); //エラーが発生した場合、レスポンスは"error"というキーを含む
}
const products = json.products;
//csvの行定義
const ind = { NEW: 1, SALES: 3, RATING: 16, COUNT_REVIEWS: 17, BUY_BOX_SHIPPING: 18 };
//取得情報の表示
for(const product of products) {
const { asin, title, stats, csv } = product;
const { avg30, salesRankDrops30, buyBoxPrice, buyBoxShipping } = stats;
console.log('ASIN', asin);
console.log('商品名', title);
console.log('平均価格(30日)', avg30);
console.log('販売個数(30日)', salesRankDrops30);
console.log('カート価格', buyBoxPrice + buyBoxShipping);
}
まとめ
シンプルなリクエストで豊富な商品情報が取れるKeepa APIのRequest Productsを紹介しました。
Request Productsを使うと、MWS APIでは取得できない以下のような情報も取得できます。
- 各種履歴データ(ランキング、カート価格、出品数など)
- レビュー(レート、個数)
- EAN(JAN)、UPC eanList, upcList
- 商品説明(箇条書き、詳細) features, description
- Amazon本体の出品有無 availabilityAmazon
また、Request Seller Informationと組み合わせると、セラーIDやセラー評価、ストアフロントの中身まで取得できます。
ただし、出品データやカート価格はオプションになっており、余計にトークンを消費するので使い所に注意が必要です。
次回は実際にRequest Productsを使ったシンプルなリサーチツールを紹介します!