Skip to content

Instantly share code, notes, and snippets.

@tetlabo
Created January 20, 2023 03:32
Show Gist options
  • Save tetlabo/81f1b801320103acfda13a3acb935e52 to your computer and use it in GitHub Desktop.
Save tetlabo/81f1b801320103acfda13a3acb935e52 to your computer and use it in GitHub Desktop.
「横浜市立学校 空気の見える化プロジェクト」(https://minnaair.com/blog/yokohama/) のデータを取得するRスクリプト
# 「横浜市立学校 空気の見える化プロジェクト」(https://minnaair.com/blog/yokohama/) のデータを取得するRスクリプト
# タナカケンタ (鶴見教育工学研究所)
# https://mana.bi/
#
# プロジェクトのWebページにアクセスし、データをスクレイピングし、整形するスクリプトです。
# (どういうわけか) Webページの中に全期間の生データが直接書いてある🤪ので、それを取得しています。
# 今後データが増えていったら、ページの読み込み速度がどんどん遅くなりそうですが...
# 現在のところ、2023/01/20頃から本運用が開始され、それ以降のデータがすべて取得できるようですので、
# このスクリプトでは前回の結果からの差分を取る、といったことはしていません。
# スクリプトの利用、改変はご自由にどうぞ。ただし、スクレイピングの間隔は空けて、サービス提供者の負荷に
# ならないようにしてください。
# 教育・学習用途でコメントをしっかり書いておきます。
# ライブラリの読み込み
library(tidyverse)
library(lubridate) # 日付データの取り扱いを容易にする
library(rvest) # Webスクレイピングを行う
library(jsonlite) # JSONデータを取り扱う
html <- read_html("https://minnaair.com/blog/yokohama/") # HTMLを取得
data <- html %>%
html_nodes("script") %>% # <script> タグの要素を取得する
.[[13]] %>% # 13番目のタグに欲しいデータが格納されている
html_text() %>% # タグに囲まれた文字列を取得する
str_split(., "\n") %>% # 改行で文字列をベクトルの要素に分解する
unlist(.) %>% # ベクトルを囲んでいるリストを解除する
.[3:5] %>% # 1、2行目と6行目は空行なので除外する
str_replace_all(., "^\\s+const db_.* = ", "") # JavaScriptの変数定義に関する記述を削除する
# 学校情報
places <- fromJSON(data[1]) %>% # 取得したデータベクトルの1番目の要素を選択し、JSONとして読み込む
select(-as.character(0:14)) %>% # どういうわけか、列が重複しているので、数字が列名になっているものを除去する
rename(school_id = id, school_uuid = uuid, school_name = name) # データを結合する時のために列名を変更する
# 機器情報
devices <- fromJSON(data[2]) %>% # 同上
select(-as.character(0:6)) %>%
rename(device_id = id, device_uuid = uuid, device_name = name, school_id = office_id)
# 観測値
values <- fromJSON(data[3]) %>% # 同上
select(-as.character(0:10)) %>%
mutate(timestamp_value = as_datetime(as.numeric(timestamp_value), tz = "Asia/Tokyo")) %>% # UNIXタイムを読みやすい年月日時刻に変換する
rename(value_id = id, value_uuid = uuid, datetime = timestamp_value) # 列名を変更する
# データを結合する
df <- values %>%
left_join(devices, by = "device_id") %>% # いちばん行数が多い個別の観測値 (values) をベースに機器情報を結合する
left_join(places, by = "school_id") %>% # さらに学校情報を結合する
# 必要な列だけ抽出する
select(datetime, school_id, school_name, district, latitude, longitude, device_id, device_name, co2, humidity, pm10, pm25, temperature, tvoc, air_quality, value_id)
# Excelでも開けるUTF-8 BOM付きのCSVファイルで出力する
write_excel_csv(df, "yokohama_air_data.csv")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment