天気情報取得APIを試してみた。Google スプレッドシートへの連携まで


こんにちは、Mikenerianです。

実はQiitaとnoteどちらが良いのか勝負を勝手に開催しています。

この記事でわかること

  • 天気情報を取得するAPI「OpenWeather API」について
  • Google Apps Script (GAS) について
  • 簡単なサーバーレスアーキテクチャについて

天気の情報を自分でも取得してみたくない?

冷静に考えて、天気予報ってすごいことです。科学文明が成し遂げた偉大な成果です。

産業革命前、人々は様々な方法で天気を占い、豊作のために雨乞いしていました。

それが今では人工衛星を駆使し、ほぼ外れない精度で明日の天気を予測できるに至りました。

さらにデジタルデバイスの普及により、近年では無意識のうちに天気情報を取得できるレベルです。

スマホの通知、スマートスピーカー、テレビ。天気の情報はあらゆるデバイスで、一瞬で手に入ります。

そこでこのMikenerian、天気予報に関する情報を自分で取得できないかと考えるに至りました。

そのうちアプリ開発に応用したいと思っています。
どう考えても、それが主目的です。

OpenWeather APIを使ってみる

天気情報を取得するためのAPIはいくつかあるのですが、一番使いやすそうなOpenWeather APIを使いたいと思います。

OpenWeatherはイギリスが拠点ですが、全世界の天気データをAPI経由で提供している団体です。

使い方はとても簡単です。まずはトップページからSign inをクリックし、Create an accountからユーザ登録を行います。

無料でサクッと登録を済ませるとAPIキーが払い出されます。無料プランではAPIリクエスト数に色々と制限がありますが、個人で使う分には問題ない範囲かと思います。

APIについてゼロから知りたい方は、本から入るのがおすすめですが以下記事で軽く概要を説明しています。

試しに、東京の現在の天気を取得してみたいとしましょう。詳しくは公式ドキュメントに記載されていますが、以下のAPIコールで取得できます。

https://api.openweathermap.org/data/2.5/weather?q=Tokyo&appid={API key}

コールの「Tokyo」の部分を変更することで、任意の都市に変更できます。

少しハマったのですが、都市名が被っていると狙った地点の情報が取得できないので、その場合はcity IDを使ったほうが良さそうです。(例:日本の茨城県と茨木市など)

以下のようなjson形式で取得できます。※ちょっといじっているので、実際の値とは異なります

{
 "coord": {
   "lon": 135.5683,
   "lat": 34.8164
 },
 "weather": [
   {
     "id": 801,
     "main": "Clouds",
     "description": "few clouds",
     "icon": "02n"
   }
 ],
 "base": "stations",
 "main": {
   "temp": 278.57,
   "feels_like": 274.33,
   "temp_min": 274.26,
   "temp_max": 280.93,
   "pressure": 1028,
   "humidity": 65
 },
 "visibility": 10000,
 "wind": {
   "speed": 3.09,
   "deg": 20
 },
 "clouds": {
   "all": 20
 },
 "dt": 1612086928,
 "sys": {
   "type": 1,
   "id": 8032,
   "country": "JP",
   "sunrise": 1612043830,
   "sunset": 1612081498
 },
 "timezone": 32400,
 "id": 1862033,
 "name": "Tokyo",
 "cod": 200
}

取得情報をスプレッドシートに保存

APIを使って何かアプリを作るにしても、とりあえずどこかに保存する必要があります。

とりあえずGoogle スプレッドシートに保存しておけば気軽に利用できるだろうということで、ここからはGAS (Google Apps Script)を使ってAPIコール、スプレッドシートへの保存方法を紹介します。

GASはGoogle サービスとの連携に特化した、JavaScriptベースのサーバーレス実行環境です。個人的にはAWS Lambda、Google Cloud Functionsに近いサービスだと思っています。

基本無料であり、各種Google サービスと連携できることから、手軽な実行環境としては最適なサービスだと思っています。

まずはスプレッドシートを作成します。
今回は単純に、B列に日付、C列にAPIから取得した気圧データを格納するスプレッドシートを設定します。

続いてGASを作成します。作成は以下のリンクからできます。

またはスプレッドシートの「ツール>スクリプトエディタ」からアクセスすることもできます。

GASは実行ボタンでソースコードを試験的に実行することもできます。最初の実行時にスプレッドシートとの認証が走ります。

そのうち改善されると思いますが、Chromeでアクセスすると「このアプリは Google で確認されていません」という警告画面が表示されます。これは左下の「詳細を表示」から、「〇〇(安全ではないページ)に移動」をクリックすることで無事に認証できます。Googleのサービスなのに…

以下がソースコードです。取得したjsonデータのうち、気圧データを12時間おきに更新する設定としています。

// OpenWeatherMapから東京の天気を取得し、スプレッドシートの最終行に気圧情報を追記するコード
function getWeatherOfTokyo() {
 // APIによる気象情報の取得
 const response = UrlFetchApp.fetch('https://api.openweathermap.org/data/2.5/weather?q=Tokyo&appid={API key}')
 // JSONデータのパース
 const forecast = JSON.parse(response.getContentText())
 // 今日の日付の取得
 const date = new Date()
 // シート情報の取得
 const mySheet = SpreadsheetApp.getActiveSheet()
 // シートに記載のある最終行を取得
 const lastRow = mySheet.getLastRow()
 // シートのB列に日付を「xxxx/xx/xx」の形式で挿入
 mySheet.getRange(lastRow + 1, 2).setValue(Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd'))
 // シートのC列に気圧情報を挿入
 mySheet.getRange(lastRow + 1, 3).setValue(forecast.main.pressure)
}

続いて、定期実行のためのトリガーを設定します。左のタブから「トリガー」を選択します。

「トリガーの追加」からトリガーを追加します。
以下のように設定しました。本当は時間の間隔が24時間で良かったのですが、最大が12時間なのでこのように設定しました。

これで、後は何もしなくても気圧情報がひたすら保存されるスプレッドシートが完成しました。

今回のエッセンスを応用することで、自分の取得したい天気情報が気軽に試せるようになると思います。こんな理由で取得した、などの事例がありましたらぜひコメントお願いします。

Enjoy good weather forecast and have a nice day!