Help us understand the problem. What is going on with this article?

COVID-19Hokkaidoデータ編①スクレイピングなどによる初期データ作成

もくじ

COVID-19Hokkaidoデータ編①スクレイピングなどによる初期データ作成←この記事だよ!
COVID-19Hokkaidoデータ編②オープンデータ化+自動更新
COVID-19Hokkaidoデータ編③完全自動化

スクリーンショット 2020-03-10 17.25.46.png

はじめに

東京都とCode for Japanにより東京都公式コロナウイルス対策サイトがリリースされ、そのソースコードがなんとGitHubでMITライセンスで公開されました。つまり他の道府県でも「同様のデータを用意できれば」同じように可視化するウェブアプリケーションを作成出来るという事です(実際はサーバーのリソースなども必要になってきますが)。画期的な取組です。

さてそんな訳で、全国各地の動きも活発化し、北海道ではCode for Sapporoや道内IT企業、自治体職員など多彩なバックグラウンドをもつ有志によるJUST道ITというグループが結成され、3月6日に東京都からフォークしたプロジェクトが3月9日の昼にリリースされました。

Covid19Hokkaido 北海道新型コロナウイルスまとめサイト

ほぼ同時に神奈川でも同様の形でサイトがリリースされたり、これらの動きが窓の杜さんやITmediaさんにも紹介されるなど、東京発の画期的な取組が全国へ波及し始めています。

この記事について

前述のとおり、「同様のデータを用意できれば」同じように可視化するウェブアプリケーションを作成出来る訳ですが、自治体によってデータの公開状況・提供方法が異なるため、それらをうまいこと収集してデータをこさえるのが重要になってくる訳です。私も微力ながら本プロジェクトに参加させて頂き、データ周りの開発に携わった事から、データの取得・生成・管理のフローについて本記事にまとめる事とします。

東京都公式サイトのデータ

東京都公式サイト(以下都サイト)のソースコードでは、data/data.jsonというファイルに可視化されるべきデータが全て格納されており、key別に以下の構成になっていました(フォーク時点)。

key 東京都サイトでの名称 内容
contacts 新型コロナコールセンター相談件数 日別コールセンター相談件数
discharges 未実装 退院者別属性
discharges_summary 未実装 日別退院者数
inspections 未実装 日別検査データ
inspections_summary 未実装(devでは検査実施日別状況) 検査により陽性が判明した日・人数のデータ(1/24〜、都内外別)
patients 陽性患者の属性 感染者別属性
patients_summary 陽性患者数 日別感染者数
better_patients_summary 未実装 感染者数、退院者数、死亡者数、軽症、中等症、重症の日別データ
querents 帰国者・接触者電話相談センター相談件数 日別電話相談センター相談件数

またkeyごとの各カラムの意味は以下のとおりです(必要なデータのみ)。

key colum 東京版の何に使われているか memo
contacts 日付 新型コロナコールセンター相談件数 utils/formatGraph.tsに読まれます
contacts 小計 新型コロナコールセンター相談件数 utils/formatGraph.tsに読まれます
inspections_summary labels 検査実施日別状況 index.vueで読まれます
inspections_summary 都内 検査実施日別状況 index.vueで読まれます
inspections_summary その他 検査実施日別状況 index.vueで読まれます
patients リリース日 陽性患者の属性 utils/formatTable.tsに読まれます
patients 居住地 陽性患者の属性 utils/formatTable.tsに読まれます
patients 年代 陽性患者の属性 utils/formatTable.tsに読まれます
patients 性別 陽性患者の属性 utils/formatTable.tsに読まれます
patients_summary 日付 陽性患者数 utils/formatGraph.tsに読まれます
patients_summary 小計 陽性患者数 utils/formatGraph.tsに読まれます
querents 日付 帰国者・接触者電話相談センター相談件数 utils/formatGraph.tsに読まれます
querents 小計 帰国者・接触者電話相談センター相談件数 utils/formatGraph.tsに読まれます

以上を踏まえたdata.jsonの構造は以下です。

data.json
{
    "contacts": {    
        "data": [
            {
                "日付": "2020-02-14T08:00:00.000Z",
                "曜日": "",
                "9-13時": "",
                "13-17時": "",
                "17-21時": "",
                "date": "2020-02-14",
                "w": "",
                "short_date": "02/14",
                "小計": 172
            },
            {
                "日付": "2020-02-15T08:00:00.000Z",
                "曜日": "",
                "9-13時": "",
                "13-17時": "",
                "17-21時": "",
                "date": "2020-02-15",
                "w": "",
                "short_date": "02/15",
                "小計": 179
            },
            //以下略
        ],
        "date": "2020-03-07T17:55:16.974293+09:00"
    },
    "querents": {},
    "patients": {},
    "patients_summary": {}, 
    "discharges": {},
    "discharges_summary": {},
    "inspections": {},
    "inspections_summary": {},
    "better_patients_summary": {},
    "last_update": "2020-03-07T17:55:16.974293+09:00", //ISO-8601フォーマットのdatetime
    "main_summary": {}
}
//last_updateとmain_summary以外は、contactsと同様にdateとdataを持ちます
//contacts以外は要素を割愛しています
//main_summaryは特殊ですが、システム上は使用されていないので無視しても問題ありません

北海道版V0のデータ

V0時点で外部から取得可能なデータは北海道のウェブサイトに掲載されているデータに限られており、その中で機械判読可能な情報は、HTMLのtableに表示される患者の属性のみでした。また、札幌市が相談件数のCSVファイルをオープンデータとして公開していた事から、北海道版V0時点ではこれらのデータを用いる事となります。使えるデータと形式は以下のとおりです。

key データの出所 形式
patients 道ウェブサイト HTMLのテーブル
patients_summary 道ウェブサイト HTMLのテーブル
contacts 札幌市 CSVファイル
querents 札幌市 CSVファイル

※検査データはV0では用意出来ないと判断し、表示しない事としました

以上から、V0時点とV1以降の稼働イメージが以下のとおりになりました。
スクリーンショット 2020-03-10 17.37.10.png
以下、データの取得・生成・管理のフローをまとめます。

データの取得・生成

さすがに手作業でデータを更新する事はなく、データ取得・生成を自動で行うスクリプトを書きました。
Kanahiro/covid19hokkaido_scraping
※上記はV0リリース時の状態のURLです(履歴から復元)
※現在はcodeforsapporoにフォークされそちらが本流になっております

本スクリプト(main.py)は実行されると以下の手順でdata.jsonを生成します(V0時点)。

  1. data.jsonに準拠した構造のdictを生成(各要素のデータは空)
  2. 道ウェブサイトをスクレイピングしてdictに変換
  3. importの中にあるcsvファイルをすべてdictに変換
  4. 2,3のdictを1の各要素に突っ込む
  5. 1をdata.jsonとして出力

道ウェブサイトのスクレイピング

道ウェブサイトは、PythonとBeautifulSoupによりスクレイピングしています。table内の全ての行(tr)を取得してdictに変換しています。
※コードは割愛、上記リポジトリのpatients.pyになります

CSVファイルの読み込み

V0時点で、contantsとquerentsはソースが生のCSVファイルであるため、importディレクトリ内に保存されたCSVファイルを全て読み込みdictに変換する仕組みとしました。

データの管理

V0から現在まで、本スクリプトで生成されたdata.jsonを「手動で」本体リポジトリにプッシュしています。
data.jsonの生成自体はGitHub Actionsでスケジューリングしており、15分間隔でmain.pyを実行する事で生成・別ブランチにプッシュするようになっています。
なので、リリース時点では適宜私がdata.jsonを本体にプッシュしていました(1日2,3回くらい)。

自動化へ向けて

V0段階ではdata.jsonのプッシュが手動になっており、手間や即時性を考えると自動化したい訳です。
APIサーバーを別途立てるなど、様々な手法が考えられますが、以下であればGitHubのみで完結します。
(都公式も、他自治体での運用も考えてGitHubだけで完結するように作っていたのかなぁ)

  • data.jsonの生成をGitHub Actionsで自動化
  • その自動生成されたjsonファイルに直接アクセス・非同期通信し、UIに反映させる

※都公式サイトのUIは(フォーク時点では)非同期通信は想定されていなかったので、適宜フロントの修正が必要です

Kanahiro
GISを中心に勉強中、いろいろ作っています。
https://kiguchi999.hatenablog.com/
MIERUNE
位置情報に関する様々な技術情報やTipsをMIERUNEのメンバーがお届けします。位置や可視化に関するご相談がございましたらぜひご連絡ください!
https://mierune.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした