LoginSignup
4
8

More than 3 years have passed since last update.

selenium-powershellを使ってWindows上で環境構築せずにWebスクレイピングする備忘録

Posted at

初めに

Windowsで面倒な環境構築をせずにSeleniumでスクレイピングがしたい。
最近はWSL2でdockerコンテナを動かせば簡単にseleniumの環境構築もできると思いますが、会社の環境だとできなかったりするのでもっとお手軽にやりたいと思いました。

というわけで調べたところPowerShell用のSeleniumモジュールがあったので使用してみることに。
大まかな使いかたをまとめました。

私自身それほどSeleniumに関して詳しくないので使用していてわかった事があれば
随時追記していこうと思います。
もっと良いコマンドの使用方法など指摘あればコメント頂けると幸いです。

環境

PowerShellのバージョン

$PSVersionTable

Name                           Value                                                                                  
----                           -----                                                                                  
PSVersion                      5.1.19041.1                                                                            
PSEdition                      Desktop 
...

Seleniumモジュールのバージョン

Get-InstalledModule -Name selenium

Version              Name                                Repository           Description                             
-------              ----                                ----------           -----------                             
3.0.1                Selenium                            PSGallery            Web automation using the Selenium Web...

現在(2020年10月)時点ではバージョン3.0.1が最新ですがもう少しでバージョン4が出そうです。
バージョン4が出たら随時更新したいと思います。

Chromeのバージョン

Chromeのバージョン.png

実際に使ってみる

モジュールのインストール

下記コマンドで最新のモジュールをインストールできます。
インストールさえしてしまえばもうSeleniumでスクレイピングできます。

Install-Module -Name Selenium

ブラウザを起動する

起動コマンドレットとそのパラメーター

ブラウザを起動するにはStart-SeChromeなどStart-Se<ブラウザ名>を使用します。
下記は主に使うパラメーターを抜粋しています。

Start-SeChrome
   [-Headless]                    #ブラウザ非表示
   [-Maximized]                    #全画面
   [-DefaultDownloadPath <String>] #ダウンロード時のパス指定
   [-StartURL <String>]            #起動時に開くURL

基本的な仕様

ブラウザ起動時には$Driver = Start-SeChromeとして変数$Driverへ格納しますが
これは他のコマンドレットのパラメーターでドライバーを指定する際に必須となるので
決まり文句としてどのブラウザを使用する場合でも実施しています。

$Driverは別ページへ推移したりブラウザの更新があると勝手に更新されます。(仮に手動で別ページへ推移させたとしても変数は勝手に更新されます。)
ブラウザの更新が完了した時点でのHTMLが自動取得されるので、更新を待つようなループ処理を作成する必要がありません。

各ブラウザ毎のコマンドレット

Chromeを使用する場合

$Driver = Start-SeChrome

Edgeを使用する場合

$Driver = Start-SeEdge

Firefoxを使用する場合

$Driver = Start-SeFirefox

IEを使用する場合

$Driver = Start-SeInternetExplorer

ここではまった事

いつも通り$Driver = Start-SeChromeを実行するとエラーになりました。
Chromeをアップデートした後に発生したのでバージョンを確認して、対応するChromeDriverをダウンロードしなおしたら正常に動作しました。
ダウンロードはこちら

どうやらChromeのバージョンとChromeDriverのバージョンはそろえる必要があるようです。
私の環境では下記にのドライバーを更新しました。
C:\Users\ユーザ名\Documents\WindowsPowerShell\Modules\Selenium\3.0.1\assemblies\chromedriver.exe

指定のURLへ移動

Enter-SeUrl -Url '<URL>' -Driver $Driver

指定したURLへ推移し、ブラウザの更新が完了した時点の情報が$Driverに格納されます。

エレメントの取得

エレメントの取得にはFind-SeElementコマンドレットを使用します。
このコマンドレットは条件に合致したエレメントをオブジェクトの配列で返します。
(もしエレメントが見つからない場合は10秒でタイムアウトし、何も出力せず終了します。)

例えばdivをすべて取得する場合はFind-SeElement -Driver $Driver -TagName 'div'とすればすべてのdivタグが配列として返されます。
配列で返されるので(Find-SeElement -Driver $Driver -TagName 'input')[3]のようにインデックスでエレメントを指定もできます。

エレメントを取得した際に返されるオブジェクトのプロパティについて。

Find-SeElement -Driver $Driver -TagName div | ?{$_.Text -ceq 'ログイン'}

WrappedDriver                        : OpenQA.Selenium.Chrome.ChromeDriver
TagName                              : div
Text                                 : ログイン
Enabled                              : True
Selected                             : False
Location                             : {X=0,Y=20}
Size                                 : {Width=1261, Height=0}
Displayed                            : True
LocationOnScreenOnceScrolledIntoView : {X=0,Y=20}
Coordinates                          : OpenQA.Selenium.Remote.RemoteCoordinates

これらプロパティはPowerShellのその他のオブジェクトと同様にパイプラインで渡すことで、フィルタリングできます。(上記ではTextプロパティをWhere-Objectでフィルタリングしています。)

下記のようにさらに複雑な条件でフィルタリングできます。(ただし低速)

Find-SeElement -Driver $Driver -TagName div | ?{
    $_.Displayed -eq $TRUE -and
    $_.Text -ceq 'hogehoge' -and
    $_.Location.X -eq 0
}

全てのエレメントを取得

Find-SeElement -Driver $Driver -TagName *

これは確かにすべてのエレメントを取得できますが、その後パイプラインで渡してWhere-Objectによるフィルタリングをする必要があります。それは非常に低速なのでお勧めしません。

下記に記載している各種パラメーターを使用し、ある程度フィルタリングした後にWhere-Objectによるフィルタリングをするのが無難と思われます。

XPathで取得

idやclassあるなしにかかわらずドンピシャでエレメントを指定できます。
idがあってもなくても正確に取得できますのでこれでほとんど事足りると思います。

Find-SeElement -Driver $Driver -XPath '<XPath>'

IDで取得

ドンピシャで指定できるのでidがある場合はこれを使用すればよいと思います。

Find-SeElement -Driver $Driver -Id '<ID>'

TagNameで取得

これで大雑把にフィルタリングしてから詳細な条件でフィルタリングしたい場合などによく使用します。

Find-SeElement -Driver $Driver -TagName '<Tagname>'

例えばliタグでテキストが「hogehoge」であるエレメントを取得したい場合は下記のようにします。

Find-SeElement -Driver $Driver -TagName 'li' | ?{$_.Text -ceq 'hogehoge'}

ClassNameで取得

Find-SeElement -Driver $Driver -ClassName 'hogehoge'

特定のテキストを含むエレメントを全て取得(低速なので非推奨)

Find-SeElement -Driver $Driver -TagName * | ?{$_.Text -ceq 'hogehoge'}

特定のテキストを含むdivを取得

Find-SeElement -Driver $Driver -TagName 'div' | ?{$_.Text -ceq 'hogehoge'}

特定の属性値を持つdivを取得

下記はclass属性の値が「hogehoge」であるエレメントを取得しています。

Find-SeElement -Driver $Driver -TagName div | ?{$_.GetAttribute('class') -ceq 'hogehoge'}

正規表現を使用したい場合は比較演算子を-matchとするだけです。-cmatchとしているのは大文字小文字を区別させるためです。

Find-SeElement -Driver $Driver -TagName div | ?{$_.GetAttribute('class') -cmatch '^hogehoge$'}

特定のエレメント配下のエレメントを取得

下記は配下の更に配下のように再帰的にすべてのエレメントを取得しているわけではありません。
あくまでもid="hogehoge"直下のエレメントのみ取得しています。
XPathでエレメントを指定してその配下を/*としているだけです。もっといい方法がありそう。。

Find-SeElement -Driver $Driver -XPath '//*[@id="hogehoge"]/*'

取得したエレメントに対する操作

下記例にて記載されている$Elementには
$Element = Find-SeElement -Driver $Driver -Id '<ID>'などで一つのエレメントが取得されているものとします。

取得したエレメントの属性値を取得する

下記はclass属性の値を返します。

$Element.GetAttribute('class')

キーボード入力

通常文字列

Send-SeKeys -Element $Element -Keys 'hogehoge'

特殊キー

下記はEnterキーの場合

Send-SeKeys -Element $Element -Keys '{{ENTER}}'
Send-SeKeys -Element $Element -Keys ([OpenQA.Selenium.Keys]::Enter)

クリックする

下記2つはどちらも通常のクリック。
同じ動作をするはず。。

$Element.Click()
$Element | Invoke-SeClick -Driver $Driver 

JavaScriptでクリック

$Element | Invoke-SeClick -JavaScriptClick -Driver $Driver 

スクリーンショットを保存する

$Screenshot = Invoke-SeScreenshot -Target $Driver
Save-SeScreenshot -Screenshot $Screenshot -Path ./test.png

-Pathパラメーターで任意のフォルダへ保存できます。

終了して閉じる

Stop-SeDriver -Driver $Driver

参考

GitHub : selenium-powershell

4
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
8