初めまして。NakamuraBlog運営者の nkmrです。
selenium×VBAについてGoogle検索しても 的外れなサイトが多かったので、
自分用のメモとして本記事を作成するに至りました。
ぜひブックマークをして利活用ください。
せっかくだから、そこから網羅的に書いています。
必要な箇所を飛び飛びで ピックアップして ご利用くださいませ。
非表示にできる< 目次 >
VBAでSeleniumを利用するためのセットアップ
Selenium Basic をインストール
まずは以下の手順で PCに Selenium Basic をインストールしましょう。
step
1SeleniumBasicをダウンロード
GitHubの公式ページから 「SeleniumBasic-2.0.9.0.exe」 をダウンロードしましょう。
メモ:SeleniumBasicダウンロードURL
step
2SeleniumBasicをインストール
ダウンロードした「SeleniumBasic-2.0.9.0.exe」をインストールしましょう。
ここでのポイント
SeleniumBasic がインストールされるフォルダURL(ディレクトリ情報)をメモっときましょう。
step
3SeleniumBasicがインストールされたフォルダを確認
インストールされた SeleniumBasicフォルダを開いて待機しておきましょう。
ChromeDriverのセットアップ
step
1まずは利用中のChromeバージョンを確認
利用中のChromeバージョンに対応した ChromeDriver をダウンロードする必要があるため、まずは確認しましょう。
はてな
◆質問◆
Chromeバージョンが「89.x.xxxx.xx」ってあるけど、xは何ですか?
◆回答◆
xの部分は、マイナーバージョンと呼びます。一方、記事内の89の箇所は メジャーバージョンと呼びます。
Chromeに限らず、EXCELでも、アプリのバージョン構成は「メジャーバージョン+マイナーバージョン」で表現されることが多いです。
で、今回使用するのは メジャーバージョン なので、そこの箇所を記憶しておいてください。
step
2ChromeDriverをダウンロード
ダウンロートサイトから 「Chrome Driver」 をダウンロードしましょう。
この際の注意点は Chromeのメジャーバージョンに合った ChromeDriverをダウンロードしてください。
メモ:ChromeDriverダウンロードURL
注意
Windows 64bit版のPCを利用している方も「chromedriver_win32.zip」をダウンロードしてください。
Windows 64bit用のChromeDriverは、現在 存在しません。でも、問題なく動作するので安心してください。
step
3ダウンロードしたZipファイルを開き、SeleniumBasicのフォルダへ移す
SeleniumBasicフォルダ内に 既に存在する「chromedriver.exe」を置き換える形で、
先ほど ダウンロードした ChromeDriver を移し替えて下さい。
VBE側-参照設定
最後に、EXCEL-VBE側の参照設定を更新しておきましょう。
ポイント
「Selenium Type Library」にチェックを入れて設定を完了させましょう。
主に、画像を見てもらえれば 直感的に分かってくれるかなと。
次項からは 動作確認をしていきます。
Seleniumの動作検証
Yahooを表示してみる
伝統的な動作確認方法である「Yahoo!」のWebページを表示させてみましょう。
VBE上に新規プロシージャを作って、以下のコードをコピペしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Sub Selenium動作検証_Yahoo表示() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") 'YahooのURLを開く driver.Get ("https://yahoo.co.jp") 'Seleniumの一時停止 (キーボード:F5を押せば処理再開して、自動でChromeが閉じます。) Stop End Sub |
この画面が出れば、動作確認はOKです。
この画面が表示されていればOK
もし動作しなかったら後述する方法を試して見てください。
エラーが起きたら
実行環境は PCによってバラバラですから、もしかしたらエラーが発生するかもしれません。
一応 僕が経験したエラー内容と解決方法について後述しますね。
想定されるエラー内容
- ChromeDriverのバージョンが、Chromeのメジャーバージョンと合致していない。
- 「実行時エラー ‘-2146232576(80131700)’ オートメーション エラーです。」 が表示される
エラー対処①:ChromeDriverのバージョンを確認しよう
ChromeDriverのバージョンとChromeブラウザのバージョンと不一致の可能性があります。
その場合、本記事内にある「ChromeDriverのセットアップ」を再度試してください。
もしかしたら、読み飛ばしている人もいると思いますので、念のために記載しておきます。
ココに注意
ChromeDriverのバージョンを確認しよう。
エラー対処②:NET Frameworkをインストールしよう
もしかしたら、このような画面が表示されているかもしれません。
こんなエラー表示
エラー文言:実行時エラー ‘-2146232576(80131700)’ オートメーション エラーです。
この場合の対処方法は、NET Framework をインストールすれば解決できるかもしれません。
NET Framework のインストール方法は以下の記事にまとめてますので、こちらを参照ください。
-
【VBA】Seleniumのオートメーションエラー解消方法【画像説明】
続きを見る
ココに注意
NET Frameworkが未インストールの可能性が有。
Seleniumコーディング時の ひな形(★重要)※本記事利用の前提条件でもあり
さて、記事タイトル通りに、Seleniumリファレンス系に突入していきます。
筆者自身の備忘止めも兼ねており、ブックマークして利活用する予定で、
ちゃんとしたものを作りたく…。
本記事の読者の方は、ほぼ全員VBA開発者だと思うのでコーディング時にひな形を用意する有用性は説明不要かと思います。
筆者の場合は、以下の ひな形を最低限 VBE-新規プロシージャに入れてから、コーディングを開始しています。
Seleniumコード作成時の雛形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub Seleniumコーディングひな形() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") '任意のURL driver.Get ("https:~") End Sub |
あとは、後述するリファレンス内容をコピペしながら 繋いでいくイメージですね。
参考:WindowsAPIも一緒に入れるケースがあります。
1 2 |
'Sleep機能を使うAPI Private Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long) |
Selenium自体にも Sleep機能と同等のwait というのがあるのですが、
慣れている Sleep を使用する方が 多いので、この辺は 好みって感じですね。
Seleniumリファレンス
要素の取得(単一系):FindElementBy
ブラウザ操作を行うには、まずHTML要素を取得する必要があります。
FindElementメソッドを使用すると、HTML要素をWebElement型のインスタンスとして取得し、
取得した要素に対してクリックなどの動作を行うことができます。(もちろん、値の抽出も)
Seleniumは決まった型を使いまわすケースが大半なので。笑
メソッドは以下の通り。
FindElementメソッド
- FindElementById
- FindElementByCss
- FindElementByTag
- FindElementByName
- FindElementByClass
- FindElementByXPath
- FindElementByLinkText
- FindElementByPartialLinkText
使用例は 以下のイメージ。
1 2 3 4 5 6 7 8 9 |
'◆◆◆:対応するHTML要素に書き換えてあげる。 driver.FindElementById("◆◆◆").Click driver.FindElementByCss("◆◆◆").Click driver.FindElementByTag("◆◆◆").Click driver.FindElementByName("◆◆◆").Click driver.FindElementByClass("◆◆◆").Click driver.FindElementByXPath("◆◆◆").Click driver.FindElementByLinkText("◆◆◆").Click driver.FindElementByPartialLinkText("◆◆◆").Click |
◆◆◆に対応するHTML要素の記載ルールについては、別記事 ↓ にてまとめています。
-
【VBA×Selenimu】FindElementの記載ルール注意点【動かない人向け】
続きを見る
迷われたら上記の記事が解決の一助になると思いますので、どうぞ。
要素の取得(複数系):FindElementsBy
HTML要素は1つとは限りません。
その場合は、FindElementsByメソッドを活用します。
基本的に DOM制御の場合、単一系まで 割り切ってあげないといけないので、添え字を忘れないようにしましょう。
メソッドは以下の通り。
FindElementsメソッド
- FindElementsByTag
- FindElementsByName
※ByIDやByXPathなどについて、複数形はHTML構造上ありえないので除外
使用例は、以下のイメージ。
1 2 3 4 5 6 7 8 9 10 |
'記入例 '添え字を入れてあげる(意味:上から数えて1番目の◆◆◆をクリック) driver.FindElementsByName("◆◆◆")(0).Click '重ね掛けもできます(意味:上から数えて1番目の◆◆◆の★★★をクリック) driver.FindElementsByName("◆◆◆")(0).FindElementByName("★★★").Click 'ByTagとByNameを重ねることもできます。 driver.FindElementsByTag("◆◆◆").FindElementByName("★★★").Click |
必ずHTML要素は特定してあげましょう。。
この辺を 極めていくと、ページによって増減するWebページ情報抽出にも対応できたりします。
正直、FindElementsBy は For Each と一緒に使う場面が多い思います。
1 2 3 4 5 6 7 8 9 10 11 12 |
'実はFindElement系はHTMLツリー構造が合っていれば重ねることができるよ。 Dim seObjs As selenium.WebElement seObjs = driver.FindElementByID("●●").FindElementsByTag("▲▲") 'ForEachでHTML分析も出来るよ。 Dim seObj As selenium.WebElement For Each seObj In seObjs '←seObjsは「FindElementsByTag」で複数形が格納されている。 If seObj.text = "■ ■" then '←seObjはイメージとしてFindElementsByTag(n)でカウントアップしていく。 Msgbox "■ ■があったよ!" Exit For 'ForEachを終了させる End if Next |
ひとまず、単一系のFindElementByXPathでSelenium操作する方法を覚えましょう。
単一系のFindElementByXPathを利用する率が 90%以上(体感値)なので、
それだけでほぼ十分だったりします。
動的にHTML構造が変化する場面やTableタグを処理する場合に、複数形のFindElementsを使用する場面が多いので、それ以外は無視で良いかな、と。
URL遷移 :get
指定のWebページへ遷移したい場合は、getメソッドを使用します。
メソッドは以下の通り。
getメソッド
- driver.get("[URLを入力]")
使用例は、以下のイメージ。
1 2 |
'任意のURL driver.Get ("https://yahoo.co.jp") |
クリック:Click
Webページの要素を クリックしたい場合、Clickメソッドを使用します。(マウスのクリックと同じです。)
メソッドは以下の通り。
Clickメソッド
- driver.FindElementByXPath("◆◆◆").Click
※◆◆◆:HTML要素(例:検索ボタンのXPathなど)
使用例は、以下のイメージ。
1 2 |
’使用例 driver.FindElementByXPath("//*[@id=""ContentWrapper""]/section").Click |
キー入力:SendKeys
Webページの要素に情報を入力したい場合、SendKyesメソッドを使用します。
メソッド…というより構文は以下の通り。
SendKyesメソッド
- driver. FindElementByXPath("◆◆◆").SendKeys 文字列
※◆◆◆:HTML要素(例:検索用テキストボックスのXPathなど)
使用例は、以下のイメージ。
1 2 3 4 5 6 7 8 9 10 |
'記入例 'Yahooの検索用テキストボックスのXPathを利用 driver. FindElementByXPath("◆◆◆").SendKeys "hogehoge" 'ちなみに、EXCELの変数(String型)も利用できます。 Dim moji As String moji = "hogehoge" driver. FindElementByXPath("◆◆◆").SendKeys moji '←hogehogeが入力されます。 |
Seleniumによる自動化の可能性をグッと広げてくれます。
特殊キー入力:EnterやTabなど
キーボード独自の「Enter」や 「Tab」を使用したいケースが・・・きっとあるはず。
その場合、Selenium側に Keysクラスを用意してくれていますので、SendKeysメソッドに掛け合わせて利用します。
使用例は以下の形。
1 2 3 4 5 6 7 8 9 |
'特殊キー入力方法 'SeleniumでKeysクラスがあるので New KeysをKyに宣言してあげる必要がある。 Dim ky As New Keys 'Enterを入力したい場合 driver. FindElementByXPath("◆◆◆").SendKeys (ky.Enter) 'Tabを入力したい場合 driver. FindElementByXPath("◆◆◆").SendKeys (ky.Tab) |
ココがポイント
Dim ky As New Keys の宣言をしないと クラスを利用できないので、必ず宣言しましょう。
ちなみに、確認できる Keysクラス内のメンバー情報は以下の通り。
理論上、SendKeys (ky.メンバー)の記載形式で使えるはず。
※使えなかったらすみません。
Keysクラス(メンバー一覧)
Add
Alt
ArrowDown
ArrowLeft
ArrowRight
ArrowUp
Backspace
Cancel
clear
Command
Control
Decimal
Delete
Divide
Down
End
Enter
Equal
Escape
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12
Help
Home
Insert
Left
LeftAlt
LeftControl
LeftShift
Meta
Multiply
Null
NumPad0
NumPad1
NumPad2
NumPad3
NumPad4
NumPad5
NumPad6
NumPad7
NumPad8
NumPad9
PageDown
PageUp
Pause
Return
Right
Semicolon
Separator
Shift
Space
Subtract
Tab
Up
入力情報消去:Clear
Webページの要素内で 削除したい文字列がある場合、Clearメソッドを使用します。(既入力の検索情報など)
メソッドは以下の通り。
Clearメソッド
- driver.FindElementByXPath("◆◆◆").Clear
※◆◆◆:HTML要素(例:検索ボックス欄のXPathなど)
使用例は、以下のイメージ。
1 2 |
'入力情報消去 driver. FindElementByXPath("//*[@id=""ContentWrapper""]/input").Clear |
ラジオボタンの選択:Click
Webページの要素で ラジオボタンを選択したい場合、Clickメソッドを使用します。
メソッドは以下の通り。
Clickメソッド
- driver.FindElementByXPath("◆◆◆").Click
※◆◆◆:HTML要素(例:ラジオボックスでクリックしたい箇所のXPath)
使用例は 以下の通り。
1 2 |
'使用例 driver.FindElementByXPath("◆◆◆").Click |
先ほどもClickメソッドは登場しましたが、
ラジオボタンの選択だったので再登場となります。
メモ
ちなみに、試してない(必要性を感じてない)ので未確認情報ですが、Clickメソッド以外でも ラジオボタンの選択は出来ると思います。
HTMLでラジオボタン側にValue値が設定されていた場合、そのValue値をSendKeys だったりで送ってあげれば 選択されるかなーと想像したり。。。
もし 質問などあれば、Twitterやってますので、そこから 気軽に聞いて下さい(ブログネタにもなるため歓迎)。
プルダウンの選択:AsSelect.SelectBy系
Webページの要素で プルダウンを選択したい場合、AsSelect.SelectBy系のメソッドを使用します。
メソッドは以下の通り。
AsSelect.SelectByメソッド
- driver.FindElementByXPath("◆◆◆").AsSelect.SelectByValue ("★★★")
- driver.FindElementByXPath("◆◆◆").AsSelect.SelectByIndex ("★★★")
- driver.FindElementByXPath("◆◆◆").AsSelect.SelectByText ("★★★")
※◆◆◆:HTML要素(例:プルダウンのXPath)
※★★★:後述の使用例を参照してね。
使用例ですが、さすがにHTMLのダミー例を用意しないと説明が難儀になります。
HTML例
<select name="test">
<option value="test1">テスト1</option>
<option value="test2">テスト2</option>
<option value="test3">テスト3</option>
</select>
こちら↑のHTML例をベースに説明した、使用例が以下の通り。
例:プルダウンで"テスト3"を選択したい場合
1 2 3 4 |
例:プルダウンで"テスト3"を選択したい場合 driver.FindElementByXPath("◆◆◆").AsSelect.SelectByValue ("test3") driver.FindElementByXPath("◆◆◆").AsSelect.SelectByIndex ("2") driver.FindElementByXPath("◆◆◆").AsSelect.SelectByText ("テスト3") |
実際のコーディング例を見て理解を深めると良いと思います。
任意の時間-処理を止める:wait
Seleniumの動作が安定しない…などの理由で、任意の時間 処理を停止させたい場合、waitメソッドを利用します。
メソッドは以下の通り。
waitメソッド
- driver.wait 任意の時間(1000 で 1秒の意味となります)
使用例は以下の通り。
1 2 3 4 5 |
'1秒止める driver.wait 1000 '60秒止める driver.wait 60000 |
ブラウザ情報の取得:window.title
ブラウザの ウィンドウタイトルを取得する時に使用します。
1 |
driver.Window.Title |
使用例は以下の通り。
1 2 |
'イミディエイトウィンドウで、WindowTitleを表示させる Debug.Print driver.Window.Title |
driver.Window.Title は文字列(String型)なので、VBAのMsgboxも利用可能です。
複数ウィンドウをスイッチする際に、スイッチ前のウィンドウに戻りたい時に WindowTitleで指定して戻ったりするので。
これについては、後述してますので「SwitchToWindowByTitle」のメモ欄を参照ください。
新規のウィンドウを制御対象にする:SwitchToNextWindow
Webページによっては、クリックした後に 新規ウィンドウが出現します。
Seleniumは便利なもので「SwitchToNextWindow」を利用すれば、制御ウィンドウに切替を簡単に出来ます。
メソッドは以下の通り。
SwitchToNextWindowメソッド
- driver.SwitchToNextWindow
使用例は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Sub Selenium_SwitchToNextWindow() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") '該当のURLを開く driver.Get ("https://~") '新規ウィンドウを出現させるボタンをクリック(◆◆◆:XPathは置き換えて下さい) driver.FindElementByXPath("◆◆◆").Click '★driverオブジェクト内容が新規ウィンドウに置き換わる driver.SwitchToNextWindow 'イミディエイトウィンドウで driverのタイトル名を確認 Debug.Print driver.Window.Title End Sub |
任意のウィンドウを制御対象にする:SwitchToWindowByTitle
Webページによっては、クリックした後に 新規ウィンドウが出現します。
その場合、driverオブジェクトで制御するウィンドウを指定し直す必要があります。
「SwitchToWindowByTitle」を使用すれば、任意のウィンドウに制御をスイッチすることが可能。
メソッドは以下の通り。
SwitchToWindowByTitleメソッド
- driver.SwitchToWindowByTitle("◆◆◆")
※◆◆◆:ウィンドウタイトル(※完全一致が必要)
注意点を先に述べると、スイッチ先のウィンドウタイトルは完全一致であることが必要です。
注意
スイッチ先のウィンドウタイトルは完全一致であることが必要。
例)Webページが「Yahoo! JAPAN」のウィンドウタイトルの場合
OK例:driver.SwitchToWindowByTitle("Yahoo! JAPAN")
NG例:driver.SwitchToWindowByTitle("Yahoo")
それを踏まえた上で、使用例を確認ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Sub Selenium_SwitchToWindowByTitle() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") '該当のURLを開く driver.Get ("https://~") '新規ウィンドウを出現させるボタンをクリック(◆◆◆:XPathは置き換えて下さい) driver.FindElementByXPath("◆◆◆").Click '★driverオブジェクト内容が新規ウィンドウに置き換わる driver.SwitchToWindowByTitle ("Yahoo! JAPAN") 'イミディエイトウィンドウで driverのタイトル名を確認 Debug.Print driver.Window.Title End Sub |
ご参考までに
ウィンドウAとウィンドウBがあったとして、
それぞれを横断的に制御したい時、僕は 以下の感じで やりくりしています。
解説は コード内のインラインコメントに入れてますので、よろしければどうぞ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
Sub Selenium_SwitchToNextWindowの実用イメージ() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver '★ 変数:ウィンドウA と ウィンドウBを作る Dim windowA As String Dim windowB As String 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") '該当のURLを開く(ウィンドウAとする) driver.Get ("https://~") '★ウィンドウAのタイトル名を変数に格納 windowA = driver.Window.Title 'ウィンドウBを出現させるボタンをクリック(◆◆◆:XPathは置き換えて下さい) driver.FindElementByXPath("◆◆◆").Click '一旦、SwitchToNextWindowでウィンドウBに制御を移行させる driver.SwitchToNextWindow '★ウィンドウBのタイトル名を変数に格納 windowB = driver.Window.Title ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'この段階で、windowAとwindowBにそれぞれ制御したいウィンドウタイトルが入ってる ' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '★状況に応じて、都度SwitchToWindowByTitleでdriverオブジェクトの制御対象をスイッチさせる 'windowAを制御したい時 driver.SwitchToWindowByTitle ("" & windowA & "") ''┗ 不安な人は、debug.printで正しくスイッチされているかタイトルを確認 'Debug.Print driver.Window.Title 'windowBを制御したい時 driver.SwitchToWindowByTitle ("" & windowB & "") ''┗ 不安な人は、debug.printで正しくスイッチされているかタイトルを確認 'Debug.Print driver.Window.Title End Sub |
アラート表示の制御:SwitchToAlert(★New)
制御しているChromeブラウザでポップアップウィンドウが出現し、それを制御したい場合は、SwitchToAlertメソッドを使用します。
メソッドは以下の通り。
メソッド
- driver.SwitchToAlert.Accept() '※OKを押したい場合
- driver.SwitchToAlert.Dismiss() '※キャンセルを押したい場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Sub Selenium_Close() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") '該当のURLを開く driver.Get ("https://~") ’~~~~~ポップアップウィンドウが出現するまでの制御~~~~~ ' OKを押す場合 driver.SwitchToAlert.Accept() '' キャンセルを押す場合 'driver.SwitchToAlert.Dismiss() End Sub |
Webページ内-要素の存在確認:IsElementPresent
制御しているChromeブラウザ内で要素の存在確認をしたい場合は、IsElementPresent メソッドを使用します。
メソッドは以下の通り。
IsElementPresent メソッド
Boolean型(True/False)が戻り値
- driver.IsElementPresent(myBy.XPath("◆◆◆"))
- driver.IsElementPresent(myBy.ID("◆◆◆"))
※◆◆◆:HTML要素(XPathやIDなどで使い分ける)
IsElementPresentの戻り値は Boolean型です。
ポイント
対象の要素があればTrue 、要素がなければ False が返ります。
それを踏まえた使用例が以下の通り。
①Webロード待ち で使用するパターン
1 2 3 4 5 6 7 |
’① Webロード待ち で使用するパターン '期待する要素があるか確認(ロード待ち) FWFlag = False Do FWFlag = driver.IsElementPresent(myBy.XPath("◆◆◆")) driver.Wait 1000 Loop Until FWFlag = True |
②If分岐 で使用するパターン
1 2 3 4 5 6 |
'②If分岐 で使用するパターン If driver.IsElementPresent(myBy.XPath("◆◆◆")) Then 'True時の処理を記載 Else 'False時の処理を記載 End If |
③Function化して要素確認 (応用)するパターン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
'③Function化して要素確認 (応用)するパターン '独自Function:XPathCertain Sub 要素確認() If XPathCertain("◆◆◆") Then '※1 'True時の処理を記載 Else 'False時の処理を記載 End If '※1:◆◆◆:XPathを記入 ' → XPathが「//*[@id="eyebrow"]」だった場合、 ' ◆◆◆には「//*[@id=""eyebrow""]」と入れてあげる。 ' VBA記載ルールの"(ダブルクォーテーション)を追加することを忘れずに。 End Sub '******************************************************************************* '* '*内容:Selenium操作における XPath要素の存在確認を行う。 '* '* 理由:①根本的にHTML存在確認を行う方法が、IEのDOM制御とは違うため独自Functionで解決するのが目的 '* ②Function化することで、コード可読性の向上も目的 '* '* 引数:Target ← XPathを入れる '* 戻り値:Boolean (対象XPathあればTrue、無ければFalse) '* '******************************************************************************* Function XPathCertain(Target As String) As Boolean Dim XFlag As Boolean Dim c As Long Dim myBy As New By XFlag = False c = 0 Do '10秒間-存在確認を行い、未確認なら変数XPathCertainにFalseを返す If driver.IsElementPresent(myBy.XPath("" & Target & "")) Then XPathCertain = True '要素が見つかれば、XPathCertainの戻り値:True を返す。 Exit Function Else driver.Wait 1000 c = c + 1 XFlag = False End If Loop Until c > 10 '10秒間リトライ '10秒間でFWFlagがFalse(なかった)場合、XPathCertainの戻り値:False となる。 If Not (FWFlag) Then: XPathCertain = False '余談:もっと良いコーディング方法はあると思いますでカスタムしちゃってくださいorz End Function |
ウィンドウを閉じる:Close
制御しているChromeブラウザを閉じたい場合は、Closeメソッドを使用します。
メソッドは以下の通り。
Closeメソッド
- driver.Close
- driver.Quit (※Closeで閉じれない時は、Quitでもいける)
そもそも、Seleniumは、動作が終了すれば、自動でブラウザを閉じてくれる仕様です。
なので、ライトな感じでSelenium自動化を狙う人にとっては知らなくても良い情報ですが、
一応 使用例を紹介します。(Webエンジニアが自動テストする際は使用すると思いますし。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Sub Selenium_Close() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") '該当のURLを開く driver.Get ("https://~") '★ウィンドウを閉じる driver.Close End Sub |
参考:Web読込待ちの方法(Seleniumエラー時の約90%は解決できるはず)
seleniumの動作スピードが 早すぎてエラーになることがあります。
大体の原因が「Web読込待ちを待たずに、Seleniumが次の動作を行い、該当の要素が表示されておらず、処理が実行できずにエラーに落ちる」というのが、体感値としては多いです。
本記事内の IsElementPresent を利用したものとなり、以下の記事でも紹介しています。
-
【Selenium×VBA】Webブラウザをロード待ちする方法【コード有】
続きを見る
ちなみに、selenium利用時のエラーは、90%くらい Web読込待ちに起因するものだと思っとります。
残りの10%は、適切なHTML要素が記載できないケースや、そもそものVBAコーディングが間違っているケースです。
Selenium ←→ EXCELで情報を行き来させる方法
EXCEL→Seleniumへの情報入力
EXCELの情報を Selenium経由で Chromeブラウザに送る方法を紹介します。
- 【方法①:一回Clickメソッドを経由してSendkeyで、EXCELのA1セルの文字列を送る方法】
driver.FindElementByXPath("◆◆◆").Click
driver.SendKeys Range("A1") - 【方法②:直にSendkeyで、EXCELのA1セルの文字列を送る方法】
driver.FindElementByXPath("◆◆◆").SendKeys Range("A1") - 【方法③:変数(String型)を送る方法】
Dim moji As String
moji = "hogehoge"
driver.FindElementByXPath("◆◆◆").SendKeys moji
※◆◆◆:HTML要素(例:検索用テキストボックスのXPathなど)
具体的な使用例は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Sub EXCEL情報をSeleniumで情報入力() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") 'YahooのURLを開く driver.Get ("https://yahoo.co.jp") ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'Yahooの検索ボックスのXPathを対象に説明 ' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '方法①:一回Clickメソッドを経由してSendkeyで、EXCELのA1セルの文字列を送る方法 driver.FindElementByXPath("//*[@id=""ContentWrapper""]/header/section[1]/div/form/fieldset/span/input").Click driver.SendKeys Range("A1") '方法②:直にSendkeyで、EXCELのA1セルの文字列を送る方法 driver.FindElementByXPath("//*[@id=""ContentWrapper""]/header/section[1]/div/form/fieldset/span/input").SendKeys Range("A1") '方法③:変数(String型)を送る方法 Dim moji As String moji = "hogehoge" driver.FindElementByXPath("//*[@id=""ContentWrapper""]/header/section[1]/div/form/fieldset/span/input").SendKeys moji End Sub |
Selenium→ EXCLE への情報入力
SeleniumからEXCELへ情報入力する方法も紹介します。
- 【方法①:直接EXCELへ情報抽出する方法】
Range("A1") = driver.FindElementByXPath("◆◆◆").Text - 【方法②:変数(String型)を経由してEXCELへ情報入力する方法】
Dim moji As String
moji = driver.FindElementByXPath("◆◆◆").Text
Range("A1") = moji - 参考:Value値なども抽出可能
Range("A1") = driver.FindElementByXPath("◆◆◆").value
※◆◆◆:HTML要素(例:抽出したいXPathなど)
使用例を紹介しますね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Sub SeleniumからEXCELへ情報入力() '変数:driver でSelenium制御をしますよ宣言 Dim driver As New Selenium.ChromeDriver 'Selenium利用時、ウィンドウサイズを最大化で開く初期設定 driver.AddArgument "disable-gpu" driver.AddArgument "start-maximized" 'SeleniumでChromeを使用する初期設定 Call driver.Start("chrome") 'YahooのURLを開く driver.Get ("https://yahoo.co.jp") ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'Yahooの適当なテキスト情報のXPathを対象に説明 ' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '方法①:直接EXCELへ情報抽出する方法 Range("A1") = driver.FindElementByXPath("//*[@id=""tabpanelTopics1""]/div/div[1]/p/span").Text '方法②:変数(String型)を経由してEXCELへ情報入力する方法 Dim moji As String moji = driver.FindElementByXPath("//*[@id=""tabpanelTopics1""]/div/div[1]/p/span").Text Range("A2") = moji End Sub |
ちなみに、今回 Text 情報を抽出しておりますが、innerTextやinnerHTML、outerTextやouterHTMLの情報も取得できます。
こちらについては、別記事に まとめてますので、必要に応じて 確認してみて下さい。
-
【VBA×Selenium】innerTextの使い方【注意点あり】
続きを見る
-
【VBA×Selenium】innerHTMLの使い方【注意点あり】
続きを見る
-
【VBA×Selenium】outerHTMLの使い方【注意点あり】
続きを見る
終わりに
さて、今回はここまでとなります。
全てを紹介しきれてませんが、本記事の内容で 90%以上は やりたいことは実現できると思っとります。
頻度は そこまで多くないと思いますので、またの機会ということで。
本記事を ブックマークしておくと、中々に便利ですので、よろしければ活用ください。
(リファレンス追加することもあると思いますので。)
一応 検証しながらやっていますので、大丈夫だと思いますが。
はい。
ということで、本当にこれにて終わりとなります。
皆様のVBA×Seleniumライフがより良いものになれば、筆者としてはハッピーです。
さて、ここまでお読みいただきありがとうございました。
-----終わり-----