前回のつづき 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)


つづく