PowerShell で天気取得…っていうか、割と REST → DynamicJson あたりのコンボで何も考えなくてもいい気がするけど
— だるじろうさん (@takeshik) 2013年1月29日
めげずに見たところ、返ってきたデータがXMLだったのでJsonにはしてませんが一応できました。
もしPowerShellでJsonする場合は、以下が参考になります。
PowerShellでJScript.NETを利用してJSONをパースする
取得サイト
定番ですが、GlobalWeatherから取得しました。GlobalWeather
コマンドレット
定番ですが、New-WebServiceProxyを使いました。New-WebServiceProxy
国、都市の取得
天気はGetWeatherから取得出来るのですが、City,Coutryが必要とのこと。 まずは都市の一覧をGetCitiesByCountry取得します。$web = New-WebServiceProxy -Uri http://www.webservicex.net/globalweather.asmx $web.GetCitiesByCountry("Japan") ` | %{([xml]$_).NewDataSet.Table} ` | sort City
Function化
流用したいので、以下のfunctionに書き直してっと。 ※恐らく日本人が見るでしょうから、デフォルト値をJapanにしています。function Get-CityCountry{ [CmdletBinding()] param( #引数がなかった場合はJapanを指定 [parameter (Position=0,ValueFromPipeline=$true)] [string]$Country="Japan" ) begin{ $web = New-WebServiceProxy -Uri http://www.webservicex.net/globalweather.asmx } process{ $web.GetCitiesByCountry($Country) ` | %{([xml]$_).NewDataSet.Table} ` | sort City } }これで、以下の一文でその国の都市一覧が取得できます。
Get-CityCountry -Country Japanアメリカを取得するなら以下です。
Get-CityCountry -Country "United States"イギリスを取得するなら以下です。
Get-CityCountry -Country "United Kingdom"
取得結果例
Japanの取得結果です。Country City ------- ---- Japan Akeno Ab Japan Akita Airport Japan Amami Airport Japan Aomori Airport Japan Asahikawa Ab Japan Asahikawa Airport Japan Ashiya Ab Japan Atsugi United States Naval Air Station Japan Chichijima Japan Chitose Ab Japan Chitose Japanese Air Self Defense Force Japan Chofu Airport Japan Fuji Ab Japan Fukue Airport Japan Fukui Airport Japan Fukuoka Airport Japan Fukushima Airport Japan Futenma Marine Corps Air Facilit Japan Gifu Ab Japan Hachijojima Airport Japan Hachinohe Ab Japan Hakodate Airport Japan Hamamatsu Ab Japan Hamby U. S. Army Airfield Japan Hanamaki Airport Japan Hiroshima Airport Japan Hofu Ab Japan Hyakuri Ab Japan Ichikawa Japan Iejima Auxiliary Ab Japan Iki Airport Japan Iruma Ab Japan Ishigakijima Japan Iwakuni Marine Corps Air Station Japan Iwami Airport Japan Iwojima Japan Izumo Airport Japan Kadena Ab Japan Kagoshima Airport Japan Kamigoto Japan Kanoya Ab Japan Kansai International Airport Japan Kasumigaura Ab Japan Kasuminome Ab Japan Kikai Island Japan Kisarazu Ab Japan Kitakyushu Airport Japan Kochi Airport Japan Komatsu Ab Japan Komatsujima Ab Japan Kumamoto Airport Japan Kumejima Japan Kushiro Japan Kushiro Airport Japan Matsumoto Airport Japan Matsushima Ab Japan Matsuyama Airport Japan Memambetsu Airport Japan Metabaru Ab Japan Miho Ab Japan Minamidaitojima Japan Minamitorishima Japan Misawa Ab Japan Miyakejima Airport Japan Miyakojima Japan Miyazaki Airport Japan Mombetsu Airport Japan Muroran Japan Nagasaki Airport Japan Nagoya Airport Japan Naha Airport Japan Nakashibetsu Airport Japan Nankishirahama Airport Japan New Tokyo Inter-National Airport Japan Niigata Airport Japan Nyutabaru Ab Japan Obihiro Airport Japan Oita Airport Japan Ojika Island Japan Okayama Airport Japan Oki Airport Japan Okinoerabu Japan Okushiri Island Japan Ominato Ab Japan Osaka International Airport Japan Oshima Airport Japan Ozuki Ab Japan Rebun Island Japan Rishiri Island Japan Sado Airport Japan Sapporo Ab Japan Sasebo Usn Japan Sendai Airport Japan Shimofusa Ab Japan Shizuhama Ab Japan Tachikawa Ab Japan Tajima Japan Takamatsu Airport Japan Tanegashima Airport Japan Tateyama Ab Japan Tokachi Japanese Ground Self Defense Force Japan Tokunoshima Island Japan Tokushima Ab Japan Tokyo Japan Tokyo Heliport Japan Tokyo International Airport Japan Tottori Airport Japan Toyama Airport Japan Tsuiki Ab Japan Tsushima Airport Japan Utsunomiya Ab Japan Wakkanai Airport Japan Yakushima Japan Yamagata Airport Japan Yamaguchi Ube Airport Japan Yao Airport Japan Yokosuka Fwf Japan Yokota Ab Japan Yonaguni Airport Japan Zama Airfield
天気の取得
ここまで来れば簡単で、GetWeatherから天気を取得してみます。$web = New-WebServiceProxy -uri http://www.webservicex.net/globalweather.asmx [xml]$xml = $web.GetWeather("Tokyo","Japan") $xml.CurrentWeather
取得結果例
取得結果が英語ですね…。Location : Tokyo International Airport, Japan (RJTT) 35-33N 139-47E 8M Time : Jan 29, 2013 - 12:30 AM EST / 2013.01.29 0530 UTC Wind : from the W (270 degrees) at 7 MPH (6 KT) (direction variable):0 Visibility : greater than 7 mile(s):0 SkyConditions : mostly clear Temperature : 53 F (12 C) DewPoint : 10 F (-12 C) RelativeHumidity : 17% Pressure : 30.12 in. Hg (1020 hPa) Status : Success嫌がりそうな人が多そうなので、日本向けにでカスタムオブジェクトを生成しましょう。 表題の日本語化、温度の摂氏のみ表示、気圧にhPaのみの表示と行ったところでしょうか。
#Requires -Version 3 $web = New-WebServiceProxy -uri http://www.webservicex.net/globalweather.asmx [xml]$xml = $web.GetWeather("Tokyo","Japan") $xml.CurrentWeather ` | %{ $object = [psCustomObject]@{ 場所=$_.Location; 時刻=$_.Time; 風向=$_.Wind; 視程=$_.Visibility; 天候=$_.SkyConditions; 温度=$_.Temperature -replace "([\d].|[\d]|[\d]{2}.[\d])[' ']F[' '][(]","" -replace "[)]",""; 露点温度=$_.DewPoint -replace "([\d].|[\d]|[\d]{2}.[\d])[' ']F[' '][(]","" -replace "[)]",""; 湿度=$_.RelativeHumidity; 気圧=$_.Pressure -replace "[\d].[.][\d].[' ']in[.][' ']Hg[' '][(]","" -replace "[)]","" } $object }日本語結果は、こんな感じで。
場所 : Tokyo International Airport, Japan (RJTT) 35-33N 139-47E 8M 時刻 : Jan 29, 2013 - 01:00 AM EST / 2013.01.29 0600 UTC 風向 : from the SSW (200 degrees) at 13 MPH (11 KT):0 視程 : greater than 7 mile(s):0 天候 : mostly clear 温度 : 11 C 露点温度 : -7 C 湿度 : 27% 気圧 : 1020 hPa先ほどのGet-CityCountry と組み合わせると各都市の取得も簡単ですね。
#Requires -Version 3 $CityCountry = Get-CityCountry $CityCountry ` | %{ $web.GetWeather($_.City,$_.Country) ` | %{ $xml = [xml]$_ $xml.CurrentWeather ` | %{ $object = [psCustomObject]@{ 場所=$_.Location; 時刻=$_.Time; 風向=$_.Wind; 視程=$_.Visibility; 天候=$_.SkyConditions; 温度=$_.Temperature -replace "[\d].[' ']F[' '][(]","" -replace "[)]",""; 露点温度=$_.DewPoint -replace "[\d].[' ']F[' '][(]","" -replace "[)]",""; 湿度=$_.RelativeHumidity; 気圧=$_.Pressure -replace "[\d].[.][\d].[' ']in[.][' ']Hg[' '][(]","" -replace "[)]","" } $object } } } | Format-Table
Function化
さて、せっかくなので流用できるように日本語版をFunction化します。Fukui Airportを初めとして、いくつかの都市がNo Data Found返すため、[xml]キャストに失敗します。 Fukue Airportって長崎県五島市にある地方管理空港はでるのに…って、福井空港は定期便が…… ( これらに関してはtry~catch~finallyで例外処理しています。
#Requires -Version 3 function Get-Weather{ [CmdletBinding()] param( [parameter (Position=0,Mandatory=$true,ValueFromPipeline=$true)] [string]$City, [parameter (Position=1,Mandatory=$true,ValueFromPipeline=$true)] [string]$Country ) begin{ if ($web -eq $null) { $web = New-WebServiceProxy -uri http://www.webservicex.net/globalweather.asmx } } process{ $web.GetWeather($City,$Country) ` | %{ try {$xml = [xml]$_ } catch [Exception] { $Error = $_.Excption.Message #Data Not Foundの際にスキップ } finally { $xml.CurrentWeather ` | %{ $object = [psCustomObject]@{ 場所=$_.Location; 時刻=$_.Time; 風向=$_.Wind; 視程=$_.Visibility; 天候=$_.SkyConditions; 温度=$_.Temperature -replace "([\d].|[\d]|[\d]{2}.[\d])[' ']F[' '][(]","" -replace "[)]",""; 露点温度=$_.DewPoint -replace "([\d].|[\d]|[\d]{2}.[\d])[' ']F[' '][(]","" -replace "[)]",""; 湿度=$_.RelativeHumidity; 気圧=$_.Pressure -replace "[\d].[.][\d].[' ']in[.][' ']Hg[' '][(]","" -replace "[)]","" } $object } } } } }これで、以下の一文でその都市の天気が取得できます。
Get-Weather -City Tokyo -Country Japan
まとめ
New-WebServiceProxyの利用によるWeb Serviceの練習になりました。 2つのFunctionを組み合わせれば、一文で各国のそれぞれで天気を一覧取得できます。#Requires -Version 3 function Get-CityCountry{ [CmdletBinding()] param( #引数がなかった場合はJapanを指定 [parameter (Position=0,ValueFromPipeline=$true)] [string]$Country="Japan" ) begin{ $web = New-WebServiceProxy -Uri http://www.webservicex.net/globalweather.asmx } process{ $web.GetCitiesByCountry($Country) ` | %{([xml]$_).NewDataSet.Table} ` | sort City } } function Get-Weather{ [CmdletBinding()] param( [parameter (Position=0,Mandatory=$true,ValueFromPipeline=$true)] [string]$City, [parameter (Position=1,Mandatory=$true,ValueFromPipeline=$true)] [string]$Country ) begin{ if ($web -eq $null) { $web = New-WebServiceProxy -uri http://www.webservicex.net/globalweather.asmx } } process{ $web.GetWeather($City,$Country) ` | %{ try {$xml = [xml]$_ } catch [Exception] { $Error = $_.Excption.Message #Data Not Foundの際にスキップ } finally { $xml.CurrentWeather ` | %{ $object = [psCustomObject]@{ 場所=$_.Location; 時刻=$_.Time; 風向=$_.Wind; 視程=$_.Visibility; 天候=$_.SkyConditions; 温度=$_.Temperature -replace "([\d].|[\d]|[\d]{2}.[\d])[' ']F[' '][(]","" -replace "[)]",""; 露点温度=$_.DewPoint -replace "([\d].|[\d]|[\d]{2}.[\d])[' ']F[' '][(]","" -replace "[)]",""; 湿度=$_.RelativeHumidity; 気圧=$_.Pressure -replace "[\d].[.][\d].[' ']in[.][' ']Hg[' '][(]","" -replace "[)]","" } $object } } } } }以下の一文で天気情報を取得出来ます。
Get-CityCountry -Country "Japan" | %{ Get-Weather -City $_.City -Country $_.Country } | Format-Tableあるいはリスト表示もいいですね。
Get-CityCountry -Country "Japan" | %{ Get-Weather -City $_.City -Country $_.Country } | Format-List