Seleniumの使い方 - 基本操作
ブラウザ起動
WebDriverのインスタンスを作成すると、ブラウザが表示されます。
使用するブラウザによって参照するdll・名前空間・クラスは異なりますが、似たような定義方法です。
ブラウザのオブジェクトを格納する変数をインタフェースで定義すれば、どのブラウザ用のオブジェクトでも格納できます。
以下は、Formにボタンを3つ貼り付け、それぞれのブラウザのインスタンスを作成するサンプルです。
Imports OpenQA.Selenium Imports OpenQA.Selenium.IE Imports OpenQA.Selenium.Chrome Imports OpenQA.Selenium.Firefox Public Class Form1 Private _browser As IWebDriver 'IE Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click _browser = New IE.InternetExplorerDriver() End Sub 'Chrome Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click _browser = New ChromeDriver() End Sub 'Firefox Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click _browser = New FirefoxDriver() End Sub End Class
using OpenQA.Selenium; using OpenQA.Selenium.IE; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Firefox; public class Form1 { private IWebDriver _browser; // IE private void Button1_Click(object sender, EventArgs e) { _browser = new IE.InternetExplorerDriver(); } // Chrome private void Button2_Click(object sender, EventArgs e) { _browser = new ChromeDriver(); } // Firefox private void Button3_Click(object sender, EventArgs e) { _browser = new FirefoxDriver(); } }
また、各DriverはIDisposable
インタフェースを備えていますので、using
も使えます。
usingが終了のタイミングで、ブラウザも自動で終了します。
'IE Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Using browser As New IE.InternetExplorerDriver() 'ここにIE操作処理を記載 End Using End Sub
// IE private void Button1_Click(object sender, EventArgs e) { using (IE.InternetExplorerDriver browser = new IE.InternetExplorerDriver()) { //ここにIE操作処理を記載 } }
Webページの表示
以下の方法があります。
Urlプロパティへの設定
GoToUrlメソッド
読み込み待ち
SeleniumでWeb操作を実行していると、プログラムの速度が早すぎて読み込みが終わっていないのに次の要素の操作を行おうとして、
エラーが発生する場合があります。
JavaScriptで動的に要素が作成される場合も同様です。
そのため、読み込みが伴う操作後には、要素を検出できるまでの待機が必要です。
Seleniumの読み込み待ちには2種類の方法があります。
Webページ上のコンテンツが読み込まれるまで待機する方法
OpenQA.Selenium.Support.UI.WebDriverWait
クラスとUntil
メソッドを使用します。WebDriverWait
により、任意のHTML要素が取得できるまで(ページが読み込まれ、使用する要素が使用可能となるまで)指定時間を待機します。
Until
で要素の取得条件を指定します。指定時間が経過しても読み込みが終わらない(=要素が取得できない)場合は、
TimeoutException
例外が発生します。また、待機条件は「要素がクリック可能になれば」「要素のテキストが変更されれば」のように、細かくカスタマイズすることができます。詳しくはこちらを参照ください。
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 'Chromeブラウザを表示 Dim driver As New ChromeDriver() 'ページを表示 driver.Navigate().GoToUrl("https://www.yahoo.co.jp") 'ページが表示されるまで(検索欄が認識できるまで)待機 Try 'Imports OpenQA.Selenium.Support.UI Dim element = New WebDriverWait(driver, TimeSpan.FromSeconds(3)).Until(Function(drv) drv.FindElement(By.Name("p"))) '新しいSeleniumではExpectedConditionsは廃止されている '旧いのと同じ処理を行いたい場合、NuGetから「DotNetSeleniumExtras.WaitHelpers」からインストールする。 'Dim element As IWebElement = New WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//a/h3"))) Catch ex As TimeoutException Console.WriteLine(ex.Message) End Try End Sub
private void button1_Click(object sender, EventArgs e) { var driver = new ChromeDriver(); driver.Url = "https://www.yahoo.co.jp"; try { //using OpenQA.Selenium.Support.UI; var element = new WebDriverWait(driver, TimeSpan.FromSeconds(3)).Until(drv => drv.FindElement(By.Name("p"))); //新しいSeleniumではExpectedConditionsは廃止されている //旧いのと同じ処理を行いたい場合、NuGetから「DotNetSeleniumExtras.WaitHelpers」からインストールする。 //IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//a/h3"))); } catch (TimeoutException ex) { Console.WriteLine(ex.Message); } }
要素を取得するときに待機が行われる方法
Manage().Timeouts().ImplicitWait
を一度設定しておけば、以降の
FindElement
やFindElements
で要素を取得するときに、毎回待機が行われるようになります。Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click 'Chromeブラウザを表示 Dim driver As New ChromeDriver() 'タイムアウト時間を設定 driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10) 'ページを表示 driver.Navigate().GoToUrl("https://www.yahoo.co.jp") 'ページが表示されるまで(検索欄が認識できるまで)待機 Try Dim element As IWebElement = driver.FindElement(By.Name("p")) Catch ex As TimeoutException Console.WriteLine(ex.Message) End Try End Sub
private void button2_Click(object sender, EventArgs e) { //Chromeブラウザを表示 var driver = new ChromeDriver(); //タイムアウト時間を設定 driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); //ページを表示 driver.Url = "https://www.yahoo.co.jp"; try { //ページが表示されるまで(検索欄が認識できるまで)待機 var element = driver.FindElement(By.Name("p")); } catch (TimeoutException ex) { Console.WriteLine(ex.Message); } }
参考
待機
Selenium Web Driver, ExpectedConditions [deprecated] alternative
戻る/進む/更新
タイトル/URLの取得/ソースコードの取得
現在表示しているサイトのタイトルとURLを取得します。
alert/confirm/promptの操作
alert/confirm/promptのダイアログを操作する方法です。
browser.SwitchTo().Alert()
でダイアログのオブジェクトを取得でき、Accept
やDismiss
でボタンを押下します。
'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で Private Sub btnAlert_Click(sender As Object, e As EventArgs) Handles btnAlert.Click '------------------------ 'alert表示 CType(_browser, IJavaScriptExecutor).ExecuteScript("alert('alert test');") 'alertのオブジェクトを変数に格納 Dim alert As IAlert = _browser.SwitchTo().Alert() 'alertのテキストを取得 MsgBox(alert.Text) 'OKボタンを押す alert.Accept() '------------------------ 'confirm表示 CType(_browser, IJavaScriptExecutor).ExecuteScript("confirm('confirm test');") 'confirmのオブジェクトを変数に格納 alert = _browser.SwitchTo().Alert() 'confirmのテキストを取得 MsgBox(alert.Text) 'キャンセルボタンを押す alert.Dismiss() '------------------------ 'prompt表示 CType(_browser, IJavaScriptExecutor).ExecuteScript("prompt('prompt表示 test');") 'prompt表示 alert = _browser.SwitchTo().Alert() 'メッセージ入力 alert.SendKeys("test") 'OKボタンを押す alert.Accept() End Sub
//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で private void btnAlert_Click(object sender, EventArgs e) { //------------------------ //alert表示 ((IJavaScriptExecutor)_browser).ExecuteScript("alert('alert test');"); //alertのオブジェクトを変数に格納 IAlert alert = _browser.SwitchTo().Alert(); //alertのテキストを取得 MessageBox.Show(alert.Text); //OKボタンを押す alert.Accept(); //------------------------ //confirm表示 ((IJavaScriptExecutor)_browser).ExecuteScript("confirm('confirm test');"); //confirmのオブジェクトを変数に格納 alert = _browser.SwitchTo().Alert(); //confirmのテキストを取得 MessageBox.Show(alert.Text); //キャンセルボタンを押す alert.Dismiss(); //------------------------ //prompt表示 ((IJavaScriptExecutor)_browser).ExecuteScript("prompt('prompt表示 test');"); //prompt表示 alert = _browser.SwitchTo().Alert(); //メッセージ入力 alert.SendKeys("test"); //OKボタンを押す alert.Accept(); }
参考
JavaScriptの実行
表示しているページに対してJavaScriptのコードを実行することができます。
Seleniumにはクラスやメソッドがなくて行えない操作も、JavaScriptを使用することで行えます。
((IJavaScriptExecutor)driver).ExecuteScript
メソッドの引数にJavaScriptのコードを指定します。
非同期用実行用の((IJavaScriptExecutor)driver).ExecuteAsyncScript
メソッドも使用できます。
VBやC#のプログラムで取得していた要素のオブジェクトを、JavaScriptのコードに渡すこともできます。
例えばelement変数に要素のオブジェクトを取得していた場合に、JavaScriptのコードにarguments[0]
と記載すれば、その部分がelementのオブジェクトに置き換わります。
Dim element = _browser.FindElement(By.Id("inputid2"))
CType(_browser, IJavaScriptExecutor).ExecuteScript("alert(
arguments[0]
.value);", element
)JavaScriptの実行結果やページの情報を取得したい場合は、JavaScriptのコードで値をreturnすれば、
ExecuteScript
メソッドの戻り値として返却されます。注意
alert
のJavaScriptを実行する場合は注意が必要です。alert
でアラートと表示して閉じないまま、さらにalert
の表示を行うと、例外が発生します。また、非同期メソッドの
ExecuteAsyncScript
でalert
のJavaScriptを実行すると、処理が止まってしまいました。'下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で Private Sub btnAttr_Click(sender As Object, e As EventArgs) Handles btnAttr.Click '文字のスタイル内容を表示 CType(_browser, IJavaScriptExecutor).ExecuteScript("document.getElementById('styleid1').setAttribute('info', 'newinfo');") CType(_browser, IJavaScriptExecutor).ExecuteScript("alert(document.getElementById('styleid1').getAttribute('info'));") End Sub 'VB/C#で取得した要素をJavaScriptに渡す Private Sub btnJs2_Click(sender As Object, e As EventArgs) Handles btnJs.Click Dim element = _browser.FindElement(By.Id("inputid2")) CType(_browser, IJavaScriptExecutor).ExecuteScript("alert(arguments[0].value);", element) End Sub '非同期のコード Private Async Sub btnAttr2_Click(sender As Object, e As EventArgs) Handles btnAttr.Click '文字のスタイル内容を表示 Await CType(_browser, IJavaScriptExecutor).ExecuteScript("document.getElementById('styleid1').setAttribute('info', 'newinfo');") 'CType(_browser, IJavaScriptExecutor).ExecuteScript("alert(document.getElementById('styleid1').getAttribute('info'));") End Sub 'JavaScriptの実行結果の値を取得 Private Sub btnJs_Click(sender As Object, e As EventArgs) Handles btnJs.Click Dim result As String = CType(CType(_browser, IJavaScriptExecutor).ExecuteScript("return 'test';"), String) MsgBox(result) End Sub
//下記コードの動作確認はテストページ(https://web.biz-prog.net/test/testpage.html)で private void btnAttr_Click(object sender, EventArgs e) { //文字のスタイル内容を表示 ((IJavaScriptExecutor)_browser).ExecuteScript("document.getElementById('styleid1').setAttribute('info', 'newinfo');"); ((IJavaScriptExecutor)_browser).ExecuteScript("alert(document.getElementById('styleid1').getAttribute('info'));"); } //VB/C#で取得した要素をJavaScriptに渡す private void btnJS_Click(object sender, EventArgs e) { var element = _browser.FindElement(By.Id("inputid2")); ((IJavaScriptExecutor)_browser).ExecuteScript("alert(arguments[0].value);", element); } //非同期のコード private async void btnAttr_Click(object sender, EventArgs e) { //文字のスタイル内容を表示 await ((IJavaScriptExecutor)_browser).ExecuteScript("document.getElementById('styleid1').setAttribute('info', 'newinfo');"); //((IJavaScriptExecutor)_browser).ExecuteScript("alert(document.getElementById('styleid1').getAttribute('info'));"); } //JavaScriptの実行結果の値を取得 private void btnJS2_Click(object sender, EventArgs e) { string result = ((IJavaScriptExecutor)_browser).ExecuteScript("return 'test';").ToString(); MessageBox.Show(result); }