aktnk / covid19

静岡県 新型コロナウイルス感染症対策サイト / Shizuoka COVID-19 Task Force website
https://stopcovid19.code4numazu.org/
MIT License
0 stars 0 forks source link

「最新のお知らせ」欄が更新されるようにする #21

Open aktnk opened 4 years ago

aktnk commented 4 years ago

改善詳細 / Details of Improvement

スクリーンショット / Screenshot

期待する見せ方・挙動 / Expected behavior

動作環境・ブラウザ / Environment

aktnk commented 4 years ago

(案1)の場合、 実現手段は

  1. 手動(目で見て、ファイルを手動で作成し、登録する)
  2. 自動(Webスクレイピングし、ファイルを生成し、登録する) 東京都の新型コロナウイルス対策サイトは、東京都防災ホームページhttps://www.bousai.metro.tokyo.lg.jp/taisaku/saigai/1007261/index.html より関係のあるものを抜き出している感じです。

(案2)の場合、 例えば、北海道の新型コロナウイルス対策サイトhttps://stopcovid19.hokkaido.dev/ では、「北海道発表の新型コロナウイルス感染症に関する情報はこちら」として、道庁のサイトhttp://www.pref.hokkaido.lg.jp/ss/tkk/singatakoronahaien.htm が表示されます。

(案3)の場合、 実現案として、毎日のdata.json更新の際に、下記を判断して、各カードへのリンクにして記載する。

が感がられそう。 どれが良いでしょう・・・?

hrsano645 commented 4 years ago

なかなか難しいですね。。案2で誘導したほうが本来は良いと思ってます。

案1の対策サイトに載せるのであれば、手動だと手間をかけてしまうので、スクレイピングで自動でやりたいですね。午前、午後で2回ほど巡回する感じで。 ただ、サイトの構造が変わると何もできなくなるのがデメリットですね。(吸収する手段は無くはないのですが。。)構造変えないでほしいと静岡県に言いたいw

案3は、こちらの解釈が入ってしまうのが問題かもしれないので悩みますね。

aktnk commented 4 years ago

@hrsano645 さんのコメントを踏まえ、まあ、やるなら「案1の自動化」かなということで、試作してみました。 実運用するには、data.jsonの実行環境と合わせて、文字コードなど問題がでないか確認する必要がありそう・・・ なお、下記を試した環境は、Windows10のPython 3.8.3 です。

下記のwhats_new.py実行すると・・・

from lxml import html
from urllib.request import urlopen
import json
import codecs

# 新着情報を入手するサイトのURL
TARGET_URL = "https://www.pref.shizuoka.jp/kinkyu/covid-19.html"
# 新着情報が掲載されている位置をXPathで指定
NEW_ITEM_PTAG = "/html/body/div[1]/div[3]/div[2]/div/div/div[1]/table[2]/tbody/tr[2]/td/p"
# 出力するファイル名
FILE_NAME = "news.json"

try:
    tree = html.parse( urlopen( TARGET_URL ))
    html_src = tree.getroot()

    new_items = []
    # 新着情報を全取得
    for p_element in html_src.xpath( NEW_ITEM_PTAG ):
        a_element = p_element.xpath('a') # a tag
        # 日付文字列の先頭に"・"、最後に" "があるから省く
        item = {
            "date": p_element.text.strip()[1:],
            "url": a_element[0].get('href'),
            "text": a_element[0].text
        }
        new_items.append(item)

except Exception as e:
    print("Error: {}\n新着情報取得中にエラーが発生しました".format(e))
    print("'{}' ページが無くなったか、\n同ページ内の構成が変更された可能性があります".format(TARGET_URL))
    exit(1)

# ここまで来たらjsonファイルに保存する
with codecs.open( FILE_NAME, 'w', 'utf-8' ) as f:
    json.dump( {"newsItems": new_items}, f, ensure_ascii=False, indent=4 )

以下のdata.jsonファイルを保存します。

{
    "newsItems": [
        {
            "date": "7/10",
            "url": "https://www.pref.shizuoka.jp/kinkyu/covid-19-tyuumokujouhou.html",
            "text": "新型コロナウイルス陽性者が1名確認されました"
        },
        {
            "date": "7/10",
            "url": "/kinkyu/covid-19-keikailevel.html",
            "text": "警戒レベルを更新しました"
        },
        {
            "date": "7/10",
            "url": "/bousai/covid-19-saigaijikansenboushitaisaku.html",
            "text": "災害時における新型コロナウイルス感染防止対策をご確認ください"
        },
        {
            "date": "7/7",
            "url": "/kinkyu/covid19-com.html#kaigaikyotenn",
            "text": "海外に事業拠点をお持ちの方へのお知らせを追加しました"
        }
    ]
}
hrsano645 commented 4 years ago

@aktnk 基本的には自分も似たような感じになりそうです。 スクレイピングはライブラリ使ったほうが早いので、requests+beautifulsoup4当たりでやろうと思ってます。 そうなると、データ生成用のサーバーにもライブラリを入れる必要があって、そこをどうするかも考えてみます。

hrsano645 commented 4 years ago

エラー処理を増やして、requests + bs4を使ったパターンを作ってみました。

https://github.com/hrsano645/covid19-gen-datajson-shizuokapref/blob/issue%2310-add_news_json/gen_newsjson.py

データ生成させているサーバーで動かす場合、lxmlも requests+bs4でもパッケージのインストールが必要になるので、シェルスクリプトで毎回仮想環境生成させてパッケージのインストール, 実行が必要になりそうです。

aktnk commented 4 years ago

@hrsano645 さん、本件よろしくお願いします。

aktnk commented 4 years ago

スクレイピングして生成してしまうと、この部分だけ多言語対応ができなくなりますね・・・

hrsano645 commented 4 years ago

メトロ版でも対応難しそうですし、動的な翻訳サービスでも入れないと厳しいと思います。。