Livedoorお天気Webサービスで遊ぶ
Livedoorのお天気Webサービス
(Livedoor Weather Web Service / LWWS)で遊んでみる。
仕様はこれ→お天気Webサービス仕様 - Weather Hacks - livedoor 天気情報
対応している地域をリストアップする
LWWSは全国142箇所の地域に対応している。
このXMLのcityタグを見ると分かる。→livedoor天気ならびにWeather Hacksに関するお知らせ - livedoor 天気情報
まずはこの142箇所の地域をリストアップしてみる。
以下のスクリプトを実行すると、
標準出力とforecastmap.txtに結果が出力される。
XMLの解析にはREXMLを使用した。
require 'open-uri' require 'kconv' require 'rexml/document' url = "http://weather.livedoor.com/forecast/rss/forecastmap.xml" wfile = "forecastmap.txt" doc = nil open(url){|f| doc = REXML::Document.new(f) } citys = Array.new citys = REXML::XPath.match(doc, "//city/attribute::title") id = 0 open(wfile, 'w'){|f| citys.each{|city| puts "%3d: #{city.to_s.tosjis}" % id+=1 f.puts city.to_s.tosjis } }
実行結果はちょっと長いけどこのようになる。
1: 稚内 2: 旭川 3: 留萌 4: 札幌 5: 岩見沢 6: 倶知安 7: 網走 8: 北見 9: 紋別 10: 根室 11: 釧路 12: 帯広 13: 室蘭 14: 浦河 15: 函館 16: 江差 17: 青森 18: むつ 19: 八戸 20: 秋田 21: 横手 22: 盛岡 23: 宮古 24: 大船渡 25: 仙台 26: 白石 27: 山形 28: 米沢 29: 酒田 30: 新庄 31: 福島 32: 小名浜 33: 若松 34: 水戸 35: 土浦 36: 宇都宮 37: 大田原 38: 前橋 39: みなかみ 40: さいたま 41: 熊谷 42: 秩父 43: 東京 44: 大島 45: 八丈島 46: 父島 47: 千葉 48: 銚子 49: 館山 50: 横浜 51: 小田原 52: 甲府 53: 河口湖 54: 富山 55: 伏木 56: 金沢 57: 輪島 58: 福井 59: 敦賀 60: 新潟 61: 長岡 62: 高田 63: 相川 64: 長野 65: 松本 66: 飯田 67: 静岡 68: 網代 69: 三島 70: 浜松 71: 名古屋 72: 豊橋 73: 岐阜 74: 高山 75: 津 76: 尾鷲 77: 大津 78: 彦根 79: 京都 80: 舞鶴 81: 大阪 82: 神戸 83: 豊岡 84: 奈良 85: 風屋 86: 和歌山 87: 潮岬 88: 岡山 89: 津山 90: 広島 91: 庄原 92: 松江 93: 浜田 94: 西郷 95: 鳥取 96: 米子 97: 下関 98: 山口 99: 柳井 100: 萩 101: 徳島 102: 日和佐 103: 高松 104: 松山 105: 新居浜 106: 宇和島 107: 高知 108: 室戸 109: 清水 110: 福岡 111: 八幡 112: 飯塚 113: 久留米 114: 大分 115: 中津 116: 日田 117: 佐伯 118: 長崎 119: 佐世保 120: 厳原 121: 福江 122: 佐賀 123: 伊万里 124: 熊本 125: 阿蘇乙姫 126: 牛深 127: 人吉 128: 宮崎 129: 延岡 130: 都城 131: 高千穂 132: 鹿児島 133: 鹿屋 134: 種子島 135: 名瀬 136: 那覇 137: 名護 138: 久米島 139: 南大東島 140: 宮古島 141: 石垣島 142: 与那国島
簡単なお天気情報を取得する
地域IDと予報日を指定して、お天気情報を取得する。
require 'open-uri' require 'kconv' require 'rexml/document' def get_weather(city = 1, day = 'today') return if city < 1 or 142 < city return if day != 'today' and day != 'tomorrow' and day != 'dayaftertomorrow' url = 'http://weather.livedoor.com/forecast/webservice/rest/v1' query = "?city=#{city}&day=#{day}" url += query title = "" telop = "" doc = nil open(url){|f| doc = REXML::Document.new(f) } doc.elements.each("lwws/title"){|e| title = e.text.tosjis } doc.elements.each("lwws/telop"){|e| telop = e.text.tosjis } puts "#{title}: #{telop}".tosjis end get_weather(63, 'tomorrow')
上記のスクリプトを実行した結果が以下。
東京都(ID63)の明日の天気が出力される。
東京都 東京 - 明日の天気: 曇時々晴
明日は今日学んだことを発展させて、
もう少し何かやってみるかも・・・しれない。
1月から12月の月末を表示する
出力結果が整うように、
%を使ってmonthのフォーマットを調整してみた。
標準出力の整形にはcenterも役に立つ。
require "date" today = Date.today puts today.year.to_s.center(18) puts "-" * 18 1.upto(12){|month| lday = Date.new(today.year, month, -1) month = "%2d" % month puts "#{month}月の最終日は#{lday.day}日" }
実行結果は以下。
2007 ------------------ 1月の最終日は31日 2月の最終日は28日 3月の最終日は31日 4月の最終日は30日 5月の最終日は31日 6月の最終日は30日 7月の最終日は31日 8月の最終日は31日 9月の最終日は30日 10月の最終日は31日 11月の最終日は30日 12月の最終日は31日
XMLをパースしたいのでREXMLの勉強中
ぶっちゃけまだ全然分からない。
ほんとに全然・・・。
XMLから抽出したい文字列があるのだけど、
それを実現することは適当な正規表現だけじゃ難しい。
また、正規表現でどうにかなったとしても、
それはすごく分かりづらい方法になってしまうと思う。
とても後から見返す気がおきないような・・・。
RubyにはREXMLというライブラリがあって、
今後もお世話になることがあるかもしれないので、
今の内に勉強しておこうと思う。
追記
何となくは使えるようになった。
一番役に立ったのがここ。→http://codezine.jp/a/article/aid/1329.aspx?p=3
次点がここ。→http://circle.cc.hokudai.ac.jp/tsagara/programing/rexml.html
REXMLで何かやろうと思ったときは、
まずこの2つをチェックしてみるのが早いと思う。