---
PowerShellを使うと、Invoke-WebRequestを使うことで、特にライブラリ等を準備せずともWebページをスクレイピングすることができる(参考:PowerShellでスクレイピング 後編 HTMLをパースする) 。
これはこれで便利なのだが、少し複雑なHTMLになると、Where-ObjectやSelect-Objectがだんだん増えてきてしまう。こんな感じである。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$res = Invoke-WebRequest $url | |
$resultItems = $res.ParsedHtml.getElementsByTagName("div") | Where-Object { $_.getAttributeNode("class").Value -eq "result-item" } | |
$itemLinks = $resultItems[0].getElementsByTagName("a") | Where-Object { $_.pathname -ilike "list/*" } |
やっぱりDOMツリーをたどるなら使い慣れたCSSセレクタの記法が使いたいよね?ということで、今回はCSSセレクタが使える.NET用HTMLパーサライブラリ「AngleSharp」をPowerShellから使ってみるお話。本当はC#で馴染みのあったCsQueryを使おうと思ったのだけど「Not Actively Maintained」ということでAngleSharpにしてみた。
インストール
例によって適当なフォルダに移動してnuget.exeを使ってダウンロードする。> nuget install AngleSharp
使い方
初期化
まず、AngleSharp.dllをロードし、loaderが設定されたconfigを使って、BrowsingContextを作っておく。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add-Type -Path .\AngleSharp.0.9.3\lib\net45\AngleSharp.dll | |
$config = [AngleSharp.ConfigurationExtensions]::WithDefaultLoader([AngleSharp.Configuration]::Default) | |
$ctx = [AngleSharp.BrowsingContext]::New($config) |
このBrowsingContextを使っていく。
GETリクエスト
シンプルにGETリクエストを出すには、文字列のURLを使ってOpenAsyncを呼び出す。そして返ってきたものに対して、最初に一致したものだけでよければQuerySelector()を、全て欲しい場合はQuerySelectorAll()を呼び出す。例として、このブログの右側の「ブログ アーカイブ」の一番上のタイトル(画像参照)を取得するにはこんな感じである。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PS > $doc = [AngleSharp.BrowsingContextExtensions]::OpenAsync($ctx, "http://d.sunnyone.org").Result | |
PS > $elem = $doc.QuerySelector("#ArchiveList ul.posts li a") | |
PS > $elem.TextContent | |
Loqui 0.6.4 リリース |
~Asyncは、流儀通りTask<T>が返ってくる。PowerShell世界では扱いに困るのでResultでひたすらブロックしていく(ひどい)
ほぼ同じであるが、もう一つの例として@mutaguchiさんのブログPowerShell Scripting Weblogの右側にあるMVPのタイトルを取得するにはこんな感じである。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PS > $doc = [AngleSharp.BrowsingContextExtensions]::OpenAsync($ctx, "http://winscript.jp/powershell/").Result | |
PS > $elem = $doc.QuerySelector('#RMENU a[href*="mvp.microsoft.com"]') | |
PS > $elem.TextContent.Trim() | |
Microsoft MVP for Cloud and Datacenter Management July 2004-June 2016 |
各ブラウザの開発者ツール(F12)のコンソールで、document.querySelector('#ArchiveList')などとして、先に試しておくとよい。
POSTリクエスト
POSTにするには、OpenAsync()の第2引数にリクエストオブジェクトを生成する。POSTリクエストを作る便利メソッドはいくつかあり、例えばPostAsUrlEncodedを使うとこんな感じである。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$qparam = New-Object 'System.Collections.Generic.Dictionary[[string],[string]]' | |
$qparam.Add("key1", "value1") | |
$req = [AngleSharp.Network.DocumentRequest]::PostAsUrlencoded("http://www.example.jp/", $qparam) | |
$doc = [AngleSharp.BrowsingContextExtensions]::OpenAsync($ctx, $req, [System.Threading.CancellationToken]::None).Result |
$docができたら、あとはGETと同様に、QuerySelector()やQuerySelectorAll()を呼び出せばOKである。
0 件のコメント:
コメントを投稿