こんにちは、blueです。
前回はOpenWeatherMapのWeb APIで現在天気の取得を行いました。
前回の記事はこちら
今回は同じOpenWeatherMapにて5日間の天気予報を取得します。
HTTPリクエストからレスポンスまでの流れは前回と変わりませんが、取得後の処理は少し躓きポイントがあります。今回はそれらを主にまとめましたので参考にしていただければ幸いです。
なお今回の記事は以下の書籍を参考にしています。
pythonですが会話形式で非常にわかりやすく書かれている書籍です。webAPIやスクレイピングを一から理解できる内容になっています。
今回のAPI
今回利用するOpenWeatherMapのWeb APIは以下になります。
3時間ごとの5日間の天気を取得することができます。
APIのURLは以下になります。
全コード
今回のコードは以下になります。
レスポンス後のコードは変えていますが、HTTPリクエストはURLを今回のAPI Call用に変更しただけになります。
Public Sub 現在天気取得_緯度経度()
Call CurrentWeatherData
End Sub
Private Sub CurrentWeatherData()
Const key As String = "API key" 'OpenWeatherMapから取得したものを入れること
Const lat As String = "35.6809704" '東京駅の緯度 GoogleMapから取得
Const lon As String = "139.7678007" '東京駅の経度 GoogleMapから取得
Dim http As MSXML2.XMLHTTP60
Set http = New MSXML2.XMLHTTP60
With http
Call .Open("GET", "https://api.openweathermap.org/data/2.5/forecast?lat=" & lat & "&lon=" & lon & "&units=metric&lang=ja&APPID=" & key)
Call .send
Do
If .readyState = 4 Then
Exit Do
End If
DoEvents
Loop
'JSONを一行で出力
Debug.Print .responseText
ThisWorkbook.Worksheets(1).Range("A1").Value = .responseText
'JSONパース
Dim jsonObj As Object
Set jsonObj = JsonConverter.ParseJson(.responseText)
'JSON整形(今回は出力しない)
'Debug.Print JsonConverter.ConvertToJson(jsonObj, " ")
'JSON出力
Dim i As Long
For i = 1 To 9 'Jsonconverterの配列は1始まりのよう
Debug.Print "日時=" & CDate((CLng(jsonObj("list")(i)("dt")) + 32400) / 86400 + 25569)
Debug.Print "気温=" & jsonObj("list")(i)("main")("temp")
Debug.Print "天気=" & jsonObj("list")(i)("weather")(1)("description")
Debug.Print "降水確率=" & (jsonObj("list")(i)("pop")) * 100 & "%"
Next i
End With
End Sub
コードの説明
今回は以下の点について説明します。
- JSON整形
- JSONからのデータ取得
- UNIX時間
次から説明します。
JSON整形
JSON整形とはJSONコードに適切なインデントと改行を付けて、確認しやすくすることです。
このJSON整形は「VBA-JSON」を導入して、JsonConverter.ConvertToJson(jsonObj, ” “)で実施することが可能です。
ただしこれを出力させる場合以下の問題があります。
- イミディエイトウインドウに表示させる場合199行までしか表示できない(以降は上書きされていく)
- Excelのワークシートに表示させる場合は1セルにまとめて表示されてしまう
後者の場合以下のように表示されます。
すべて表示されていないように見えますが、実際はすべて出力されています。エクセルの行の最大幅の問題です。
この場合は1セルに表示されたテキストを全選択して再度別セルに貼り付けることで以下のように表示させることができます。
ただこれも面倒なので以下のサイトを利用します。
JSON形式の1行データを入力すると、、、
JSON整形されたデータが得られます。
これを全選択して、コピーペーストすればExcelで確認することも可能です。
なおイミディエイトウィンドウに出力されたものをコピーペーストしてもうまくいきません。
これはイミディエイトウィンドウ内で改行されていることによるものなので、入力する際は1行にするようにしてください。
JSONからのデータ取得
「VBA-JSON」を用いてJSONパースされたオブジェクトは以下の方法で取得します。
- オブジェクト内の値はDicrionaryオブジェクト(“key”)で取得する
- 配列はDictonaryオブジェクト(”key”)(Index)で取得する
- 階層が深い場合は上位階層のオブジェクトに追加して取得する
JSON-VBAはDictionaryを用いているので以下のようにkeyから値を取得できます。
Dictionaryオブジェクト.Item(“key”) または Dictionaryオブジェクト(“key”)
JSON-VBAのDictionaryオブジェクトはjsonObjとしたので各種keyからの値(図枠内)取得は以下のようになります。
このようにしてVBA-JSONでパースされたデータからも任意の値を取得することができます。
UNIX時間
今回OpenWeatheMapで取得している日時はUNIX時間になります。
UNIX時間は「1970/1/1」からの「秒数」を表しています。
一方ExcelはExcelのシリアル値は「1900/1/0」からの「日数」を表しています。
参考:Excelの日付(シリアル値)についてと、UNIX時間との変換 (JavaScript, VBA)
今回UNIX時間をシリアル値を日付型にしたかったので以下のような計算をしています。
- CLng(jsonObj(“list”)(i)(“dt”)・・・文字列型をLong型に変更
- CLng(jsonObj(“list”)(i)(“dt”)) + 32400) ・・・協定世界時(UTC)と日本標準時(JST)の時差9時間の秒数
- CDate((CLng(jsonObj(“list”)(i)(“dt”)) + 32400) / 86400・・・秒数を日に変換(1日86400秒)
- CDate((CLng(jsonObj(“list”)(i)(“dt”)) + 32400) / 86400 + 25569)・・・1900年から1970年までの日にちを加算し、Date型に変更
参考:7.1 UNIX Time (time_t) ⇒ 日付のシリアル値変換
やっていることは単純ですがUNIX時間を日付にするにはこのような処理が必要になります。
最終的には以下のように日時で表示することができます。
日時=2022/04/15 15:00:00
気温=11.62
天気=適度な雨
降水確率=84%
日時=2022/04/15 18:00:00
気温=11.36
天気=小雨
降水確率=80%
日時=2022/04/15 21:00:00
気温=10.81
天気=小雨
降水確率=87%
日時=2022/04/16
気温=10.42
天気=小雨
降水確率=50%
日時=2022/04/16 3:00:00
気温=9.75
天気=小雨
降水確率=54%
日時=2022/04/16 6:00:00
気温=9.93
天気=小雨
降水確率=26%
日時=2022/04/16 9:00:00
気温=9.46
天気=小雨
降水確率=46%
日時=2022/04/16 12:00:00
気温=9.81
天気=小雨
降水確率=57%
日時=2022/04/16 15:00:00
気温=11.65
天気=厚い雲
降水確率=41%
今回のまとめ
今回はOpenWeatherMapのAPIを使って5日間の天気を取得しました。
HTTPリクエストからレスポンスまでの流れは前回と変わりませんでしたが、取得後の処理については少し躓きポイントがありました。
なおpythonだと簡単に処理できるようなのでVBA特有のもののようです(汗)。
ただこれも勉強と思って参考にしていただければ幸いです。
pythonですが会話形式で非常にわかりやすく書かれている書籍です。webAPIやスクレイピングを一から理解できる内容になっています。
Selenium-VBAでのWebスクレイピングに関する記事はこちらをどうぞ
【ExcelVBA‐Selenium】【永久保存版】スクレイピングに必要なSeleniumのインストール方法教えます
【Selenium-VBA】Yahooメールへのログイン方法をわかりやすく説明する
ChromeでのWebスレイピングをできる限りわかりやすく説明する(Excel VBA)
【ExcelVBA‐Selenium】Chrome driverのバージョンエラーが出た時の対処法(2021/10/7更新)
【Selenium-VBA】Seleniumを用いたスクレイピングでテーブル情報を取得する1
【Selenium-VBA】スクレイピングをするのに必要なHTMLについて説明します1
【Selenim-VBA】起動済みのChromeを用いてSeleniumによるスクレイピングを行う
【Selenium-VBA】JavaScriptを使ってスクレイピングをしてみる1
【VBA】SeleniumBasicにおけるクラス、メソッド、プロパティ一覧(日本語版)
Web-APIを用いたデータ取得に関する記事はこちらをどうぞ
【VBA】Web APIを使ってデータを取得する(OpenWeatherMap)1
【VBA】Web APIを使って時間別天気予報を取得する(気象庁API)
【VBA】Web APIを使ってLINE通知を行う(LINE Notify)1
コメント