WEBスクレイピング-4
銘柄コードで株価データを取得するマクロー配列方式
ここでは前に説明したマクロ[Nikkei_StockDataScraping]を別の方法で作ったものを説明します。マクロ名は[Nikkei_StockDataScraping_2]です。
前のマクロでは株価情報をオブジェクト変数に代入しましたが、今度は配列変数に代入する方法です。取得する方法はどちらも似ていますが、まとめ方が違います。今回の方法は表示速度が速いメリットがありますが、表示する順番にデータを用意する必要があるので、設定が多少面倒です。
マクロ[[Nikkei_StockDataScraping_2]のスクリプトの一部を下記に示します。全スクリプトはソフトのスクリプトページをご覧ください。
下記は「銘柄名」と「日付」データを抽出する例です。先のオブジェクト配列で行った方法と似ています。オブジェクト配列の場合はstockInfo['meigara']=htmlMei のように配列の要素に直接代入しましたが、ここは仮の変数に代入します。個々のデータを仮変数に入れて置き、後でまとめて順番に配列変数に代入します。
他のデータの抽出方法は基本的にはオブジェクト変数の場合と同じなので省略します。とりあえず仮の変数に入れて置きます。仮変数では表示する順番に抽出する必要はありませんが、適切なデータのない項目やシート上で計算する項目はダミーデータとして空白を入れます。
すべての変数を抽出したらあらかじめ表示する順番に代入します。
125~137行目で配列変数stockDataにstockData.push('項目')で順番に代入しています。console.logの前の//を取るとデータの中身をデバッグ領域にプリントできます。console.logの部分にデータの内容を記していますが、配列の中ではこの形式でデータがセットされています。
下記のマクロは上のマクロ[Nikkei_StockDataScraping_2]を使うマクロ[Get_Nikkei_StockDataScraping_2]です。
シートクリアや値上り・値下り銘柄カウントマクロは共通です。
52行目で株価情報を取得し、59行目でこのデータを一括して銘柄コードの行に表示します。前のマクロの場合は、getRangeでセルを指定して個別にデータを表示していますが、ここでは銘柄名(C列)から利回り欄(O列)まで一括で表示します。このため表示が速くなります。ダミーで欠けたデータはプログラム計算で補足します。
マクロの違いによるデータ取得と表示速度の違い
①先に説明したマクロ[Nikkei_StockDataScraping]を使う場合は、約12~15分。セルごとにデータを記入するので速度は遅くなりますが、メリットはプロパティの指定で任意のセルに表示できる融通性がいい。
②後のマクロ[Nikkei_StockDataScraping_2]を使う場合は約8~9分、30~40%速い結果でした。連続したセル範囲に一括でデータを表示するので表示が速くなります。高速さはメリットですが、あらかじめ決まった順番に配列データを作る必要があり、変更に対する柔軟性が悪い。
実際の所、どちらのマクロも配列の使い方で逆の使い方もできますが、ここでは省略します。
GASの速度はExcelに比べるとあきれるほど遅いといつも感じます。理由はセルを指定するgetRange()を多用するためと言われます。ExcelでもApplication.Updating=Trueにすると遅くなりますが、それよりも遅い感じ。配列を使う場合は結構速いので、データ処理は極力配列化で処理すべきです。ただ最終的にはシートのセルに表示しないといけないので、getRange()の回数を減らす工夫が必要です。公開中の[日経225銘柄株価データ取得]では、もっと多くの項目を扱うため①のマクロの方法をベースにして、シートで計算できる部分はセルに計算式を埋め込んで自動的に計算することで少しでも表示速度をアップするようにしています。それでも遅い!
マクロの関数化はサーバーの負荷を考慮
どちらのマクロも取得した一連の株価情報を1つの変数(stockInfo/stockData)に代入して戻していますが、戻す情報を1つずつにすれば項目ごとに関数化できます。セルに関数を指定するとIMPORTXML関数のようにデータを自動的に表示が可能になります。ただし、その場合は項目ごとにサーバーにデータを取りに行くのでサーバー側の負荷が増える恐れがあります。銘柄数や取得項目数が少なければその方が便利ですが、多くの銘柄数や項目を取得する場合を考えるとこちら側の処理速度を遅くしてもサーバー側の負荷を増やさないようにすべきと思います。ロボットによる機械的な取得に比べれば当方の取得など取るに足らない負荷かもしれませんが・・・