Edited at

OpenWeatherMap APIで取得したXMLを整形して表示。

More than 1 year has passed since last update.

 こんにちは、クイックイタレート株式会社の加藤 義也と申します。

 現在「始めるならpythonをおすすめする理由」というブログ記事を書いています。


やりたい事

事務所の天気予報をXMLで取得して整形して表示してみます。


環境


  • Windows10 Home

  • anaconda navigator 4.4.0

  • python 3.6.1


    • urllib --URLを指定してコンテンツを取得するライブラリ)

    • ElementTree --XMLファイルを解釈・変更するライブラリ




構成要素を考えて見ます。


  • 十分な情報を提供してくれるサービスを探す。

  • サービスの使い方を調査する。

  • リクエストを作る。

  • 取得したXMLから必要な情報を抽出する。

  • 抽出した情報をきれいに表示する。


お天気APIサービスの候補

「天気予報 API フリー」で検索してみると

以下のサービスが存在していることが分かりました。

- Livedoor お天気Webサービス

- OpenWeatherMap

今回は「OpenWeatherMap」を使ってみたいと思います。


API概要

OpenWeatherMapは様々な方法で詳細な情報が取得出来る様に構成されています。

抜粋して表にしてみます。

パラメータ
意味
値例
必須

URL
リクエストを送付する宛先

http://api.openweathermap.org/data/2.5/forcast?
必須

appid
割りあてられたID
必須 *1
必須

name
都市固有の名称
tokyo-to
オプション*2

id
都市固有のID(cityid)
1850144
オプション*2

lat
10進数表記の緯度
35.78
オプション*2

lon
10進数表記の緯度
139.83
オプション*2

zip
郵便番号
1210053
オプション*2

country
国名略称(zip指定時)
jp
オプション*2

unites
表記単位 *1
metric or imperial or 無し
オプション*2

mode
取得形式の指定
xml or json or html
オプション*2

*1 appidはこちらからユーザー登録後、こちらで取得出来ます。

*2 「name」「id」 か 「lat & lon」 か 「zip & contry」 で場所を指定する必要があります。

値例には弊社事務所の所在地を設定しておりますが実際には必要な場所をご指定ください。

cityid、countryの詳細な指定方法はこちらに記載されています。

APIの詳細はこちら(英語です。^^;)に記載されています。

リクエストURLのイメージ(Cityidを使った場合)

http://api.openweathermap.org/data/2.5/forecast?id=1850144&APPID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&units=metric&mode=xml

リクエストURLのイメージ(緯度・経度を使った場合)

http://api.openweathermap.org/data/2.5/forecast?lon=139.83&lat=35.78&APPID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&units=metric&mode=xml


pythonのコード

では情報が整ったところで早速pythonを使って情報を取得し、整形されたXMLの形で表示してみたいと思います。


openweathermap.py

#ライブラリのインポート

import urllib.request
import urllib.parse
import xml.etree.ElementTree as et
import xml.dom.minidom as md
url='http://api.openweathermap.org/data/2.5/forecast?' #基底URLの設定
query = {
'id' : '1850144' ,
'APPID' : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', #あなたが取得したappid
'units' : 'metric',
'mode' : 'xml'}#クエリに設定する値群
url = url + urllib.parse.urlencode(query) #リクエストURLの生成
response = urllib.request.urlopen(url) #httpリクエスト
root = et.fromstring(response.read()) #取得したコンテンツをXML Elementに格納

リクエストに使用したurlの中身を確認します。


生成されるurlを確認

print(url) #urlの中身を表示

http://api.openweathermap.org/data/2.5/forecast?id=1850144&APPID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&units=metric&mode=xml


xmlを表示するコード

document = md.parseString(et.tostring(root, 'utf-8')) #minidomモジュールが XML Elementをパース

print(document.toprettyxml(indent=" ")) #パースされたXML情報をインデント付きで文字列に変換して表示

リクエストで帰ってきた値を実際に整形されて出力されたXMLです。


result.xml

<?xml version="1.0" ?>

<weatherdata>
<location>
<name>Tōkyō-to</name>
<type/>
<country>JP</country>
<timezone/>
<location altitude="0" geobase="geonames" geobaseid="1850144" latitude="35.6895" longitude="139.6917"/>
</location>
<credit/>
<meta>
<lastupdate/>
<calctime>0.0129</calctime>
<nextupdate/>
</meta>
<sun rise="2017-06-23T19:26:28" set="2017-06-24T10:00:54"/>
<forecast>
<time from="2017-06-24T06:00:00" to="2017-06-24T09:00:00">
<symbol name="broken clouds" number="803" var="04d"/>
<precipitation/>
<windDirection code="SSE" deg="148.001" name="South-southeast"/>
<windSpeed mps="2.41" name="Light breeze"/>
<temperature max="24.68" min="23.88" unit="celsius" value="23.88"/>
<pressure unit="hPa" value="1015.57"/>
<humidity unit="%" value="66"/>
<clouds all="56" unit="%" value="broken clouds"/>
</time>
・・(途中省略)・・
</forecast>
</weatherdata>


次回はXMLの内容を抽出して加工してみたいと思います。


記事を書いた際、参考にさせて頂いたサイト等

ありがとうございます。