ご注意
以下のURLにあるように、WeatherHacksは2020/7/31でサービスを終了したようです。
https://help.livedoor.com/weather/index.html
残念です
本記事は残しますが、記事中のサイトには接続できない状態なので、あくまでプログラミングの参考としてご使用ください。
この記事 (Pythonで天気予報をLINE通知する) に触発されて、ちょこっとお天気の通知をやってみました。
天気アプリとか入れててもいまいち使えてないので、LINEで通知されたら見るんかなあ?というのが動機のひとつです。
ちなみに、私は Python 2.7.14
を使ってます。
Mac標準からあんまり環境いじっておりません。
地域IDを取得する
じゃあ早速 WeatherHacks から天気予報を、、、と思ったんですが。
せっかくだから地域IDを固定じゃなくて、こっちも自動で取得してみようかな、と思い立ちました。
XMLをダウンロードして変換する
http://weather.livedoor.com/forecast/rss/primary_area.xml
のXML の中の rss/channel/ldWeather:source/pref/city
と辿って取得できる数字が地域IDだそうです。
まず直接アクセスして、XML->辞書型に変換してみます。
url = "http://weather.livedoor.com/forecast/rss/primary_area.xml"
primary_area = urllib2.urlopen(url)
primary_area_dict = xmltodict.parse(primary_area)
# 県情報だけ抜き出し
pref_list = primary_area_dict["rss"]["channel"]["ldWeather:source"]["pref"]
XMLの変換ライブラリは xmltodict
を使ってます。pipでインストールしてください。
せっかくなので、クラス作ってさらに必要な部分だけ選り分けます。
# 市クラス
class City(object):
def __init__(self, pref_name, name, city_id):
self.pref_name = pref_name
self.name = name
self.city_id = city_id
# 県クラス
class Pref(object):
def __init__(self, name, city_list):
self.name = name
self.city_list = city_list
def searializeCity(pref_name, city_dict):
# 県名
pref_name_trans = pref_name
if pref_name in ["道北", "道東", "道南", "道央", "道西"]:
# 北海道はいっぱいある
pref_name_trans = "北海道"
# 名前
name = ""
if city_dict["@title"]:
name = city_dict["@title"].encode("utf-8")
# ID
city_id = ""
if city_dict["@id"]:
city_id = city_dict["@id"].encode("utf-8")
# 市
city = City(pref_name_trans, name, city_id)
return city
def serializePref(pref_dict):
# 名前
pref_name = ""
if pref_dict["@title"]:
pref_name = pref_dict["@title"].encode("utf-8")
# 市リスト
city_list = []
if not isinstance(pref_dict["city"], list):
# リストじゃないのは1件だけの辞書として扱う
city_dict = pref_dict["city"]
city = searializeCity(pref_name, city_dict)
city_list.append(city)
else:
for city_dict in pref_dict["city"]:
city = searializeCity(pref_name, city_dict)
city_list.append(city)
if len(city_list) > 0:
# 県
pref = Pref(pref_name, city_list)
return pref
else:
return None
url = "http://weather.livedoor.com/forecast/rss/primary_area.xml"
primary_area = urllib2.urlopen(url)
primary_area_dict = xmltodict.parse(primary_area)
# 県情報だけ抜き出し
pref_list = primary_area_dict["rss"]["channel"]["ldWeather:source"]["pref"]
# 変換してみる
pref_list = []
for pref_dict in pref_dict_list:
pref = serializePref(pref_dict)
if pref is not None:
pref_list.append(pref)
辞書に変換する間に、キーがいつのまにか @
付きになってたり、1件だけの場合はリストじゃなくて、いきなり単体の値になってたり、など諸々問題ありましたがなんとかやりました。
そもそもORマッパーとか探して使えよですが、まだまだPythonシロートなので許してください。
ちなみに、北海道だけ東西南北で別れてるので、県名を変換してあります。
市名から検索できるようにする
上記で変換した内容を使って、市名から検索かけれるようにしてみます。
def getPrefList():
# primary_areaのxmlファイルURL
url = "http://weather.livedoor.com/forecast/rss/primary_area.xml"
try:
# ファイル情報取得
primary_area = urllib2.urlopen(url)
# 辞書に変換
primary_area_dict = xmltodict.parse(primary_area)
# 県情報だけ抜き出し
pref_list = primary_area_dict["rss"]["channel"]["ldWeather:source"]["pref"]
if pref_list:
return pref_list
else:
return []
except Exception as e:
raise e
return []
def searchCity(city_name):
# 県情報を取得
pref_dict_list = getPrefList()
# 変換
pref_list = []
for pref_dict in pref_dict_list:
pref = serializePref(pref_dict)
if pref is not None:
pref_list.append(pref)
# 対象の市を検索する
for pref in pref_list:
for city in pref.city_list:
if city.name == city_name:
return city
return None
# 検索してみる
city = searchCity("大阪")
# 大阪府
print city.pref_name
# 大阪
print city.name
市名で検索するとか使いやすいのか謎ですけど、とりあえずはできました。
長くなってきたので、続きはまた後日!