コマンドレットのパラメータを列挙してみる。2015の15日目の記事です。はじめに前々回と前回は、PowerShellによるWebスクレイピングの具体的手法についてまとめました。APIを用いるのが本道かと思います。APIを用いるお話です。APIというのは、その名の通り、プログラムからWeb上のデータを取得したり、何らかのサービスの機能を実行したりするための、呼び出し方式を定めた規約です。APIでは、HTTPリクエストに呼び出したい機能の内容を指定し、結果をHTTPレスポンスとして受け取るというのが一連の流れになります。APIの主な実装方式としてはSOAPとRESTがありますが、このうち、XMLでリクエストを組み立てるSOAPは最近は廃れてきた感じです。APIはNew-WebServiceProxyコマンドレットで対応しています。APIを指すことが殆どです。DELETE:データの削除)、操作に対するパラメータ=クエリストリング(GETの場合)もしくはリクエストボディ(POSTの場合)、結果の返却=HTTPレスポンス(JSON、XML等)となるのが基本です。RESTの呼び出しは基本的にステートレスなものとなります。要はセッション情報を持たない≒cookieを使わない、ってことです。APIを簡便に利用するためにInvoke-RestMethodコマンドレットが用意されています。3.0から)Invoke-RestMethodコマンドレットのパラメータ指定Invoke-RestMethodコマンドレットのパラメータについては、実は前々回に取り上げたInvoke-WebRequestコマンドレットと同じです(IEのパーサーを使うことはないので、-UseBasicParsingも無いですが)。APIの形式は前述の通りなので、利用するパラメータは限られてきます。パラメータ(連想配列あるいはJSONやXML等)となるかと思います。@{Authorization="認証情報"}のような指定も必要になることがあります。Invoke-RestMethodコマンドレットのレスポンスInvoke-RestMethodコマンドレットがInvoke-WebRequestコマンドレットと異なる最大のポイントは、レスポンス文字列の種類によって、自動的に出力オブジェクトの型が切り替わるところです。私の調べた限りでは以下のような対応になっているようです。APIでAEDの所在地情報を検索し、JSONで結果を得ることができます。-AutoSizeのようにします。ここで$responseには、JSON形式のデータをパースしてPSCustomObject化したデータが格納されるので、あとはFormat-Tableコマンドレットで見やすい形で出力してあげれば良いでしょう。結果はこんな感じです。MAP上で表示する」なんてこともできます。APIにQueryStringでパラメータ(経度、緯度)情報を渡しているところと、レスポンスから生成されたオブジェクトのプロパティ値をマップ表示の際のパラメータとして利用しているところに注目してください。APIの一種と考えて良いと思います。ここではこのブログのRSSを取得する例を示します。Format-ListDescriptionの加工がやや適当(HTMLタグっぽいところを削除して50文字に切り詰めてるだけ)ですが、少し見やすくしています。結果は以下のように表示されます。RSSの結果は、1エントリがXMLElement型のオブジェクトとして出力されるので、データの取扱いが比較的楽だと思います。APIの良い例がなかったので省略してますが、基本的には前回取り上げた、XHTMLをXMLとしてパースする方法と同じやり方です。Invoke-RestMethodの場合は[xml]型アクセラレータによる変換は不要で、いきなりXmlDocumentオブジェクトが得られます。現状の問題点レスポンスがコールバック関数つきのJSONP形式であるとかで、JSON、XML、RSS/ATOMのいずれの形式にも適合しない場合はプレーンテキストとして出力されてしまいます。その場合は、出力文字列を適宜加工した後に、[xml]型アクセラレータや、ConvertFrom-Jsonコマンドレット等により手動でオブジェクト化するようにしてください。その場合は敢えてInvoke-RestMethodを使わずInvoke-WebRequestで充分ですが。APIというのは大抵(特にPOSTの場合)、認証を要するのですが、最近よくあるのはTwitter等でもおなじみのOAuth認証です。ところがOAuth認証は結構めんどくさい処理で、何らかのライブラリを使わないとしんどいです。残念ながらPowerShellの標準コマンドレットには存在しないので、自前で頑張って書くか、既存のライブラリやコマンドを利用することになるかと思います。今回そこまで説明できませんでしたが、また機会があれば。2014の24日目の記事です。位置情報プラットフォーム」をPowerShellから呼び出して、位置情報(緯度、経度)を取得してみよう、という話になります。位置情報プラットフォーム」という機能が追加され、アプリケーションから現在位置情報(緯度、経度など)をAPIで取得できるようになっています。位置情報プラットフォームでは、位置情報をGPSがあればGPSから、なければWi-Fiの位置情報あるいはIPアドレスなどから推定して取得します。GPSがない場合でも位置情報を取得できる、いわば仮想GPSの機能がデフォルトで備わっているのがミソです。センサー&ロケーションプラットフォーム」というのがありましたが、OSデフォルト機能としては仮想GPSはありませんでした。Windowsというサードパーティー製アプリを追加すると仮想GPS使えたんですけどもね。位置情報プラットフォームをPowerShellで使うには、.NET4.0以上に含まれている、System.Device.Location名前空間配下に含まれるクラスの機能を用います。アセンブリ名としてはSystem.Deviceとなります。以下のような関数Get-GeoCoordinateを定義します。System.Deviceを実行して必要なアセンブリをロードする必要があります。関数本体ではまず、System.Device.Location.GeoCoordinateWatcherオブジェクトを生成します。位置情報プラットフォームにアクセスして、位置情報の変化を監視します。位置情報の変化を感知すると、PositionChangedイベントが発生し、取得した位置情報を、イベントハンドラの引数にGeoPositionChangedEventArgs<T>オブジェクトとして返します。PowerShellでは、.NETクラスのイベントを取得するには、Register-ObjectEventコマンドレットを用い、イベントを「購読」します。{処理内容}のようにして、イベントハンドラを記述するのが一般的です。今回は位置情報の変化の最初の一回(つまり、初期値の取得)さえPositionChangedイベントを捕まえればOKなので、-Actionは使用しません。代わりにWait-Eventコマンドレットを用い、初回のイベント発生を待機するようにしています。Wait-Eventコマンドレットは、当該イベントを示すPSEventArgsオブジェクトを出力します。PSEventArgsオブジェクトのSourceEventArgsプロパティには、当該イベントのイベントハンドラ引数の値(ここではGeoPositionChangedEventArgs<T>オブジェクト)が格納されているので、あとはそこから.Position.Locationと辿ることで、位置情報を格納したGeoCoordinateオブジェクトが取得できます。(注:あとで知ったんですけど、GeoCoordinateWatcherクラスには、同期的に位置情報を取得するTryStartメソッドというのがあって、これを使えばイベント購読は実は不要でした...まぁいっか)なお、関数のパラメータとしてLatitude(緯度)、Longitude(経度)を指定すると、現在位置ではなく、指定の位置を格納したGeoCoordinateオブジェクトを生成するようにしています。位置情報プラットフォームを有効にする」にチェックを入れておきます。あとはGet-GeoCoordinateをそのまま実行するだけです。Falseこのように現在位置が表示されるかと思います。いっても、緯度、経度が表示されたところでちゃんと取得できてるのかよく分からないので、以下のような簡単な関数(フィルタ)を定義しておきます。"http://maps.google.com/maps?q=$($_.Latitude),$($_.Longitude)"}このフィルタを使うと、指定の緯度経度周辺の地図を、標準のWebブラウザで開いたGoogleマップ上に表示してくれます。位置測定に用いたソースによってはkmオーダーでズレると思いますが、それでも何となく、自分がいる場所が表示されるのではないかと思います。先ほども書いたように、パラメータで任意の緯度、経度を指定することも可能です。位置情報プラットフォーム」を使って現在位置が取れるよ、という話でした。PowerShellでSystem.Device.Locationとかを使っているサンプルを見かけないので、何かの参考になれば幸いです。あとPowerShellでのイベントの扱い方についても復習になるかと。APIを呼び出して活用しよう、というようなネタを書くつもりだったんですが、長くなったんでまたの機会としましょう。@mutaguchiBooks書籍版。