tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

PowerShellでGlobalWeatherから天気情報取得してみる

開始しようとして某星人に早々に答え言われました ( めげずに見たところ、返ってきたデータが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

参考サイト

PowerShell – 国の主要な都市を取得する [PowerShell V2 CTP3] try – catch – finally 連想配列を変換してユーザー定義オブジェクトを簡単に作成する ハッシュテーブルからカスタムオブジェクトへのキャスト(V3) 作ってから以下のサイトもあることに気づきしょぼーん。 Hey, Scripting Guy! Web サービスを使用して特定の都市の天気を確認する方法はありますか