Google Apps Script (GAS) でスクレイピング~マスタから気象庁データのあるエリアごとに新しくデータを書きこんでいく実験

Others

こんにちは。1カ月とまた間が空きましたが、たぶんこれでラストのはず。

 

気象庁データ取得を頑張るシリーズ

 

Google Apps Script (GAS) でスクレイピング~気象庁のページにある過去の気象データをスプレッドシートに書き込む実験~

Google Apps Script (GAS) でスクレイピング~気象庁のページにあるブロックのデータをスプレッドシートに書き込んでマスタを作る実験~

Google Apps Script (GAS) でスクレイピング~マスタから気象庁データのあるエリアごとに新しくスプレッドシートを作る実験

 

今回もスプレッドシートをExcel形式でDLできるようにしてみました。

 

変更点は

・「data_2」に2列追加。「tm」とAC列。AC列は「次のデータの日時」を作るための列だが、1行目にエリアの制御用数値を置いてみました。

本当はこことは別にシートなり行なり作るべきなんでしょうが、スプレッドシートもセル数制限などありますので、なるべくコンパクトにいきます。

※Z~AC列はスクリプト制御用なので。。。

 

なお、Y列は「******************」が並んでいますが、前回記事の通りにスクリプトが回っていれば、ご自身の作ったファイルのIDを記録できているはずですので、そちらを使ってください。

 

今回の機能追加はこちら。

・作ったシートに対して、気象庁の過去データからスクレイピングしてきたデータを書き込んでいく

すごく簡易的な制御をつけて、作ったスクリプトを繰り返し回すだけでエリア・年月をさかのぼって計算していくようにした

(一部でおそらくつまずく)

 

今回のコード

var folderID="1OTNVaC0Q43-i8mClSnf6ztopuglAzj1F";//対象のフォルダ(google drive)
function writeWeatherData(){
  var bookurl_masterbook = "https://docs.google.com/spreadsheets/d/********************/edit#gid=********************";
  var masterbook = SpreadsheetApp.openByUrl(bookurl_masterbook);
  var sheet_master = masterbook.getSheetByName("data_2");

	var opt = {"contentType":"text/html;","method":"get"};
	var data_html = "";
	var content_html ="";
	var postText = "";

  var tgRow = sheet_master.getRange(1,29).getValue();
  var masterData =sheet_master.getRange(tgRow,1,1,29).getValues();
  var masterLastrow = sheet_master.getLastRow();
  var blockid=masterData[0][3];
  var blockName=masterData[0][4];
  var precId=masterData[0][0];
  var precName=masterData[0][1];
var arr_day = new Array('日', '月', '火', '水', '木', '金', '土');
  //http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&block_no=47662&year=2018&month=4&day=&view=
  var url ="http://www.data.jma.go.jp/obd/stats/etrn/view/daily_"+masterData[0][2]+"1.php?prec_no="+masterData[0][0]+"&block_no="+masterData[0][3]+"&year="+masterData[0][25]+"&month="+masterData[0][26]+"&day=&view=";

    //html取得
    data_html = UrlFetchApp.fetch(url ,opt);
    content_html = data_html.getContentText();
    postText = getStringSlice(content_html, "</pre>
",'
<table class="data2_s" id="tablefix1"></table>
<pre>
');
	postText = postText.replace(/\<\/td\>/g , "xxyyxx" );
	postText = postText.replace(/\<\/th\>/g , "xxyyxx" );
  postText = postText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'');
	var Middle_Arr = postText.split( /xxyyxx\n/g );
  Middle_Arr.shift();
  Middle_Arr.shift();
  Middle_Arr.shift();
  Middle_Arr.shift();
  //Middle_Arr.shift();
  Middle_Arr.pop();
  var table_Arr=[[]];
  var dbType = masterData[0][2];
    for(var j =0;j<Middle_Arr.length;j++){
      table_Arr[j] = Middle_Arr[j].toString().split( /xxyyxx/g );
      if(dbType == "a"){
        table_Arr[j].splice(1, 0, '-','-');
        table_Arr[j].splice(9, 0, '-','-');
        table_Arr[j].splice(16, 1);
        table_Arr[j].push('-','-');
      }
      var darrs = masterData[0][25]+"/"+masterData[0][26]+"/"+table_Arr[j][0];
      table_Arr[j][0] = masterData[0][25]+"年"+masterData[0][26]+"月"+table_Arr[j][0]+"日";
      //曜日変換 http://www.relief.jp/docs/google-spreadsheet-gas-get-day.html
      Logger.log(darrs);
      var days = new Date(darrs);
      Logger.log(days);
      var day_num = days.getDay();

      table_Arr[j][21] = blockid;
      table_Arr[j][22] = blockName;
      table_Arr[j][23] = precId;
      table_Arr[j][24] = precName;
      table_Arr[j][25] = arr_day[day_num];

  var result = WritingData(masterData[0][24],table_Arr);
    Logger.log(result);
  sheet_master.getRange(tgRow,28).setValue(masterData[0][28]);
  if(tgRow < masterLastrow){
  sheet_master.getRange(1,29).setValue(tgRow+1);
  }else{
    tgRow = 2;
  }
}
}

function WritingData(id,Arr){
  var targetbook = SpreadsheetApp.openById(id);
  var target = targetbook.getSheetByName("data");
  var writerow = Arr.length;
  var writecolumnn = Arr[0].length;
  var lastrow = target.getLastRow();
  target.getRange(lastrow+1,1,writerow,writecolumnn).setValues(Arr);
  return "success";
}

/*以下、前回のコード*/

とりあえず、残している問題は以下の通り。

・HTML取得エラーが起きた場合の処理(無尽蔵に1カ月ごとにさかのぼっていくため、必ずどこかでエラーが出る)

これについては、いくらでもやりようがあると思います。

なお、「xxyyxx」とか、本職の人がやらないようなsplitの切り方については、今回については多分問題ないですが、使いまわす際はご注意を。

とりあえず、7カ月くらい続けてきたこちらの話も今回で一区切り。自分のスキルアップにはかなり役立ちました。

スクレイピングはサイトによっては禁止されていますが、自分のサイトのチェックなどには結構便利ですよね。

次は、たまに検索で来てもらっている記事について、もう少々掘り下げてみようかと思います。

GASとは別の内容にする予定。

コメント