見出し画像

COVID19の日次新規陽性者数を居住地別にカウントするWEBアプリケーションをつくる -中間-

※約2年前に下書きしたままの記事でしたが、折角なので公開したいと思います。
記事を作成した時期と現在とでは異なっている部分も多いと思いますので、参考になさる際には十分にお気をつけください。

皆様こんにちは。前回のお話に引き続き、早速WEBアプリケーションの開発をしていきたいと思います。WEBアプリケーションの開発環境は「Jupyter Notebook」を使っています。「Jupyter Notebook」については下記のページを参考にしてください。

「Jupyter Notebook」のホームページ

1 早速結論

紆余曲折の結果、色んなサイトを調べまくった結果、下記の通りコードを書くことができました。

# covid19Oki.py

import pandas as pd
import datetime
import requests
from bs4 import BeautifulSoup
import time
import sqlite3
import csv

# 今日の日付を取得(4桁)
dt_now = datetime . date.today()
dt_now1 = dt_now.strftime("%m%d")
# 前日の日付を取得(4桁)
oneday = datetime.timedelta(days=1)
dt_yes = dt_now-oneday
dt_yes = dt_yes.strftime("%m%d")
# 今日の日付を取得
dt_now2 = datetime . date.today()
dt_now2 = dt_now2.strftime("%Y年%m月%d日")

# 県のホームページから更新日を取得する
url = 'https://www.pref.okinawa.lg.jp/site/hoken/kansen/soumu/press/20200214_covid19_pr1.html'
r = requests.get(url)
soup = BeautifulSoup(r.content, 'html.parser')
aa = soup.select('#tmp_update')
for i in aa:
    update_id = (i.string)

# 出力の仕方を定義する
def outPut ():
    # 居住地の日次新規陽性者数をカウントする
    todayCovid19_sum = (todayCovid19['居住地'] == '宜野湾市').sum()
    print('宜野湾市の本日の新規陽性者数は:',)
    print(todayCovid19_sum)

    # 居住地の陽性者数の総数を表示する
    okinawaPrefCovid19 = pd.read_csv('okinawa_pref_covid19.csv')
    okinawaPrefCovid19_sum = (okinawaPrefCovid19['居住地'] == '宜野湾市').sum()
    print('宜野湾市のこれまでの累計感染者数は:',)
    print(okinawaPrefCovid19_sum)

# もし県のホームページが更新されたら
if update_id == '更新日:' + dt_now2:

    # 今日の日付をURLに入れる
    fpath = 'https://www.pref.okinawa.lg.jp/site/hoken/kansen/soumu/press/documents/{0}youseisyaitiran.csv'.format(dt_now1)

    # 県のホームページにあるcsvファイルの読み込み
    df = pd.read_csv(fpath ,encoding='shift-jis')

    # ---取得したcsvファイルとデータベースと比較して差分を抽出する---
    df1 = df
    df2 = pd.read_csv('okinawa_pref_covid19.csv').iloc[:,1:9]
    ret = df1[~df1.iloc[:,0].isin(df2.iloc[:,0])]

    if df1 == df2 :
        # 差分のcsvデータの読み込み
        todayCovid19 = pd.read_csv('todayCovid19.csv')
        print(todayCovid19)
        #  出力する
        outPut()

    else:
        # 出力する
        outPut()

        # 差分のCSVデータを作成する
        ret.to_csv('todayCovid19.csv')

        # 最新のCSVデータを作成する <---- (index=none)を外した
        df1.to_csv("okinawa_pref_covid19.csv")

        #okinawa_pref_covid19.dbを作成し、接続(すでに存在する場合は接続のみ)
        con = sqlite3.connect("okinawa_pref_covid19.db")
        cur = con.cursor()

        #covid19テーブルを作成(IF NOT EXISTSは「存在しなければ作成する」という意味)
        create_covid19 ="CREATE TABLE IF NOT EXISTS covid19 (id INTEGER, kakuteiNo INTEGER, gender TEXT, age TEXT, onsetDate TEXT, fixedDate TEXT, adress TEXT, job TEXT, estimatedTransmissionRoute TEXT)"
        cur.execute(create_covid19)

        #covid19テーブルのデータを削除(何回もコード実行すると同じデータ追加されるので)
        delete_covid19 = "DELETE FROM covid19"
        cur.execute(delete_covid19)

        #csvファイルの指定
        open_csv = open("okinawa_pref_covid19.csv")

        #csvファイルを読み込む
        read_csv = csv.reader(open_csv)

        #next()関数を用いて最初の行(列名)はスキップさせる
        next_row = next(read_csv)

        #csvデータをINSERTする
        rows = []
        for row in read_csv:
            rows.append(row)

        #executemany()で複数のINSERTを実行する
        cur.executemany("INSERT INTO covid19 (id, kakuteiNo, gender, age, onsetDate, fixedDate, adress, job, estimatedTransmissionRoute) VALUES (?,?,?,?,?,?,?,?,?)", rows)

        #テーブルの変更内容保存
        #csvも閉じておきましょう
        con.commit()
        open_csv.close()

        #testテーブルの確認
        select_test = "SELECT * FROM covid19"

        for i in cur.execute(select_test):
            print(i)

        #データベースの接続終了
        con.close

else:
    # 差分のcsvデータの読み込み
    todayCovid19 = pd.read_csv('todayCovid19.csv')
    print(todayCovid19)
    # 出力する
    outPut()

いや〜、長かった、、。
いちおう、これでエラーなく必要な情報を取得することができました。
各機能については後ほど解説していきたいと思います。

このコードを実行する際には事前にデータベースも作成する必要があり、かつ県のホームページ上に掲載されているcsvデータも取り込むなど、前準備が必要なので、前準備をしないとエラーになりますのでご注意下さい。

とりあえず、数日様子みて特に問題が起きなければ、Webアプリケーションとして形を整えたいと思います。実はBootstrap5をベースにした無料配布されているダッシュボードテンプレートSoft UI Dashboardを使って、抽出したデータを見やすくしようと計画中。なので、今はごちゃごちゃしていますが、現時点のファイル構成はこんな感じ。

VScodeの画面

ちょっとゴチャゴチャしてきているので、とりあえず完成した後にきれいに整理したいと思います(汗)。

現在「宜野湾市」としている所を変数化して、市町村を選択すると、新規陽性者数や累計などが表示されるなど、、ちょっと役に立つようなアプリにできたらなと考えています。

ちなみに、このコード、最初はもっと長かったです(汗)
でも、定義(def)を使うことによってある程度スッキリすることができました。初学者が書くコードなので、もっと効率が良く綺麗なコードの書き方があるはず。ちょっと考えてみます。

2 今後について

コードをかく時間があまりとれず、空いた時間にちょこちょこ触っているので、説明を細かくいれて進行していくのが難しくなってきました。

年末年始のお休みくらいで、上手く完成できたら、少しずつ解説しながらnoteを綴りたいと思います。大きな不安要素があるのですが、、。

取り合えず進捗状況はお伝えしていきたいと思います。


この記事が気に入ったらサポートをしてみませんか?