SeleniumBasicでExcelシートのセルを利用したスクレイピング例を紹介します。
- 利用目的は業務効率化です。(テスト自動化ではありません)
- ブラウザはGoogleChromeが対象です。(EdgeやFirefoxは対象外)
- 原文のVBAでは現在エラー発生する場合が多いため、修正を加えてます。
Examples.xlsmの保存場所(ここをクリック)
Examples.xlsmが保存されている場所は、SeleniumBasicがインストールされているサブフォルダ内になります。SeleniumBasicのインストール完了時に保存フォルダを確認することができます。ただ、大体以下フォルダのどちらかにファイル保存されています。
- C:\Program Files\Seleniumbasic\Examples\Excel
- shell:Local AppData\SeleniumBasic\Examples\Excel
セルのテキストでWeb検索
Examplesのsheet1シート内のセルに入力されているテキストで、ウィキペディアの検索を実行します。今回は、Range("A3")に入力されている、文字列("Id")を使って、ウィキペディア検索します。
Private Sub Use_Cell_text()
Dim Driver As New ChromeDriver
Driver.Get "https://ja.wikipedia.org/wiki/Main_Page"
Dim ele As WebElement
Set ele = Driver.FindElementById("searchInput")
ele.SendKeys Sheet1.Range("A3")
ele.Submit
Stop
Driver.Quit
End Sub
5行目:IdタグにてWeb要素を取得。(検索ボックスを取得)
6行目:検索ボックスにセルの内容をインプット
7行目:フォームの送信
Excelデータテーブルの利用
SeleniumBasicでExcelのデータテーブルをTableオブジェクトで定義した後、"ExpectedTitle"列に入力されたドライバータイトルとWeb検索結果が一致しているか、確認結果を"Result"列に入力しています。
Tableオブジェクトは、SeleniumBasic独特のオブジェクト(クラス)となります。SQLに近似した表現を利用することができます。普段VBAの利用に慣れていると、このSeleniumオブジェクトを利用して、Excelのセル情報を扱うことをしなくて良いと思います。
また、確認用で利用しているVerifyオブジェクトもSeleniumBasic独特のオブジェクト(クラス)ですが、これもTableオブジェクト同様無理して利用しなくても良いかと思います。
以下、コードを紹介します。
Public Sub VerifyTitles()
Dim Table As New Selenium.Table
Dim Verify As New Selenium.Verify
Dim Driver As New ChromeDriver
Dim row
For Each row In Table.From(Sheet1.Range("A3")).Where("Id > 0")
Driver.Get row("Link")
row("Result") = Verify.Equals(row("ExpectedTitle"), Driver.title)
Next row
Driver.Quit
End Sub
2行目:Tableインスタンスの生成
3行目:Verifyインスタンスの生成
7行目:TableオブジェクトにExcelのテーブルデータを代入し、For Each文でループさせています。Tableオブジェクトへ代入するための構文は、ほぼSQLのSelect文をSeleniumで実現するための構文の様です。
・Fromメソッド
TableクラスのFromメソッドでテーブルデータのソースを指定します。Range指定でOKの様です。Tableクラスをライブラリ情報で見ると、以下説明になっていました。
Loads the data from an Excel source (address, range or worksheet)
ほぼ、SQLのSelect Fromの"From"箇所の事を指している様です。
・Whereメソッド
テーブルデータのフィルタ条件を設定します。ライブラリ情報では以下説明でした。
Filter the rows using the given expression
SeleniumBasicのチュートリアルを確認すると、「SQL表現の様にフィルタ条件を設定する。」とありましたので、ほぼSQL構文のWhere句の様に扱う物と考えて良いと思います。ここでは、"Id"列が0より大きい、という条件を設定しています。
9行目:Verifyクラスを利用して、検索結果をExpectedTitle列で入力されているドライバータイトルと一致しているか確認し、確認結果をResult列に入力します。確認結果が合致していれば、OKを返し、不一致の場合は、不一致結果を返します。ライブラリの説明は、以下のとおです。
Reurns <OK> if the objects are equal, <NOK, ...>otherwise.
リンクリストの作成
ウィキペディア(日本語版)のメインページにあるリンクテキストを取得して、リスト化してからExcelシートに出力します。以下、コードの紹介です。
Public Sub ListLinks()
Dim Driver As New ChromeDriver
Driver.Get "https://ja.wikipedia.org/wiki/Main_Page"
Dim links As List
Set links = Driver.FindElementsByTag("a").Attribute("href")
links.Distinct
links.Sort
links.ToExcel Sheet2.Range("A7")
Driver.Quit
End Sub
4行目:List型の定義
5行目:linksオブジェクトにリンクテキスト(hrefタグ)のWebを代入
6行目:linksリストで重複があれば削除
7行目:linksリストの並び替え
8行目:Excelシートにリスト出力
日本語のリンクテキストを取得する際、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
スクリーンショットを取る
ウィキペディアのメインページのスクリーンショットを取得して、エクセルシートに画像を貼付けします。以下、コード紹介です。
Public Sub TakeScreenShoot()
Dim Driver As New ChromeDriver
Driver.Get "https://ja.wikipedia.org/wiki/Main_Page"
Driver.TakeScreenshot().ToExcel Sheet3.Range("A7")
Driver.Quit
End Sub
3行目:ウィキペディアのメインページ取得
4行目:Webページのスクリーンショットを取り、Excelシートに出力