-----
・追記(2021-2-27)
アメダスのデータのURLと表示形式が変わったため、使えなくなりました。
・追記(2022-2-3)
新バージョンを作成しました → 「アメダスのデータをGASで取得する。(気象庁JSONファイルを使用)」
・追記(2022-2-10)
Web APIを作成しました → 「最新のアメダスのデータを JSON 形式で取得する Web API を作りました。」
・追記(2022-10-3)
Web サービスを作成しました → 「最寄りのアメダスの観測データを表示する Web サービスを作りました。」
-----
現状、ビニールハウス内のデータ(温度・湿度)についてはNature Remoから取得しているのですが(湿度の精度については課題ありですが)、ハウス外のデータについてはリアルタイムでの把握ができていませんでした。
野外となりますと、防水・防塵への対応なども必要となりますので、どう実現したものかと思案していたのですが、よく考えたらわざわざ自分で測定しなくてもちょっと離れた位置のデータならあるよなと。アメダスが。毎正時の観測値が各地点ごとに表形式で更新されています。(今回使いませんが地図形式もあります。)
個人的な好みとしても、ハードは最小限にとどめたいので一石二鳥です。使えるものは使っていきましょう。
ということで、以下、作り方のメモです。
(ちなみに、Webスクレイピングというのはウェブサイトから情報を抽出する技術です。公式で適切なAPIが提供されていれば不要ですが、そういうところばかりとは限りません。やはり、使えると便利です。サイトによっては規約等で禁止されていることもあるので注意が必要です。)
① スプレッドシートの準備
まずはスプレッドシートの準備をします。
これは小名浜の場合ですが、地点によって取得できる要素が異なるので適宜修正してください。
シート名は「data」にしておきます(コード作成時にこの名前で使います)。
https://docs.google.com/spreadsheets/d/ここの値をコピペ/edit#gid=0
GAS初回実行時は承認が必要となります。無料のGoogleアカウントの場合「このアプリは確認されていません」というページが表示されます。ここで「安全なページに戻る」をクリックすると実行できませんので、「詳細」→「プロジェクト名(安全ではないページ)に移動」から承認します。
このような感じになります。うまく動きましたでしょうか。
Nature RemoとGASを使って温度・湿度をリアルタイムで記録する。
② コードの作成
作成したスプレッドシートの「ツール」→「スクリプト エディタ」からスクリプトファイルを作成します。コードは以下の通りです。
var spreadsheet = SpreadsheetApp.openById("スプレッドシートID"); var dataSheet = spreadsheet.getSheetByName("data"); function getAmadasToday() { var dataLastRow = dataSheet.getLastRow(); var opt = {"contentType":"text/html;","method":"get"}; var dataAmd = ""; var contentAmd = ""; var postText = ""; var urlAmd = "アメダスURL"; var date_and_time = new Date(); var dataDate = Utilities.formatDate(date_and_time, "JST", "yyyy/MM/d H"); var time = Utilities.formatDate(date_and_time, "JST", "H"); if(time == 0) { time = 24; } var middleArr = []; var tableArr = []; dataAmd = UrlFetchApp.fetch(urlAmd ,opt); contentAmd = dataAmd.getContentText(); postText = getStringSlice(contentAmd, '<td class="time left">' + time + '</td>','</tr>'); postText = postText.replace(/<\/td>/g, '</td>,'); postText = postText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, ''); postText = postText.replace( /\r\n/g , "\n" ); postText = postText.replace( /^(\n+)|(\n+)$/g , ''); postText = postText.replace(/\/\/\//g, ''); postText = postText.replace(/ /g, ''); middleArr = postText.split( /\n/g ); tableArr[0] = middleArr[0].split(","); tableArr.splice(0,0); if(tableArr[0][0] != "" && dataDate != dataSheet.getRange(dataLastRow, 1).getValue()) { dataSheet.insertRows(dataLastRow + 1); dataSheet.getRange(dataLastRow + 1, 1).setValue(dataDate); dataSheet.getRange(dataLastRow + 1, 2, 1, 8).setValues(tableArr); } } function getStringSlice(content, startStr, endStr) { var indexStart = content.indexOf(startStr); if(indexStart == -1){ return ""; } else { indexStart += startStr.length return content.slice(indexStart, content.indexOf(endStr, indexStart)); } }
書き換えが必要なのは3か所です。
・1行目「スプレッドシートID」
スプレッドシートを開いた状態でURLの下記部分に表示されます。ちょっと長めです。
・11行目「アメダスURL」
https://www.jma.go.jp/jp/amedas_h/ より取得する地点を選んでください。
小名浜の場合ですと、 https://www.jma.go.jp/jp/amedas_h/today-36846.html になります(?より後ろにくっついている文字は必要ありません)。
・39行目「8」
取得する要素数によって変わります。要素数+1の値を入れてください。
タイムゾーンは、「Asia/Tokyo」に変更してください。(「プロジェクトの設定」→「「appsscript.json」マニフェスト ファイルをエディタで表示する」をチェックから「appsscript.json」内を編集。)
③ トリガーの設定
定期的にgetAmadasToday関数を実行するためにトリガー設定をします。
「トリガーを追加」より、
・「実行する関数を選択」→ getAmadasToday
・「実行するデプロイを選択」→ Head
・「イベントのソースを選択」→ 時間主導型
・「時間ベースのトリガーのタイプを選択」→ 分ベースのタイマー
・「時間の間隔を選択(分)」→ 30 分おき
・「エラー通知設定」→ 今すぐ通知を受け取る
アメダスの更新は1時間おきで、毎時間10分頃までには更新されるようですが、時間ベースのトリガーでは実行する厳密な時間は指定できないため、アメダスが未更新だった場合に備えて「30 分おき」にしておきます。実行時に最新の値が未取得だった場合のみスプレッドシートへの入力が行われます。
④ 取得開始
***
GASによるWebスクレイピングのスクリプトは一度作っていたのでけっこう楽に作れました。
1時間おきの気象データが(概ね)リアルタイムで取得できるといろいろ使えますね。まず温度・湿度の変化を確認するグラフは作っておきたいところ。
Nature Remoの湿度の精度がいまいちなのでこちらで補完できたらと考えています。
・関連投稿
気象データをGASのWebスクレイピングで自動取得する。