cheerup-ehime / cheerup-ehime.github.io

jekyll site for this organization
MIT License
7 stars 5 forks source link

愛媛の防災情報から避難所情報を収集して整理したい #27

Open kkd opened 6 years ago

kkd commented 6 years ago

http://ehime.force.com/PUB_VF_HinanjyoList

避難所の開設・閉鎖・人数が表示されているが、見づらすぎる。

sassy commented 6 years ago

TODO: https://github.com/cheerup-ehime/cheerup-ehime.github.io/pull/36#issuecomment-408641861

imabari commented 6 years ago

ファイル名のルールがわからないので表示のみ https://imabari.hateblo.jp/entry/2018/08/04/174753

imabari commented 6 years ago

YYYY-mm-dd-HHMM-{city}-hinanjo.mdというファイル名で避難所情報の記事を作成するようにしました。 cronで回すなら時間設定を変更してください。 避難所閉鎖しているところは除去しております。

import datetime
import re
import time
from urllib.parse import urljoin
import string

import requests
from bs4 import BeautifulSoup

def get_hinanjo_page(url):

    headers = {
        'User-Agent':
        'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
    }

    r = requests.get(url, headers=headers)

    if r.status_code == requests.codes.ok:

        soup = BeautifulSoup(r.content, 'html.parser')

        body = soup.select_one('#wrap > p').get_text(strip=True)

        # 発表内容と避難所に分割
        hapyou, hinanjo = [
            i.strip() for i in body.split('(避難世帯数、避難人数は、自主避難を含む)', 2)
        ]

        #:の後の空白文字を除去
        hapyou = re.sub(r':\s+', ':', hapyou)

        # 空行を除去、改行x2で段落にする
        res_hapyou = '\n\n'.join([i.strip() for i in hapyou.splitlines() if i])

        # マルチラインで正規表現
        pattern = re.compile(
            r'^(.*?):(臨時)?避難所\s(.*?)\s+\((\d{4}/\d{2}/\d{2} \d{2}:\d{2})\)\s+避難世帯数:(.*?)\s+避難人数:(.*?)\s+?$',
            re.M)

        # 開設済み避難所のみ抽出、閉鎖済みの避難所は除外
        hinanjo_open = [i for i in pattern.findall(hinanjo) if i[2] == '開設']

        hinanjo_list = []

        # 避難所がない場合はスキップ
        if len(hinanjo_open):

            hinanjo_list.append("|避難所名|状況|避難世帯数|避難人数|更新日|")
            hinanjo_list.append("|--|--|--|--|--|")

            # 避難所を表に変換
            for i in hinanjo_open:

                hinanjo_list.append(
                    '|{0[0]}|{0[2]}|{0[4]}|{0[5]}|{0[3]}|'.format(i))

        res_hinanjo = '\n'.join(hinanjo_list)

        return res_hapyou, res_hinanjo

if __name__ == '__main__':

    url = 'http://ehime.force.com/PUB_VF_HinanjyoList'

    headers = {
        'User-Agent':
        'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
    }
    r = requests.get(url, headers=headers)

    if r.status_code == requests.codes.ok:

        soup = BeautifulSoup(r.content, 'html.parser')

        # 現在よりn日前
        dt_now = datetime.datetime.now() - datetime.timedelta(days=1)

        # 現在よりn時間前
        # dt_now = datetime.datetime.now() - datetime.timedelta(hours=1)

        # print(dt_now)

        for dl in soup.select('#shelterArea > div > dl'):

            _date, _title = [
                p.get_text(strip=True) for p in dl.select('a > dd > p')
            ]

            # 文字から日付に変換
            dt_date = datetime.datetime.strptime(_date, '%Y/%m/%d %H:%M')

            # タイトル抽出
            title = _title.split(':')[0].strip()

            # 市町村名抽出
            city = title.split()[0].strip()

            # n日前のみ表示
            if dt_date > dt_now:

                # 避難所ページリンク生成
                link = urljoin(url, dl.select_one('a').get('href'))

                # 避難所ページをスクレイピング
                hapyou, hinanjo = get_hinanjo_page(link)

                # テンプレート
                markdown = """\
---
title: $title($date)

category:
  - $city

tag:
  - 避難所
---
$hapyou

$hinanjo
"""

                # コンテンツ
                context = {
                    'title': title,
                    'city': city,
                    'date': _date,
                    'hinanjo': hinanjo,
                    'hapyou': hapyou,
                }
                city_names = {
                    '今治市': 'imabari',
                    '新居浜市': 'niihama',
                    '西条市': 'saijo',
                    '四国中央市': 'shikokuchuo',
                    '上島町': 'kamijima',
                    '松山市': 'matsuyama',
                    '伊予市': 'iyo',
                    '東温市': 'toon',
                    '久万高原町': 'kumakogen',
                    '松前町': 'masaki',
                    '砥部町': 'tobe',
                    '宇和島市': 'uwajima',
                    '八幡浜市': 'yawatahama',
                    '大洲市': 'ozu',
                    '西予市': 'seiyo',
                    '内子町': 'uchiko',
                    '伊方町': 'ikata',
                    '松野町': 'matsuno',
                    '鬼北町': 'kihoku',
                    '愛南町': 'ainan'
                }

                # テンプレート
                template = string.Template(markdown)
                md_post = template.safe_substitute(context)

                filename = '{}-{}-hinanjo.md'.format(
                    dt_date.strftime('%Y-%m-%d-%H%M'), city_names[city])

                with open(filename, 'w') as fw:
                    fw.write(md_post)

                time.sleep(1)

            else:
                break