これまでの記事でもSeleniumBasicでJavascriptを利用する場面が多くありましたが、今回はそのJavaScript利用に焦点を当てた構文を紹介します。
- 利用目的は業務効率化です。(テスト自動化ではありません)
- ブラウザはGoogleChromeが対象です。(EdgeやFirefoxは対象外)
- 原文のVBAでは現在エラー発生する場合が多いため、修正を加えてます。
Examples.xlsmの保存場所(ここをクリック)
Examples.xlsmが保存されている場所は、SeleniumBasicがインストールされているサブフォルダ内になります。SeleniumBasicのインストール完了時に保存フォルダを確認することができます。ただ、大体以下フォルダのどちらかにファイル保存されています。
- C:\Program Files\Seleniumbasic\Examples\Excel
- shell:Local AppData\SeleniumBasic\Examples\Excel
タイトル取得
ウィキペディアホームページでウィキペディアのタイトル取得をJavaScript利用で実現します。
Private Sub Execute_Script()
Dim Driver As New ChromeDriver
Driver.Get "https://ja.wikipedia.org/wiki/Main_Page"
Dim title As String
title = Driver.ExecuteScript("return document.title;")
Debug.Assert "Wikipedia" = title
Stop
Driver.Quit
End Sub
4,5行目:JavaScriptでホームページのタイトル取得
6行目:Debug.Assertでタイトル名の確認
SeleniumBasicでJavaScriptを実行させる構文は、以下のとおりです。
Driver.ExecuteScript(“<Javascript構文>“)
Idタグのname名取得
JavaScriptの構文を利用し、Idタグ内の子ノード(name)の値を取得します。
Private Sub Execute_Script_On_Element()
Dim Driver As New ChromeDriver
Driver.Get "https://ja.wikipedia.org/wiki/Main_Page"
Dim name As String
name = Driver.FindElementById("searchInput").ExecuteScript("return this.name;")
Debug.Assert "search" = name
Stop
Driver.Quit
End Sub
4,5行目:ウィキペディアのIdタグ("searchInput")をキャッチし、JavaScriptでname値を取得。
7行目:Debug.Assertでname値の確認
ここで、Chromeのディベロッパーツール画面でもname値を確認したいと思います。ウィキペディアのホームページでCtrl + Shift + I でディベロッパーツール画面を開きます。次に、Ctrl + F で検索画面を出し、"searchInput"を入力後、エンターして検索実行します。
name="searchInput"になっていることが確認できました。
リンクテキストの取得
FindElementsByTagメソッドを利用してaタグのテキストを複数取得します。取得した値をSeleniumのリスト型に代入し、Sheet2シートのA7セルに出力します。
Private Sub Execute_Script_On_Elements()
Dim Driver As New ChromeDriver
Driver.Get "https://ja.wikipedia.org/wiki/Main_Page"
Dim links As List
Set links = Driver.FindElementsByTag("a").ExecuteScript("return this.href;")
links.ToExcel Sheet2.Range("A7")
Driver.Quit
End Sub
4行目:Seleniumのリスト型宣言(変数=links)
5行目:aタグで複数キャッチしたテキストからリンクテキスト(href)を取得し、linksに代入
6行目:Sheet2シートのA7セルにリンクテキストを出力
同じような構文は、以下ページでも紹介しています。
日本語のリンクテキストを取得する際、URLエンコードされた(日本語が%表示される)文字列を取得してしまいます。文字化けを防ぐため、シートにリンクテキストを出力した後、デコード(日本語表記化)するコードを紹介します。
まず、32bit版のOffice環境の場合、以下構文でデコードができます。こちらのページの構文を利用させていただきました。
Public Sub Decode_work()
Dim maxrow As Long, i As Long
maxrow = Sheet2.Cells(Rows.count, 1).End(xlUp).row
For i = 7 To maxrow
Sheet2.Cells(i, 1) = URL_Decode(Sheet2.Cells(i, 1))
Next i
End SUb
Public Function URL_Decode(ByVal strOrg As String) As String
With CreateObject("ScriptControl")
.Language = "JScript"
URL_Decode = .CodeObject.decodeURI(strOrg)
End With
End Function
64bit版のPC環境の場合、CreateObject("ScriptControl")は実行エラーが発生します。代わりの構文は、こちらのページの構文を利用させていただきました。Decode_work内のURL_DecodeをDEcodeURLMSHTML_64bitに置き換えて命令文を作成します。DEcodeURLMSHTML_64bit関数は、以下の内容となります。事前に参照設定で、Microsoft HTML Object Libraryを選択しておきます。
Function DEcodeURLMSHTML_64bit(ByVal sWord As String) As String
Dim d As Object
Dim elm As MSHTML.HTMLSpanElement
Dim objD As HTMLDocument: Set objD = New MSHTML.HTMLDocument
sWord = Replace(sWord, "\", "\\")
sWord = Replace(sWord, "'", "\'")
Set d = CreateObject("htmlfile")
Set elm = objD.createElement("span")
elm.setAttribute "id", "result"
objD.appendChild elm
objD.parentWindow.execScript "document.getElementById('result').innerText = decodeURIComponent('" & sWord & "');", "JScript"
DEcodeURLMSHTML_64bit = elm.innerText
End Function
JavaScript非同期処理
JavaScriptの非同期処理の実行例を紹介します。JavaScriptでゲットしたURLを引数にしてコールバック関数を実行しています。レスポンスのHTMLソースをイミディエイトウィンドウに出力します。
Private Sub Execute_Script_Async()
Dim Driver As New ChromeDriver
Driver.Get "https://en.wikipedia.org/wiki/Main_Page"
Dim response As String
response = Driver.ExecuteAsyncScript( _
"var r = new XMLHttpRequest();" & _
"r.onreadystatechange = function(){" & _
" if(r.readyState == XMLHttpRequest.DONE)" & _
" callback(this.responseText);" & _
"};" & _
"r.open('GET', 'wiki/Euro');" & _
"r.send();")
Debug.Print response
Driver.Quit
End Sub
5行目で、Driver.ExecuteAsyncScriptにより、JavaScriptの非同期処理を実行しています。JavaScriptの構文も参考までに以下にご案内します。
var r = new XMLHttpRequest();
r.onreadystatechange = function(){
if(r.readyState == XMLHttpRequest.DONE) callback(this.responseText);
};
r.open('GET', 'wiki/Euro');
r.send();