2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Apps ScriptでYahoo Finance(米国版)の財務データをスクレイピング

Last updated at Posted at 2019-05-19

やったこと

  • スプレッドシートに営業キャッシュフローマージンを調べたい米国企業のティッカーシンボルを記入
  • このティッカーシンボルをもとに、米国版yahoo financeから対応する銘柄の営業キャッシュフローと売上高をスクレイピング
  • それらの比率を計算し、スプレッドシートに書き出し

最近米国株に興味が出て「MarketHack流 世界一わかりやすい米国式投資の技法」という本を読みました。
本の中に、営業キャッシュフローマージンが15〜35%ある会社を狙えと書いてありました。
営業キャッシュフローマージンの算出は、米国版yahoo financeの「financials」ページにある、"Total Cash Flow From Operating Activities"(営業キャッシュフロー)と"Total Revenue"(売上高)の比をとれば良いとのことです。
GASの勉強がてら、これをスクレイピングしてスプレッドシートに書き出すようにしてみました。
※売上高(Total Revenue)のページ。日付もこのページのRevenueの行から抜き出す。
スクリーンショット 2019-05-20 0.11.28.png

※営業キャッシュフロー(Total Cash Flow From Operating Activities)のページ。
スクリーンショット 2019-05-20 0.11.52.png

※日本のyahooファイナンスはスクレイピング禁止とのことですが、米国版の方をざっと見た所、そのような記述が見当たりませんでした。間違っていたらすいません。

変数名とかクラス名がアレですが、↓メインの流れ。

function my_Function(){
  //スプレッドシートに記入されているティッカーを配列として取得
  var sheet = SpreadsheetApp.getActiveSheet();
  var ticker_array = sheet.getRange(2, 1, sheet.getLastRow()-1, 1).getValues();

  //銘柄ごとに、後述のStock_itemインスタンスを作成
  var output_array = [];
  for(var i = 0; i<ticker_array.length; i++){
    var Stock_item_1 = new Stock_item(ticker_array[i]);
    
    //get_item_arrayメソッドを実行。items配列の要素に合致するデータをサイトから取得。メンバーのdata_arrayにpushしていく。Revenueとしているが実態は決算の日付を取得。
    var items = ['Revenue','Total Revenue','Total Cash Flow From Operating Activities'];
    for(var j = 0; j<items.length; j++){
      Stock_item_1.get_item_array(items[j]);
      };
    
    //get_marginメソッドで営業キャッシュフローマージンを計算し、data_array配列にpush。
    Stock_item_1.get_margin();
    var output_array = output_array.concat(Stock_item_1.data_array);
  };
  

  //スプレッドシートに書き出し
  sheet.getRange(2, 3, output_array.length, output_array[0].length).setValues(output_array);
}

コンストラクタ↓。インスタンス作成時に、プロパティにティッカーシンボルを設定。

var Stock_item = function(ticker){
  this.ticker = ticker;
  this.data_array =[];//空の配列。get_item_arrayメソッドで取得データをpush
};

get_item_arrayメソッド↓。銘柄ごとに、日付、売り上げ、営業キャッシュフロー(これらをitemとしました)をスクレイピングで取得し、プロパティに配列として設定。メソッドとはこんな感じで良いのでしょうか。。。

Stock_item.prototype.get_item_array = function(item){
  this.item = item;
  
  //itemによって適当なURLを設定。★要エラー処理。
  var URL_base = 'https://finance.yahoo.com/quote/';
  if (this.item != "Total Cash Flow From Operating Activities"){
    this.URL = URL_base + this.ticker + '/financials?p=' + this.ticker;
  } else {
    this.URL = URL_base + this.ticker + '/cash-flow?p=' + this.ticker;
  }
  
  //HTMLを取得。目的の数字が<span>タグで囲まれていたので、これでHTML内検索。
  //タグを削除した配列にし、目的の値のみ抜き出し。
  var html = UrlFetchApp.fetch(this.URL).getContentText();
  html = html.match(/<span data-reactid=".*?<\/span>/gi);//ここからhtmlは配列
  html = html.map(function(value,index,array){
    return removeTag(value);
  });
  var begin_index = html.indexOf(this.item);
  var temp_array = html.slice(begin_index,begin_index+5);
  this.data_array.push(temp_array);
};

get_marginメソッド↓。営業キャッシュフローマージンを計算してthis.data_array配列に追加する。スクレイピングした値が文字列だったので、カンマを取り除き数値に変換しています。

Stock_item.prototype.get_margin = function(){
  var _ = Underscore.load();
  var temp_Trans = _.zip.apply(_, this.data_array);
  var i_TR = temp_Trans[0].indexOf('Total Revenue');
  var i_CF = temp_Trans[0].indexOf('Total Cash Flow From Operating Activities');
  
  var margin = ["C/F margin"];
  for (var i = 1; i<5; i++){
    var value_cf = parseInt(this.data_array[i_CF][i].replace(/,/g, ""),10);//カンマ取り除いて整数にする。
    var value_tr = parseInt(this.data_array[i_TR][i].replace(/,/g, ""),10);
    var value_margin = value_cf/value_tr;
    margin.push(value_margin);
  };
  
  this.data_array.push(margin);
};

タグ削除関数↓。get_item_arrayメソッド内で、とってきたHTMLの配列の各要素からタグを削除する。

function removeTag(str){
  return str.replace(/<\/?[^>]+>/gi, '');
}

実行前

スクリーンショット 2019-05-20 0.01.21.png

実行後

出力した表のどれがどの銘柄なのかわかるようにしたり、グラフによる可視化などを今後付け加えたいです。Visaの営業キャッシュフローマージンがかなり高い。
スクリーンショット 2019-05-20 0.02.36.png

参考にしたもの

参考になりました。
https://www.amazon.co.jp/dp/B07BNB1Z9L/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?