前回までに紹介した機能で、PowerShell Seleniumを経由したMicrosoft Edgeの操作はほぼできるようになったはずだ。これだけで、人が行っていた操作のほとんどをPowerShellから実行できるようになっている。今回は、機能としては最後のひと押しとなる「JavaScriptの実行」について取り上げる。
→連載「PowerShell Core入門 - 基本コマンドの使い方」の過去回はこちらを参照。
JavaScriptが実行できれば実質的に何でもできる
前回までに紹介した機能は、PowerShell Seleniumを使うことで、PowerShellのコマンドレットからMicrosoft Edgeの制御を行えるというものだった。これだけでもかなりのWebページの操作を自動化できる。
それでは提供されていない機能についてはどうか。その場合、PowerShell Seleniumを使って任意のJavaScriptコードを実行することができる。つまり、Webブラウザの開発者ツールを使って自由にページを操作できるのと同じことが、PowerShellからも実行できるわけだ。
サンプルページをJavaScriptで書き換えていく
今回は「https://getbootstrap.com/docs/4.0/examples/sign-in/」をサンプルページとして利用する。このページを表示した後、JavaScriptを実行してサンプルページの内容を書き換えるといった操作を行う。
サンプルページを開発者ツールで調べておく。
Webページのコンテンツはbody要素がトップに位置していることが多い。body要素のXPathは「/html/body」だ。今回はこのbody要素を編集することにする。body要素は通常、Webページごとに1つしかないので、body要素を名前で取得するJavaScriptのコードを使っても十分なので、今回はその方法で実装する。
PowerShell SeleniumからJavaScriptを実行
早速PowerShell SeleniumからJavaScriptを実行してみよう。まず、Microsoft Edge WebDriverとMicrosoft Edgeの起動を行う。
PS C:\Users\daichi> webdriver_edge_start.ps1
Microsoft Edge WebDriverを起動します。
Microsoft Edge WebDriverの起動処理完了。
PS C:\Users\daichi> S
webdriver_edge_start.ps1は付録として稿末に記すので、そちらを参照していただければと思う。
続いて、Set-SeUrlコマンドレットでサンプルページをオープンする。
PS C:\Users\daichi> Set-SeUrl -Url https://getbootstrap.com/docs/4.0/examples/sign-in/
PS C:\Users\daichi>
PowerShell SeleniumからはInvoke-SeJavascriptコマンドレットを使うことでJavaScriptコードの実行を行える。ここでは次のようにInvoke-SeJavascriptコマンドレットを実行して、body要素に「style="background:black"」という属性を追加する処理を実行する。
PS C:\Users\daichi> Invoke-SeJavascript -Script '
>> e = document.getElementsByTagName("body");
>> e[0].setAttribute("style", "background:black");
>> '
PS C:\Users\daichi>
上記のようにInvoke-SeJavascriptコマンドレットを実行すると、サンプルページの表示が次のように変化する。JavaScriptコードを実行してbody要素に属性データを追加した結果が反映されていることがわかる。
動作確認が終わったらMicrosoft Edge WebDriverとMicrosoft Edgeを終了する。
PS C:\Users\daichi> webdriver_edge_stop.ps1
動作しているMicrosoft Edge WebDriverを終了します。
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
23 8.28 23.83 0.02 23616 1 msedgedriver
動作しているMicrosoft Edge WebDriverの終了処理完了。
PS C:\Users\daichi>
こんな感じで、PowerShell SeleniumからJavaScriptコードを実行させるのはとても簡単だ。
PowerShellスクリプトにまとめる
上記処理をPowerShellスクリプトにまとめると次のようになる。
# WebDriver起動
webdriver_edge_start.ps1
# サンプルページをオープン
Set-SeUrl -Url https://getbootstrap.com/docs/4.0/examples/sign-in/
# JavaScriptを実行
Invoke-SeJavascript -Script '
e = document.getElementsByTagName("body");
e[0].setAttribute("style", "background:black");
'
#webdriver_edge_stop.ps1
JavaScriptが得意であれば、PowerShell Seleniumのコマンドレットを使うのではなく、全部上記スクリプトのInvoke-SeJavascriptコマンドレットにJavaScriptで処理を書いてしまう方が簡単だろう。この処理はそれだけ強力なものだ。
PowerShellを使う場合にはこうしたPowerShell Seleniumのパワーに加えて、JavaScriptをそのまま使うことができ、さらに.NETの機能をそのまま使うことができるという利点がある。これでMicrosoft EdgeのみならずOS側の処理に関してもある程度の自動化を行えるわけで、かなり強力な自動化ツールとして利用できるようになる。
付録
webdriver_edge_start.ps1
#!/usr/bin/env pwsh
#========================================================================
# Microsoft Edge WebDriverを起動する
#========================================================================
#========================================================================
# 動作しているMicrosoft Edge WebDriverをすべて終了
#========================================================================
webdriver_edge_stop.ps1
#========================================================================
# Seleniumモジュールがない場合にはインストール
#========================================================================
if (-Not (Get-InstalledModule -Name Selenium 2> $Null)) {
'Seleniumモジュールをインストールします。'
Install-Module -Name Selenium -AllowPrerelease -Force
Get-InstalledModule -Name Selenium
}
#========================================================================
# Microsoft Edge WebDriverを起動
#========================================================================
'Microsoft Edge WebDriverを起動します。'
$Size = '1200,800'
if (-Not (Start-SeDriver -Browser Edge -Size $Size 2> $Null 3> $Null))
{
#================================================================
# Microsoft EdgeとMicrosoft Edge WebDriverのバージョンが一致して
# いないためにドライバが動作しなかった可能性がある。
#================================================================
#================================================================
# 不要なドライバプロセスを終了
#================================================================
webdriver_edge_stop.ps1
#================================================================
# Microsoft Edgeのバージョン番号
#================================================================
$EdgeDir='C:\Program Files (x86)\Microsoft\Edge\Application\'
$EdgeVersion=( Get-ChildItem -Name $EdgeDir |
Where-Object { $_ -NotMatch "[a-zA-Z]+" } |
Select-Object -First 1 )
# ↑ 【Select-Object -First 1の理由】
# 更新前のバージョンと更新後のバージョンが同時に
# 存在するタイミングがあるので、更新後のバージョン
# のみを取得するためにSelect-Objectを実行している。
#================================================================
# Microsoft Edge WebDriverダウンロードURLとデプロイ先パス
#================================================================
$DriverURL="https://msedgedriver.azureedge.net/$EdgeVersion/edgedriver_win64.zip"
$SeModVer=(Get-InstalledModule -Name Selenium).Version -replace "-.+$",""
$DriverDir="$env:HOME\Documents\powershell\Modules\Selenium\$SeModVer\assemblies"
$DriverDownloadDir="$DriverDir\_download"
#================================================================
# WebDriverダウンロード用の一時ディレクトリを作成
#================================================================
New-Item $DriverDownloadDir -ItemType Directory -Force
#================================================================
# Microsoft Edgeと同じバージョンのMicrosoft Edge WebDriverを
# ダウンロード
#================================================================
"Microsoft Edge WebDriver version $EdgeVersion をダウンロードします。"
curl -get `
-o $DriverDownloadDir\edgedriver_win64.zip `
$DriverURL
#================================================================
# Microsoft Edge WebDriverをデプロイ
#================================================================
"Microsoft Edge WebDriver version $EdgeVersion をインストールします。"
Expand-Archive -Path $DriverDownloadDir\edgedriver_win64.zip `
-Destination $DriverDownloadDir `
-Force
Copy-Item -Path $DriverDownloadDir\msedgedriver.exe `
-Destination $DriverDir\msedgedriver.exe `
-Force
#================================================================
# WebDriverダウンロード用の一時ディレクトリを削除
#================================================================
Remove-Item $DriverDownloadDir -Recurse -Force
#================================================================
# Microsoft Edge WebDriverを起動する
#================================================================
if (-Not (Start-SeDriver -Browser Edge -Size $Size 2> $Null 3> $Null))
{
#========================================================
# 原因不明の起動不能
#========================================================
#========================================================
# 不要なドライバプロセスを終了
#========================================================
webdriver_edge_stop.ps1
Exit
}
}
'Microsoft Edge WebDriverの起動処理完了。'
webdriver_edge_stop.ps1
#!/usr/bin/env pwsh
#========================================================================
# Microsoft Edge WebDriverを終了する
#========================================================================
#========================================================================
# WebDriverプロセスを終了
#========================================================================
if (Get-Process -Name msedgedriver 2> $Null)
{
'動作しているMicrosoft Edge WebDriverを終了します。'
Get-Process -Name msedgedriver 2> $Null
# Microsoft Edge WebDriverを終了
Stop-SeDriver 2> $Null
# まだ動作しているほかのMicrosoft Edge WebDriverを終了
if (Get-Process -Name msedgedriver 2> $Null)
{
Get-Process -Name msedgedriver 2> $Null | Stop-Process
}
'動作しているMicrosoft Edge WebDriverの終了処理完了。'
}