KTR推しBLOG

Nim言語を使ってWebスクレイピングを行う方法を試す その1

2023-11-12

Nim言語の使い方を調べていく中で試した内容についてメモ書きを残しておきます。

シンプルにプログラミング言語でやりたいことで簡単に試すことができるものとして、Webスクレイピングを試していきたいと思います。
※ 実際にスクレイピングを行う際には接続先のサイトに負荷が掛かないことを念頭に置いて実施するようにしてください。

天気の情報を定期的に取得して何かに使いたいなぁと思ったのでやり方を調べていきたいと思います。参考先に記載しているサイトを内容を参考に以下のソースコードで気象庁の情報を取得してみます。

実行方法は以下の通りです。

nim r -d:ssl --hints:off .\sample01.nim
import std/[httpClient, strutils]
import json

# 気象庁のデータを取得する(東京のデータ)
let site = "https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json"
var client = newHttpClient()
let response = client.getContent(site)
let jsonData = response.parseJson
echo echo jsonData

上記のソースコードを実行するとJSONの辞書の情報を含んだ配列で取得することができます。そのままだと見にくい表示だったので整形すると以下のような内容となりました。

[
  {
    "publishingOffice": "気象庁",
    "reportDatetime": "2023-11-12T18:00:00+09:00",
    "timeSeries": [
      {
        "timeDefines": [
          "2023-11-12T17:00:00+09:00",
          "2023-11-13T00:00:00+09:00",
          "2023-11-14T00:00:00+09:00"
        ],
        "areas": [
          {
            "area": {
              "name": "東京地方",
              "code": "130010"
            },
            "weatherCodes": [
              "200",
              "211",
              "111"
            ],
            "weathers": [
              "くもり 所により 夜のはじめ頃 雨",
              "くもり 夕方 から 晴れ 所により 明け方 から 昼過ぎ 雨",
              "晴れ 後 くもり"
            ],
            "winds": [
              "北の風",
              "北の風 23区西部 では 北の風 やや強く",
              "北西の風 後 南の風"
            ],
            "waves": [
              "0.5メートル",
              "1メートル",
              "0.5メートル"
            ]
          },
          {
            "area": {
              "name": "伊豆諸島北部",
              "code": "130020"
            },
            "weatherCodes": [
              "214",
              "202",
              "201"
            ],
            "weathers": [
              "くもり 夜遅く 雨",
              "くもり 朝 から 昼前 雨 所により 朝 から 夕方 雷 を伴う",
              "くもり 時々 晴れ"
            ],
            "winds": [
              "北東の風 後 西の風 やや強く",
              "北の風 やや強く 後 北東の風 やや強く 新島 では 西の風 強く",
              "北の風 後 西の風"
            ],
            "waves": [
              "2.5メートル",
              "2.5メートル 後 2メートル ただし 新島 では 2.5メートル",
              "2メートル 後 1.5メートル ただし 新島 では 2.5メートル 後 1.5メートル"
            ]
          },
          {
            "area": {
              "name": "伊豆諸島南部",
              "code": "130030"
            },
            "weatherCodes": [
              "214",
              "202",
              "201"
            ],
            "weathers": [
              "くもり 夜遅く 雨 所により 雷 を伴う",
              "くもり 昼前 から 昼過ぎ 雨 所により 夕方 まで 雷 を伴う",
              "くもり 時々 晴れ"
            ],
            "winds": [
              "西の風 後 やや強く",
              "西の風 強く 後 北西の風 強く",
              "北西の風 やや強く 後 西の風"
            ],
            "waves": [
              "2.5メートル",
              "2.5メートル 後 4メートル ただし 三宅島 では 2.5メートル 後 3メートル",
              "3メートル 後 2メートル"
            ]
          },
          {
            "area": {
              "name": "小笠原諸島",
              "code": "130040"
            },
            "weatherCodes": [
              "200",
              "200",
              "101"
            ],
            "weathers": [
              "くもり",
              "くもり 所により 夕方 まで 雨",
              "晴れ 時々 くもり"
            ],
            "winds": [
              "南西の風",
              "南西の風 後 北西の風 やや強く",
              "北西の風 やや強く 後 北東の風"
            ],
            "waves": [
              "2メートル うねり を伴う",
              "2.5メートル 後 3メートル うねり を伴う",
              "3メートル  後 2.5メートル うねり を伴う"
            ]
          }
        ]
      },
      {
        "timeDefines": [
          "2023-11-12T18:00:00+09:00",
          "2023-11-13T00:00:00+09:00",
          "2023-11-13T06:00:00+09:00",
          "2023-11-13T12:00:00+09:00",
          "2023-11-13T18:00:00+09:00"
        ],
        "areas": [
          {
            "area": {
              "name": "東京地方",
              "code": "130010"
            },
            "pops": [
              "20",
              "20",
              "20",
              "20",
              "10"
            ]
          },
          {
            "area": {
              "name": "伊豆諸島北部",
              "code": "130020"
            },
            "pops": [
              "50",
              "20",
              "50",
              "20",
              "10"
            ]
          },
          {
            "area": {
              "name": "伊豆諸島南部",
              "code": "130030"
            },
            "pops": [
              "50",
              "20",
              "50",
              "50",
              "20"
            ]
          },
          {
            "area": {
              "name": "小笠原諸島",
              "code": "130040"
            },
            "pops": [
              "20",
              "30",
              "30",
              "30",
              "20"
            ]
          }
        ]
      },
      {
        "timeDefines": [
          "2023-11-13T00:00:00+09:00",
          "2023-11-13T09:00:00+09:00"
        ],
        "areas": [
          {
            "area": {
              "name": "東京",
              "code": "44132"
            },
            "temps": [
              "9",
              "15"
            ]
          },
          {
            "area": {
              "name": "大島",
              "code": "44172"
            },
            "temps": [
              "10",
              "16"
            ]
          },
          {
            "area": {
              "name": "八丈島",
              "code": "44263"
            },
            "temps": [
              "15",
              "18"
            ]
          },
          {
            "area": {
              "name": "父島",
              "code": "44301"
            },
            "temps": [
              "22",
              "26"
            ]
          }
        ]
      }
    ]
  },
  {
    "publishingOffice": "気象庁",
    "reportDatetime": "2023-11-12T17:00:00+09:00",
    "timeSeries": [
      {
        "timeDefines": [
          "2023-11-13T00:00:00+09:00",
          "2023-11-14T00:00:00+09:00",
          "2023-11-15T00:00:00+09:00",
          "2023-11-16T00:00:00+09:00",
          "2023-11-17T00:00:00+09:00",
          "2023-11-18T00:00:00+09:00",
          "2023-11-19T00:00:00+09:00"
        ],
        "areas": [
          {
            "area": {
              "name": "東京地方",
              "code": "130010"
            },
            "weatherCodes": [
              "211",
              "111",
              "101",
              "101",
              "203",
              "101",
              "101"
            ],
            "pops": [
              "",
              "20",
              "20",
              "20",
              "80",
              "20",
              "20"
            ],
            "reliabilities": [
              "",
              "",
              "A",
              "A",
              "B",
              "A",
              "A"
            ]
          },
          {
            "area": {
              "name": "伊豆諸島北部",
              "code": "130020"
            },
            "weatherCodes": [
              "202",
              "201",
              "201",
              "101",
              "202",
              "201",
              "101"
            ],
            "pops": [
              "",
              "30",
              "30",
              "20",
              "70",
              "30",
              "20"
            ],
            "reliabilities": [
              "",
              "",
              "A",
              "A",
              "A",
              "A",
              "A"
            ]
          },
          {
            "area": {
              "name": "伊豆諸島南部",
              "code": "130030"
            },
            "weatherCodes": [
              "202",
              "201",
              "200",
              "101",
              "202",
              "200",
              "201"
            ],
            "pops": [
              "",
              "40",
              "40",
              "20",
              "70",
              "40",
              "30"
            ],
            "reliabilities": [
              "",
              "",
              "B",
              "A",
              "A",
              "B",
              "A"
            ]
          },
          {
            "area": {
              "name": "小笠原諸島",
              "code": "130040"
            },
            "weatherCodes": [
              "200",
              "101",
              "101",
              "201",
              "200",
              "202",
              "202"
            ],
            "pops": [
              "",
              "20",
              "20",
              "30",
              "40",
              "50",
              "50"
            ],
            "reliabilities": [
              "",
              "",
              "A",
              "A",
              "C",
              "C",
              "C"
            ]
          }
        ]
      },
      {
        "timeDefines": [
          "2023-11-13T00:00:00+09:00",
          "2023-11-14T00:00:00+09:00",
          "2023-11-15T00:00:00+09:00",
          "2023-11-16T00:00:00+09:00",
          "2023-11-17T00:00:00+09:00",
          "2023-11-18T00:00:00+09:00",
          "2023-11-19T00:00:00+09:00"
        ],
        "areas": [
          {
            "area": {
              "name": "東京",
              "code": "44132"
            },
            "tempsMin": [
              "",
              "9",
              "9",
              "8",
              "12",
              "10",
              "9"
            ],
            "tempsMinUpper": [
              "",
              "10",
              "10",
              "10",
              "14",
              "12",
              "11"
            ],
            "tempsMinLower": [
              "",
              "6",
              "8",
              "7",
              "10",
              "8",
              "8"
            ],
            "tempsMax": [
              "",
              "17",
              "18",
              "19",
              "19",
              "18",
              "19"
            ],
            "tempsMaxUpper": [
              "",
              "19",
              "19",
              "21",
              "22",
              "20",
              "21"
            ],
            "tempsMaxLower": [
              "",
              "16",
              "16",
              "17",
              "18",
              "16",
              "16"
            ]
          },
          {
            "area": {
              "name": "大島",
              "code": "44172"
            },
            "tempsMin": [
              "",
              "10",
              "11",
              "11",
              "14",
              "13",
              "12"
            ],
            "tempsMinUpper": [
              "",
              "12",
              "13",
              "13",
              "16",
              "15",
              "14"
            ],
            "tempsMinLower": [
              "",
              "9",
              "10",
              "10",
              "13",
              "11",
              "10"
            ],
            "tempsMax": [
              "",
              "18",
              "19",
              "20",
              "20",
              "18",
              "19"
            ],
            "tempsMaxUpper": [
              "",
              "19",
              "20",
              "21",
              "21",
              "19",
              "20"
            ],
            "tempsMaxLower": [
              "",
              "17",
              "18",
              "19",
              "19",
              "16",
              "17"
            ]
          },
          {
            "area": {
              "name": "八丈島",
              "code": "44263"
            },
            "tempsMin": [
              "",
              "12",
              "14",
              "15",
              "16",
              "15",
              "14"
            ],
            "tempsMinUpper": [
              "",
              "14",
              "15",
              "16",
              "18",
              "17",
              "16"
            ],
            "tempsMinLower": [
              "",
              "11",
              "13",
              "13",
              "15",
              "14",
              "13"
            ],
            "tempsMax": [
              "",
              "19",
              "20",
              "22",
              "22",
              "19",
              "21"
            ],
            "tempsMaxUpper": [
              "",
              "21",
              "22",
              "23",
              "24",
              "21",
              "23"
            ],
            "tempsMaxLower": [
              "",
              "17",
              "19",
              "21",
              "21",
              "18",
              "19"
            ]
          },
          {
            "area": {
              "name": "父島",
              "code": "44301"
            },
            "tempsMin": [
              "",
              "19",
              "20",
              "20",
              "22",
              "20",
              "19"
            ],
            "tempsMinUpper": [
              "",
              "20",
              "21",
              "22",
              "23",
              "22",
              "21"
            ],
            "tempsMinLower": [
              "",
              "18",
              "18",
              "19",
              "20",
              "19",
              "17"
            ],
            "tempsMax": [
              "",
              "25",
              "26",
              "26",
              "28",
              "27",
              "24"
            ],
            "tempsMaxUpper": [
              "",
              "26",
              "27",
              "27",
              "29",
              "28",
              "27"
            ],
            "tempsMaxLower": [
              "",
              "24",
              "25",
              "25",
              "26",
              "26",
              "23"
            ]
          }
        ]
      }
    ],
    "tempAverage": {
      "areas": [
        {
          "area": {
            "name": "東京",
            "code": "44132"
          },
          "min": "8.7",
          "max": "16.6"
        },
        {
          "area": {
            "name": "大島",
            "code": "44172"
          },
          "min": "11.3",
          "max": "17.6"
        },
        {
          "area": {
            "name": "八丈島",
            "code": "44263"
          },
          "min": "14.1",
          "max": "19.8"
        },
        {
          "area": {
            "name": "父島",
            "code": "44301"
          },
          "min": "21.6",
          "max": "25.8"
        }
      ]
    },
    "precipAverage": {
      "areas": [
        {
          "area": {
            "name": "東京",
            "code": "44132"
          },
          "min": "4.8",
          "max": "24.8"
        },
        {
          "area": {
            "name": "大島",
            "code": "44172"
          },
          "min": "15.7",
          "max": "55.6"
        },
        {
          "area": {
            "name": "八丈島",
            "code": "44263"
          },
          "min": "39.0",
          "max": "90.0"
        },
        {
          "area": {
            "name": "父島",
            "code": "44301"
          },
          "min": "7.0",
          "max": "29.1"
        }
      ]
    }
  }
]

データがちゃんと入っていることは理解できましたが、入っているデータをどう活用するのかパッと見ただけではわからなかったので、加工方法を調べるか、別の使いやすいものを利用するのか、やりやすい方法で継続していこうかなと思います。

参考