こんにちは。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とは別の内容にする予定。
コメント