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"
}
]
}
}
]
データがちゃんと入っていることは理解できましたが、入っているデータをどう活用するのかパッと見ただけではわからなかったので、加工方法を調べるか、別の使いやすいものを利用するのか、やりやすい方法で継続していこうかなと思います。
参考
- NimでWebスクレイピングを操作
- Nim web上のページや画像データの取得(httpclient)
- 【初心者が2時間でNimを完全理解するハンズオン】Nimでローカルで起動してファイルを配信するWebサーバーを作ろう
- 【Python】気象庁API から天気予報を取得してみた
- 気象庁ホームページ防災気象情報のURL構造