スポンサーリンク

【VBA】Web APIを使って時間別天気予報を取得する(OpenWeatherMap)

VBAスクレイピング

こんにちは、blueです。

前回はOpenWeatherMapのWeb APIで現在天気の取得を行いました。

前回の記事はこちら

今回は同じOpenWeatherMapにて5日間の天気予報を取得します。

HTTPリクエストからレスポンスまでの流れは前回と変わりませんが、取得後の処理は少し躓きポイントがあります。今回はそれらを主にまとめましたので参考にしていただければ幸いです。

なお今回の記事は以下の書籍を参考にしています。

pythonですが会話形式で非常にわかりやすく書かれている書籍です。webAPIやスクレイピングを一から理解できる内容になっています。

スポンサーリンク

今回のAPI

今回利用するOpenWeatherMapのWeb APIは以下になります。

3時間ごとの5日間の天気を取得することができます。

APIのURLは以下になります。

5 day weather forecast

全コード

今回のコードは以下になります。

レスポンス後のコードは変えていますが、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きれい ~JSON整形ツール~

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

コメント

タイトルとURLをコピーしました