見出し画像

【GAS】楽天市場のデイリーランキングの特定カテゴリー順位を集計するスクリプト(ひな型)

こんにちは!ようやく仕事納めとなり、余暇の時間確保できるようになったpikiです。今回は「楽天市場のデイリーランキングデータを自動集計するスクリプト」にチャレンジしてみました。必需品ではないもののあったら便利だなと思い、以前から作成したかったのですが、日々の生活の中でなかなか時間を作ることができずにいました。少しずつ隙間時間で作成してみましたが、まだまだ機能は足りず・・・あくまで雛型のスクリプトです笑。これからもっと使い勝手の良いスクリプトにしていこうと思いますが、取り急ぎはこの雛型をご紹介できればと思います。

楽天市場ジャンル別人気ランキングとは

まずスクリプトのご紹介に入る前に、楽天市場のランキングについて記述していきたいと思います。
楽天市場では、各ジャンルごとに期間別人気商品ランキングを無料で公開しております。明確な基準は示されていませんが、おおよそ売上順となっているといわれています(数量やアクセス数も影響しているようです)。
これにより、お客様は「今何が売れているのか」というトレンドを容易に掴むことができるほか、ランキング上位であるということから「この商品、このお店は信用できるぞ」とショップへの信頼度も確認することができるというわけです。
一方で、出店業者にもありがたい仕組みで、下記の画像のようにランキングの上位に入った商品を楽天側のガイドラインのもと告知することが可能となっております。ランキングは「リアルタイム」「デイリー」「週間」「月間」の4種類。瞬間的な売上で高順位を獲得しやすいので、リアルタイム順位画像をLP(ランディングページ)に取り入れている業者さんが多い印象です。たとえ、リアルタイムの瞬間的な1位であっても、何も実績のない商品より告知されている商品の信頼度は高く感じられるはずですので、もしも同様のスペック商品であれば、ランキング上位品を選ぶ人のほうが多いと思われます。

画像1

例えばこちらの商品は「総合ランキング1位」ということで2億アイテムの中で1位という輝かしい実績を告知する権利を得て上記のようにLPに取りいれております。もちろん総合ランキングであれば、お店側も狙ってとった順位と思いますが、もしかしたら「ジャンル別」かつ「リアルタイム」であれば、人知れず一位となっていた・・・なんてことも意外とあるのではないでしょうか。

ということで必要になるのがランキング情報の自動収集ツール

楽天のガイドラインによると必要になるのは
①集計・更新日
 いつ時点のランキング情報であるか
 Ex)デイリーランキング:2020年12月30日(水)更新(集計日 12月29日)
②ランキングタイトル
 どのランキングであるか
 Ex)デイリーランキング
③対象ジャンル
 どのジャンルのランキングか
 Ex) ランキングトップ > ダイエット・健康 > サプリメント 
④順位
 上記ランキングでの順位
といった情報となります(絞り込み条件を入れる場合はそれも記載が必要)。あくまで楽天側が確認するのに必要な情報のように思います。ガイドラインにはありませんが、LPへ取り入れる場合は、上記のようにランクイン時の画像が必要になりそうです。

今回、私が作成したスクリプトは、上記の情報を得るための最低限のものとなっており、対象ジャンルのデイリーランキングを順位を毎日取得するものとなっております。一応、日付も取得できるので、もしも上位にランクインしていれば告知も可能ですが、画像がないので、今一つ根拠に乏しいものとなってしまうかもしれません。これは今後スクリーンショットを入れるなど改善予定です。

データ更新タイミングについて

リアルタイムは15分毎、デイリーランキングは毎日午前10時ごろ、週間ランキングは毎週水曜15時ごろ、月間ランキングは月初第一水曜日、となっているようです。GASのスクリプトであれば、この時間に合わせてトリガー設定しておけば最新の情報が常に得られることとなります。

デイリーランキング情報取得用スクリプト(雛型)の中身

下記スクリプトでは、指定ジャンルの楽天市場デイリーランキング情報を日々取得することができます。順位だけだなく、商品名や店舗名、商品ページURL、価格、販促情報(DEALの有無)も得られます。また、順位の範囲は1-80位までを対象としております。
そこそこな長さになっておりますが、使用する場合は上部のIDを好きなように変更すれば使用可能です。

function rakuten_rank_daily() {

/設定/    
 var category_id="6桁の数字";/*集計したいカテゴリーのID*/
 var sheet_id="シートID";/*保存先のスプレッドシート*/

/各種変数/
 var ydate = getYesterday(); /*ランキング日時取得*/
 var rank_detail=[];/*全データ格納先*/
 var rank2_3=[];/*2-3位データ格納先*/
 var rank4_80=[];/*4-80位データ格納先*/

/スプレッドシートを開く/
 var spreadsheet = SpreadsheetApp.openById(sheet_id);
 var sheet = spreadsheet.getActiveSheet();

/対象カテゴリーのデイリー集計ページ情報を取得(デイリー更新は朝10時頃)/
 var url = "https://ranking.rakuten.co.jp/daily/"+category_id+"/";
 var response =UrlFetchApp.fetch(url).getContentText();

/1位のデータをスクレイピング/  
 var regexp_0=/<div class=\"rnkRanking_top3box rnkRanking_topBgColor\">[\s\S]*?<!-- \/item bookmark area -->/ig;
 var rnkRanking_top1box=response.match(regexp_0);
 rank_detail=item_detail_get(rnkRanking_top1box,1,ydate); /*1位の商品の詳細情報を配列でまとめていく、日付は集計日を設定*/
/2-3位のデータをスクレイピング/
 var regexp_1=/<div class=\"rnkRanking_top3box \">[\s\S]*?<!-- \/item bookmark area -->/ig;
 var rnkRanking_top3box=response.match(regexp_1);
 rank2_3=item_detail_get(rnkRanking_top3box,2,ydate); 
 rank_detail.push(rank2_3[0],rank2_3[1]);
/4-80位のデータをスクレイピング/
 var regexp_2=/<div class=\"rnkRanking_after4box\">[\s\S]*?<!-- \/item bookmark area -->/ig;
 var rnkRanking_after4box=response.match(regexp_2);
 rank4_80=item_detail_get(rnkRanking_after4box,rnkRanking_after4box.length,ydate); 
 for(var i=0;i<rnkRanking_after4box.length;i++){
   rank_detail.push(rank4_80[i]);
 }

/スプレッドシートから過去保管データを取得し、新規データを追加する/  
const values = sheet.getDataRange().getValues();/*過去データ取得*/
 for(var i=0;i<rank_detail.length;i++){ 
   values.push(rank_detail[i]); /*作成した配列からデータを1行ずつスプレッドシートのデータに追加していく*/
 }
 sheet.getRange(1, 1, values.length, values[0].length).setValues(values);/*更新したデータをA1セルを基軸に貼り付け*/
 
}

/ランキング該当箇所のHTML、データ数、ランキング対象日をもとに詳細データを配列で作成/
function item_detail_get(ctext,length,date) {
 var item_array=[];
 for(var i=0;i<length;i++){
     /商品名とURLを取得/
       var regexp_after4_url_itemname=/<div class=\"rnkRanking_itemName\"><a href=\"([\s\S]*?)">([\s\S]*?)<\/a>/ig;
       var item_detail = regexp_after4_url_itemname.exec(ctext[i]); 
     /日付を配列の先頭に割り込み/
       item_detail.unshift(date);
     /商品コード取得/
       var regexp_after4_itemid=/\"https:\/\/item.rakuten.co.jp\/[\s\S]*?\/([\s\S]*?)\/\">/ig;
       item_detail.push(regexp_after4_itemid.exec(ctext[i])[1]);
     /順位情報を取得(1-3位は画像データのためtry~catch 条件分岐でうまく作成できず・・・)/
     var regexp_after4_rank=/<div class=\"rnkRanking_dispRank\">([\s\S]*?)<span class=\"rnkRanking_dispRankExt\">/ig;
     try{
       var rank =regexp_after4_rank.exec(ctext[i])[1];
       item_detail.push(rank);
     }
     catch(e){
       var regexp_top1_3_rank=/<div class=\"rnkRanking_rankIcon\"><img src=\"[\s\S]*?alt=\"([\s\S]*?)位"><\/div>/ig;
       var rank=regexp_top1_3_rank.exec(ctext[i])[1];
       item_detail.push(rank);
     }  
     /レビュー数(レビュー0件の場合、nullとなりエラーが発生、これもうまく条件分岐作成できず)/    
       var regexp_after4_review=/<div class=\"rnkRanking_starTgif\">[\s\S]*?\/\">([\s\S]*?)<\/a>/ig;
       try{   
         var review = regexp_after4_review.exec(ctext[i])[1];
           item_detail.push(review);
       }catch(e){
           item_detail.push("レビュー(0件)");
       }
     /ショップ名取得/    
     var regexp_after4_shopname=/<div class=\"rnkRanking_shop\">[\s\S]*?\/\">([\s\S]*?)<\/a>/ig;
       item_detail.push(regexp_after4_shopname.exec(ctext[i])[1]);
     /価格(税込み)取得/
     var regexp_after4_itemprice=/<div class=\"rnkRanking_price\">([\s\S]*?)円<\/div>/ig;
       item_detail.push(regexp_after4_itemprice.exec(ctext[i])[1]);
     /スーパーDEAL倍率取得、無い場合nullであるがうまく条件分岐できず/  
       var regexp_after4_deal=/<div class=\"rnkGenre_dealPoint\">([\s\S]*?)<\/div>/ig;
       try{
         var deal = regexp_after4_deal.exec(ctext[i])[1];
         item_detail.push(deal);
       }catch(e){
         item_detail.push("販促無し");
       }
     /配列のindex1番にパースした内容が入るので削除/
       item_detail.splice(1, 1); 
       
       item_array.push(item_detail);
     }
 return item_array;
}

function getYesterday() {

 var date = new Date(); //現在日時のDateオブジェクトを作る
 var today = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd');
 
 /現在の「日」を取得/
 var day = date.getDate();
 
 /前日日付/
 date.setDate(day-1);
 
 //日付の表示形式を整形/
 var yesterday = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd');
 return yesterday;
}

構造は3つに分かれており、メイン部分の「rakuten_rank_daily()」、情報取得関数の「item_detail_get(ctext,length,date)」、日付取得関数の「getYesterday()」です。
スクリプトを動かすと下記画像のようにシートにデータが保管されます。
※スプレッドシートには列のタイトルは入らないので下記のように事前にタイトルを入力して使用してください。

画像2

今後足していく機能について

・ピボット集計機能
・スクリーンショット機能
(自身で指定したアイテムがランクインした時のみor毎日取得)
・メール通知機能
(自身で指定したアイテムがランクインした時のみor毎日取得)

最後に

まだまだ自身で効率のいいコードは作成できておりませんが、やりたいことベースでどんどん作成を進めていこうと思います。また、記述のうまい方のコーディングにも触れて、少しずつ良いところをまねていけるようになりたいと思います。今回コードは、スプレッドシートに最低限の情報をまとめるだけのスクリプトとなっておりますが、引き続き、機能を足していき、その部分のコーディングについては、同様に紹介していければと思いますので、ぜひご機会あれば読んでいただけますと幸いです。

この記事が気に入ったらサポートをしてみませんか?