SeleniumBasicを利用して、ホームページに掲載されているテーブルデータを取得、利用する方法を紹介します。Excelシートとの親和性が高いため、大いに活用できる使用例になるかと思います。
本記事では、今回はSeleniumBaisicの操作(応用編)第3回目として、Web上のテーブルデータ取得の方法について解説していきます。
ブラウザの起動 |
Web操作 |
ブラウザを閉じる |
Web要素のキャッチ |
ウィンドウの操作 |
フレームの移動 |
スクリーンショットの取得 |
HTML情報の取得 |
Cookie情報取得 |
クリック |
文字列入力 |
チェックボックス操作 |
ドラッグアンドドロップ |
ドロップダウンリスト選択 |
ダイアログボックスの操作 |
テーブルデータの取得 |
ファイルダウンロード |
Web要素のプロパティ取得 |
- 利用目的は業務効率化です。(テスト自動化ではありません)
- ブラウザはGoogleChromeが対象です。(EdgeやFirefoxは対象外)
- 原文のVBAでは現在エラー発生する場合が多いため、修正を加えてます。
Examples.xlsmの保存場所(ここをクリック)
Examples.xlsmが保存されている場所は、SeleniumBasicがインストールされているサブフォルダ内になります。SeleniumBasicのインストール完了時に保存フォルダを確認することができます。ただ、大体以下フォルダのどちらかにファイル保存されています。
- C:\Program Files\Seleniumbasic\Examples\Excel
- shell:Local AppData\SeleniumBasic\Examples\Excel
マクロファイル ダウンロード
このページで掲載しているVBAのマクロファイルを以下リンクからダウンロードできます。必要に応じてファイルダウンロードして活用ください。
ダウンロードファイルのマクロ実行注意事項(ここをクリック)
ファイルダウンロード後、マクロ実行するまでの注意事項を記載しておきます。
マクロファイルを実行するには、事前にSeleniumBasicをインストールしておく必要があります。同時にChromeDriverを現在のChromeブラウザのバージョンに合わせて更新しておきます。SeleniumBasicのインストールとChromeDriverの更新については以下記事を参照ください。
マクロファイルを開き、「コンテンツの有効化」をクリックします。
Web上からダウンロードしたマクロファイルはデフォルトで実行できない様に設定されています。ダウンロードしたマクロファイルを開いて以下の様に(このファイルのソースが信頼できないため、Microsoftによりマクロの実行がブロックされました。)表示される場合はファイルプロパティを変更します。
ファイルプロパティを開いて、セキュリティ項目の「許可する」にチェックを入れ、「OK」をクリックする。
VBE(Visual Basic Editor)画面の参照設定を開き、「Selenium Type library」にチェックを入れて、OKをクリックします。
一度ファイルを閉じて、再度ファイルを開き、「コンテンツの有効化」をクリックします。その後、マクロ実行します。ダウンロードファイルは基本的に実行ボタンを実装していませんので、マクロファイルを実行するには、VBEを開き、デバッグ実行によって、スクリプト実行します。
Excelファイルを開いた後、Alt + F11にてVBEエディタを開き、該当のプロシージャまでカーソル移動して、F5にてデバッグ実行します。
ToExcelメソッドのチュートリアル
SeleniumBasicチュートリアルにあるTableElementクラスのToExcelメソッドについて以下に記載します。
Dim instance As TableElement
Dim target As Object
Dim clear As Boolean
Dim firstRowsToSkip As Integer
Dim lastRowsToSkip As Integer
Dim map As String
instance.ToExcel(target, clear, firstRowsToSkip, lastRowsToSkip, map)
target (Optional)
Type: System. Object
Optional - Excel address, worksheet or range. New sheet if null
clear (Optional)
Type: System. Boolean
Optional - If true, the cells will be cleared first
firstRowsToSkip (Optional) ← 利用不可
Type: System. Int32
First row(s) to skip. Ex : 2 will skip the first two rows
lastRowsToSkip (Optional) ← 利用不可
Type: System. Int32
Last row(s) to skip. Ex : 2 will skip the last two rows
map (Optional)
Type: System. String
Optional - Javascript code to scrap each cell. Default: (e)=>e.textContent.trim()
引数の内、"firstRowsToSkip"、"lastRowsToSkip"は指定をしても結果に変化が無かったため、私の使用環境では利用が出来ませんでした。
テーブルデータのExcelシート出力
ホームページに掲載されているテーブルデータをハンドルするメソッドの紹介です。ExcelVBAを利用する以上、これから紹介するメソッドは活用する機会は多くあります。
テーブルデータを一括で取得できる様になると、わざわざWeb要素を一つ一つ指定して取得する必要がなくなり、大変便利になります。
Excelデータ出力の基本構文は以下のとおりです。
driver.FindElementBy***("***").AsTable.ToExcel
"AsTable"メソッドでキャッチしたWeb要素をテーブルデータに変換します。
"ToExcel"メソッドでテーブルデータを出力します。
新たなシートに出力
引数に何も指定が無ければ、新シートを作成し、新シートのA1セルにテーブルデータを出力します。
Private Sub Table_ToExcel_NewSheet()
Dim driver As New ChromeDriver
driver.Get "https://the-internet.herokuapp.com/tables"
driver.FindElementById("table1").AsTable.ToExcel
driver.Quit
End Sub
既存シートにデータ出力
Sheet5が存在している場合、ToExcel引数の"target"でSheet1のA1セルを指定し、テーブルデータを出力します。
Private Sub Table_ToExcel_existSheet()
Dim driver As New ChromeDriver
driver.Get "https://the-internet.herokuapp.com/tables"
driver.FindElementById("table1").AsTable.ToExcel target:=Sheet5.Range("A1")
driver.Quit
End Sub
シート内セルをクリア後データ出力
ToExcelの引数"clear"でTrueを指定し、出力対象のシートをセルクリアしてからExcelデータを出力します。
Private Sub Table_AfterClear_ToExcel()
Dim driver As New ChromeDriver
driver.Get "https://the-internet.herokuapp.com/tables"
driver.FindElementById("table1").AsTable.ToExcel target:=Sheet1.Range("A1"), Clear:=True
driver.Quit
End Sub
JavaScriptでテーブル出力のカスタマイズ
ToExcelの引数"map"でJavaScriptの命令文を指定します。デフォルトでは、"(e)=>e.textContent.trim()"が指定されています。
Private Sub Scrap_Table_ToExcel()
Dim driver As New ChromeDriver
driver.Get "https://the-internet.herokuapp.com/tables"
driver.FindElementById("table1").AsTable.ToExcel target:=Sheet1.Range("A1"), Clear:=True, Map:="(e) => e.firstChild.textContent.trim()"
driver.Quit
End Sub
引数mapで"(e) => e.firstChild.textContent.trim()"が指定されています。
テーブルデータツリー内におけるノードの最初の子を指定し、データ出力しています。どの箇所か、Chromeのディベロッパーツールで確認してみます。
赤枠で囲っている箇所が最初の子を箇所になります。青枠箇所が<td>内でさらにタグが作成されており、最初の子ではないため、"Action"のデータは出力されません。
Web要素からテーブルデータ取得(1列)
FindElementsByにより、テーブルデータ1列分のWeb要素を取得し、取得したオブジェクトをイミディエイトウィンドウに出力します。
Private Sub Handle_Table()
Dim driver As New ChromeDriver
driver.Get "https://the-internet.herokuapp.com/tables"
Dim eles As WebElements, ele As WebElement
Set eles = driver.FindElementsByCss("#table1 tbody tr td:nth-child(2)")
For Each ele In eles
Debug.Print ele.Text
Next ele
driver.Quit
End Sub
- 5行目
-
First Name列のWeb要素のデータをFindElementsByCssで取得
- 6~8行目
-
For Eachでelesを回して、Web要素のデータをイミディエイトウィンドウに出力
First Name列の1行目データ("Tim")css取得値(加工前)と5行目の検索値(加工後)を比較すると、以下になります。
・加工前
#table1 > tbody > tr:nth-child(1) > td:nth-child(2)
・加工後
#table1 tbody tr td:nth-child(2)
緑色の文字列を削除して、FindElementsByCssの値に入力すると、First Name列(2列目)のデータを取得します。">"は有っても無くても結果は同じになります。重要なのは、”:nth-child(1)”を削除して、複数行の値を取得させる事です。
Web要素からテーブルデータ取得(全データ)
FindElementsByにより、テーブルデータ全体のWeb要素を取得し、取得したオブジェクトイミディエイトウィンドウに出力します。
Private Sub Handle_Table2()
Dim driver As New ChromeDriver
driver.Get "https://the-internet.herokuapp.com/tables"
Dim tbl As Selenium.TableElement
Set tbl = driver.FindElementByCss("#table1").AsTable
Dim data(): data = tbl.data
Dim C As Integer, r As Integer
For C = 1 To UBound(data, 1)
For r = 1 To UBound(data, 2)
Debug.Print data(C, r)
Next r
Debug.Print Empty
Next C
driver.Quit
End Sub
- 4行目
-
SeleniumのTableElementを宣言します。
- 5行目
-
FindElementByCss("#table1").AsTableメソッドにてExample 1のテーブルデータを取得します。
- 6行目
-
data()にて、2次元配列としてテーブルデータを代入。(テーブルデータが2次元配列のため、自動的に2次元配列として代入される)
- 7~13行目
-
For Nextループにて2次元配列をイミディエイトウィンドウに出力。