以下の内容はhttps://rkdora.hatenablog.com/entry/2020/03/31/204552より取得しました。


【LINEbot】天気予報くんをつくる(その2 地域IDを取得)

前回のつづき rkdora.hatenablog.com

前回で、久留米市の天気予報を取得することができた。

その他の地域の天気予報を取得したい。

そのためには、全国の地域IDを取得する必要がある。(久留米は[400040])

ここでは、全国の地域IDをスクレイピングで取得し外部ファイルに辞書として保存することにする。

スクレイピングする準備

pipenv install bs4
pipenv install lxml

scrape.py

import requests as rq
from bs4 import BeautifulSoup as bs4
import pickle

url = 'http://weather.livedoor.com/forecast/rss/primary_area.xml'

path = 'city_dict.pickle'

res = rq.get(url)
soup = bs4(res.content, 'xml')

city_tags = soup.find_all('city')

city_dict = {}

for city in city_tags:
    city_dict[city['title']] = city['id']

print(city_dict)

with open(path, mode='wb') as f:
        pickle.dump(city_dict,f)

city_dict.pickleに入れたもの

{'稚内': '011000', '旭川': '012010', '留萌': '012020', '網走': '013010', '北見': '013020', '紋別': '013030', '根室': '014010', '釧路': '014020', '帯広': '014030', '室蘭': '015010', '浦河': '015020', '札幌': '016010', '岩見沢': '016020', '倶知安': '016030', '函館': '017010', '江差': '017020', '青森': '020010', 'むつ': '020020', '八戸': '020030', '盛岡': '030010', '宮古': '030020', '大船渡': '030030', '仙台': '040010', '白石': '040020', '秋田': '050010', '横手': '050020', '山形': '060010', '米沢': '060020', '酒田': '060030', '新庄': '060040', '福島': '070010', '小名浜': '070020', '若松': '070030', '水戸': '080010', '土浦': '080020', '宇都宮': '090010', '大田原': '090020', '前橋': '100010', 'みなかみ': '100020', 'さいたま': '110010', '熊谷': '110020', '秩父': '110030', '千葉': '120010', '銚子': '120020', '館山': '120030', '東京': '130010', '大島': '130020', '八丈島': '130030', '父島': '130040', '横浜': '140010', '小田原': '140020', '新潟': '150010', '長岡': '150020', '高田': '150030', '相川': '150040', '富山': '160010', '伏木': '160020', '金沢': '170010', '輪島': '170020', '福井': '180010', '敦賀': '180020', '甲府': '190010', '河口湖': '190020', '長野': '200010', '松本': '200020', '飯田': '200030', '岐阜': '210010', '高山': '210020', '静岡': '220010', '網代': '220020', '三島': '220030', '浜松': '220040', '名古屋': '230010', '豊橋': '230020', '津': '240010', '尾鷲': '240020', '大津': '250010', '彦根': '250020', '京都': '260010', '舞鶴': '260020', '大阪': '270000', '神戸': '280010', '豊岡': '280020', '奈良': '290010', '風屋': '290020', '和歌山': '300010', '潮岬': '300020', '鳥取': '310010', '米子': '310020', '松江': '320010', '浜田': '320020', '西郷': '320030', '岡山': '330010', '津山': '330020', '広島': '340010', '庄原': '340020', '下関': '350010', '山口': '350020', '柳井': '350030', '萩': '350040', '徳島': '360010', '日和佐': '360020', '高松': '370000', '松山': '380010', '新居浜': '380020', '宇和島': '380030', '高知': '390010', '室戸岬': '390020', '清水': '390030', '福岡': '400010', '八幡': '400020', '飯塚': '400030', '久留米': '400040', '佐賀': '410010', '伊万里': '410020', '長崎': '420010', '佐世保': '420020', '厳原': '420030', '福江': '420040', '熊本': '430010', '阿蘇乙姫': '430020', '牛深': '430030', '人吉': '430040', '大分': '440010', '中津': '440020', '日田': '440030', '佐伯': '440040', '宮崎': '450010', '延岡': '450020', '都城': '450030', '高千穂': '450040', '鹿児島': '460010', '鹿屋': '460020', '種子島': '460030', '名瀬': '460040', '那覇': '471010', '名護': '471020', '久米島': '471030', '南大東': '472000', '宮古島': '473000', '石垣島': '474010', '与那国島': '474020'}

main.py

from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage
)
import os

import requests as rq
import json

import pickle

app = Flask(__name__)

LINE_CHANNEL_ACCESS_TOKEN = os.environ["LINE_CHANNEL_ACCESS_TOKEN"]
LINE_CHANNEL_SECRET = os.environ["LINE_CHANNEL_SECRET"]

line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)

city_path = 'city_dict.pickle'

def get_weather_info(city_num):
    url = 'http://weather.livedoor.com/forecast/webservice/json/v1?'
    city_params = {'city': city_num}
    data = rq.get(url, params=city_params)
    content = json.loads(data.text)

    content_title = format(content['title'])
    content_text = format(content['description']['text'])
    content_time = format(content['description']['publicTime'])\
                    .replace('T', ' ').replace('-', '/')[:-5]

    return content_title + '\n\n' + content_text + '\n\n最終更新日時:' + content_time

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    user_message = event.message.text
    with open(city_path, mode='rb') as f:
        city_dict = pickle.load(f)

    if  user_message in city_dict:
        message = get_weather_info(city_dict[user_message])
    else:
        message = '対応していません。'

    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=message))


if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

f:id:rkdora:20200331160107p:plain

f:id:rkdora:20200331160156p:plain

つづく

rkdora.hatenablog.com




以上の内容はhttps://rkdora.hatenablog.com/entry/2020/03/31/204552より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14