Ruby 天気予報編 (7) 天気予報 API へのアクセス 【計算数学 I】

更新日時:

天気予報 API へのアクセス

準備が終わり、やっと本題に入リます。天気予報 API を利用する段階にきました。

今回は Weather Hacks を使用します。 Hash を知り、 JSON を知った我々にとって、残る問題は、以下の 2 つです。

  1. 今回使用する API の仕様はいかなるものか
  2. Ruby で API にどうやってアクセスし、返り値を受け取るか

前者は、 Ruby の話ではありません。サービスを提供する側が決めた仕様を調べ、理解し、それに合わせて我々が実装するのみです。後者については、いくつか方法があります。前作の教材で open-uri モジュールを使ったので、今回はこれでいきます。

API の仕様 (リクエスト側)

今回の API の仕様書は

に書かれている通りです。仕様はサービスを提供する人が決めることなので、私が説明することはありません。これを読むしかないです。単純な API なので読めばすぐわかると思いますが、概要を箇条書きにします。

  • 情報を受け取るには、指定された URL にアクセスする。
  • URL の末尾には、我々が「リクエストを付与」する。今回の場合は、地域を番号で指定する。指定の仕方は自分でみる。例も挙げられている。

これは Ruby の練習ですから、ひとまず自分の好きな地域を 1 つ決めましょう。確認のためブラウザで URL にアクセスしてみましょう。JSON がブラウザに表示されていれば、このセクションはクリアです。

Ruby で URL にアクセスするには

今度は Ruby で URL に「アクセス」してみましょう。

API を利用すると言っても、結局 URL を指定して情報をダウンロードするだけですので、前回もやったように open-uri ライブラリを使って Kernel.#open でアクセスすればよいです。open についてこちらこちらに書きました。

前回説明していなかったこと: URL でアクセスした情報を文字列として受け取る際は read を使用します(StringIO#read)。例えば、

json = ""
open(url){|input|
  json = input.read
}

のようにすると、url にアクセスした先の情報を文字列として json に受け取ることができます。事前に json = "" としているので、ブロックの外で失われることはありません。

API の仕様 (返り値側)

返り値についても

に書かれている通りです。 JSON.parse でそのまま Hash に変換されます。 以下の説明では hash にこの JSON を変換したものが入っているとします。

天気予報 API は好きなように使えばよいと思います。好きなように使うヒントを述べておきます。

  • JSON.parse で変換したハッシュのキーは全て「文字列」です。シンボルではありません。
  • hash["forecasts"] は予報日毎に 配列 になっています。今日の天気にアクセスするならば hash["forecasts"][0] とアクセスする必要があります。
  • 最低気温、最高気温は空欄の可能性があります。次のセクションで、空欄の判定法を解説しています。

空欄の取り扱い

ある JSON を Hash にしたものを hash にいれているとします。 hash[key]key に対応する値が返ります。 ここでもし、以下の場合が起きたらどうなるでしょうか。

  • JSON 側で key に対応する項目がそもそもない
  • JSON 側で key に対応する項目は空欄である(注意:「空欄」と「空文字」は異なる)。

Ruby では、この場合、 hash[key]nil を返します。 nilNil クラスの唯一のインスタンスで、プログラム中どこで nil と書いても同じものを指します。さしあたっては「空欄」や「ないもの」を表すオブジェクトだと思っておけばよろしいです。

あるオブジェクトが nil であるかどうかを判定するメソッドは nil? です。返り値は true または false です。

以上を総合すると、 メソッド nil? を使うことにより、JSON の返り値が空欄かどうかを判定ができる ということになります。特に Ruby では、これは特徴的な考え方となっています。

API の利用規約

一般論になりますが、 API を利用する際は、利用規約をよく読みましょう。特に、以下の項目は重要です。

  1. 料金が発生するのか
    • 今回は無料。
  2. ユーザー認証が必要か
    • 今回は必要ない。
  3. どの程度の頻度でアクセスしてよいのか
    • ループしたり自動化したりして、アクセスの頻度が高くなりすぎると、返り値が返ってこないばかりか攻撃となりえる。
    • 今回はまず問題なかろう。
  4. 利用用途に制限はあるか
    • 今回はこれが重要。

Wether Hacks の Q&A を見ると、以下のように書かれています。

Q Weather Hacksの商用利用は可能でしょうか?

A 本サービスの情報を利用した、商用活動はご遠慮下さい。また、Weather Hacksが提供するデータは個人的な範囲でのご利用に留めて頂くようお願い致します。

今回は「Ruby の学習に使用する」のですから、商業利用ではありません。「Twitter で天気予報を試しに投稿する」が「個人的な範囲」を逸脱するかどうかは、一応議論の余地はあるかもしれませんが、先方から怒られることはないのではないでしょうか。

ここまでのプログラム

ここまでで、 Twitter に投稿する文章を作成することができるようになりました。標準出力に出してみましょう。ところどころ空欄にしています。

以下のプログラムでは、天気と、最高気温・最低気温を出力する文章にしてみましたが、皆さんは 自分の好きな項目 を文章にしましょう。ただし Twitter の投稿文は 140 字以内ですから、今のうちに、その文字数をオーバーしないような文章にまとめましょう。

コツ: 文章を練るときは、 irb を使うと楽 でしょう。具体的には、以下の requireget_weather() (もちろん空欄を埋めたもの) を irb にコピーアンドペーストして、 hash = get_weather() のようにしておきます。その後、 API の仕様を irb で、例えば "#{hash["forecasts"][0]["dateLabel"]}の天気" のように打ち込んでみます。すると「今日の天気」と返ってくるので、うまくいっていることがわかります。このようにしてプログラムを完成させていきます。

プログラム例

# coding: utf-8
require 'open-uri'
require 'json'

def get_weather()
  json = ""
  url = # 好きな地域の URL を入れる
  open(url){|input|
    json = input.read
  }
  # json を Hash に加工して return する。
end

def make_str(day)
  # 説明文で言うところの hash["forecast"][0] や
  # hash["forecast"][1] が引数の day に入る。
  str = # 「今日の天気は晴れ」のような文字列をここに書く。
  if # 最高気温欄が空欄でなければ
    maxi = day["temperature"]["max"]["celsius"].to_i
    str += "、最高気温は#{maxi}度"
  end
  # 最低気温についても同じことをする。
  str += "です。"
  return str
end

hash = get_weather()
ary = hash["forecasts"]
str = # 今日と明日の天気を結合する。
puts str + Time.now.strftime("(%H:%M:%S)") # 末尾に時刻を挿入してみた

出力例

今日の天気は晴時々曇、最高気温は30度です。明日の天気は雨、最高気温は23度、最低気温は20度です。(05:34:13)

ナビゲーション

この教材は、東京大学理学部数学科専門科目「計算数学 I」のために執筆されたものです。 このサイトに掲載する際に、記事を分けてあります。 他の回はRuby 天気予報編 一覧 #ks1-ruby-forecastから御覧ください。

Ruby 入門 (計算数学実習資料集)には他の TA が書いた教材があります。

コメントする