Google Apps Scriptで日経平均株価スクレイピングやってみた。

##Google Apps Scriptとは
Google Apps Scriptとは、皆さんもよく使っているであろう、Google Spread Sheetで用意されている開発環境です。javascriptで書く事ができて、APIを叩いて、JSONで返ってきたデータをパースしてみたいなお馴染みの処理等もGASのみで完結し、またその取得してきたデータ等も、Google Spread Sheetで管理できたりしちゃう優れた開発環境です。今回、インターン先でちょっとしたツールを作って欲しいという注文があったためスクリプトを書いてみました。是非みなさんもお使い下さい。必要なのは、無料で使える、Google Spread Sheetと、やる気だけです。

##使い方
簡単に使い方を説明します。本当にどこで実行すればいいのかなどの簡単な説明なので、気になった方は、ググってみて下さい。

・まずは下記のようにGoogle spread sheetにアクセスします。
<img width="1435" alt="スクリーンショット 2018-11-05 20.49.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/308967/f1dc84da-85c6-83c4-4600-882ca3801583.png">

・適当にシートを作成しましょう。
　その後、上記からツールを選択→スクリプトエディタを選択しましょう。
<img width="1377" alt="スクリーンショット 2018-11-05 20.51.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/308967/d0a4284d-7fe7-192f-80b9-2cd6d080d47e.png">

・選択後、このような感じのエディタが出てくれば完了です。
　上記の「実行」を押すと実行されます。また、GASでは、console.log();ではなく、Logger.log();
　で関数実行後の、返り値等を確認できます。出力を確認する時は、上記の「表示」→「ログ」
　を選択すると確認できます。GAS側で用意されている関数が結構あるのですが、慣れてしま
　えば簡単なので、関数等の説明が載ったありがたい記事も後述で記載しておきます。
　<img width="1432" alt="スクリーンショット 2018-11-05 20.53.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/308967/6628c87f-4d07-0aa2-fd36-d9b2a7198d26.png">


##今回の要件
今回どういう処理の流れを書いていったか下記にまとめます。

 1.日経平均株価を毎日Spread Sheetに記述するのが面倒だから、自動で入力できるようにして欲しい。
 2.Spread Sheetでは、ストップ高の銘柄を不特定数、Spread sheetに記述する事が想定される。
 3.そのストップ高の銘柄の情報の横に日経平均株価を自動で入力にして欲しい。
 4.15時時点のものが欲しい。→GASでは、関数実行を日にち、時間指定するのでここに関してはGAS側で設定できる。
 5.カラムAで日にちが入力されているので、その日にち分、横に入力して欲しい。

##処理を書いてみる。
```js
 function RealtimesetNikkeivalue(i){
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheetData = sheet.getSheetByName('ストップ高');
  var url = 'https://kabutan.jp/stock/chart?code=4592';
  var response = UrlFetchApp.fetch(url);
  var html = response.getContentText('UTF-8');
  var nikkeiTag = '<td class="header_shisuu_atai1" rowspan="2" style="border-  
  left:1px" solid="border-left:1px solid #5b5b5b;">';
  if(index !==0){
    var tagHtml = html.substring(index+nikkeiTag.length);
    var index = tagHtml.indexOf('</td>');
    if(index !== 0){
      sheetData.getRange(i,25).setValue(tagHtml.substring(0,index));
    }
  }
}
```

GASでは、どのSpreadsheetのどのシートに入力するのかを明記させるために、Spreadsheetや、sheetというオブジェクトが用意されています。

sheet変数に格納されている、SpreadsheetApp.getActiveSpreadsheet();の記述は、Spreadsheetに自動入力をするために必須ですので、覚えておくと良さそうです。

スプレッドシートオブジェクトでアクティブなスプレッドシートを取得するくらいの認識で今のところ、僕は困ってませんw また次の、sheetDataでは、先ほど呼び出したアクティブなスプレッドシートのオブジェクトのメソッドgetSheetByNameメソッドでシート名を指定しています。

ここでどのシートにスクリプトを実行すべきか明記してあげるイメージですね。

また、その後UrlFetchAppオブジェクトのfetchメソッドに引数でスクレイピングしたいURLを渡して上げる事でスクレピングしてくれて、そのデータがresponse変数に格納されます。この関数もGAS側で用意されている関数です。非常に便利です。

後は、文字列処理です。javascriptでお馴染みの関数、indexOfやsubstringを使っています。他に良い書き方があったかも知れないですが、僕はこんな感じで書いてみました。

最後のgetRangeメソッドは、セルの範囲指定をすることができます。第一引数が範囲していする行番号、第二引数に列番号を指定してあげます。カラムAが1のような感じです。とりあえず25列(カラムW)の2行目にしています。


##処理2
次に要件5のところのスクリプトを別の関数で書いて行きます。カラムAに記載されてある日付と一致した時のみ、スクレイピングしてあげたデータを入力してあげるようにしてあげます。そんなに難しくないですが書いて見ました。

```js
 function dateVerfication(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheetData = sheet.getSheetByName('ストップ高');
  var lastRow = sheet.getLastRow();
  var today = new Date();
  var d1 = today.getDate();
  var m1 = today.getMonth();
   for(i=3;i<lastRow;i++){
    var date = sheetData.getRange(i,1).getValue();
    var d2 = date.getDate();
    var m2 = date.getMonth();
   if(d1==d2 && m1==m2){
     setNikkeiValue(i);
    }
   }
  }
```

２行目までは先ほどと一緒ですが、3行目では、シートの最後の行(入力がされている)の行番号を取得しています。これもGAS側で用意されている関数です。

また、次にDate型で今日の日付を取得しています。このDate型の、getDateとgetMonthメソッドはメソッド名の通り、月と日付をint型で取得してくれます。

なぜこのように月と日にちで分けたのかというと、カラムAで予め入力されている日付を取得して、new Dateで今日の日付と一致した場合だけ上記で定義した関数setNikkeiValueを実行して、上から順に入力させるような処理を書いたのですが、int型で一度返さないと、日付が一致してもtrueを返さなかったからです。

少しここで詰まりましたが、後はスムーズにかけました。

処理が成功すると、11月5日今日時点ではこのようになります。
<img width="1061" alt="スクリーンショット 2018-11-05 21.53.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/308967/8ba619f6-b54a-16b9-795f-0ccd693fd69b.png">

色々事情があり、日付のところまで見せられないのが残念ですが、このような形になります。


##参考記事
http://www.bmoo.net/archives/2012/03/313118.html
https://uxmilk.jp/25841
https://qiita.com/keitaigarashi/items/b627ab4e22db852f1b89
https://jjnurburg.com/date/
https://spreadsheet.blue/google-apps-script/gyou/getlastrow/471/

また、このサイトが非常にGoogle Apps Scriptに関する記事が充実していますので是非参考にして見てください。
https://tonari-it.com/

この記事に関するコメント、編集リクエストお待ちしています。