こんにちは、blueです。
今回はSeleniumBasicを用いたVBAでのTable取得方法について説明します。
これまでのスクレイピングはWebサイト内の単一要素の取得や操作がメインでした。
これでも多くの自動化は達成できました。
しかし、スクレイピングによる大量データの取得も魅力的です。
そこで今回はテーブル形式で構成されている表の取得について説明します。
なお、テーブル形式といっても1種類ではありません。その為2回に分けて説明します。
ちなみに他サイトの引用ですがスクレイピングに関しては使用方法によっては違法となるケースも存在します。
スクレイピングは違法?3つの法律問題と対応策を弁護士が5分で解説
IT弁護士に聞く「企業としてのスクレイピングは違法なのか?」
使用に関しては自己判断でお願いします。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
HTMLとCSSを基礎から学びたいという方はこちらの書籍がお勧めです。対話形式で書かれているので読みやすく、スクレイピングをする際にポイントとなるタグについても一つずつ丁寧に説明してくれています。
今回のゴール
今回のゴールは以下になります。
- (tbodyタグを含んだ)tableタグから表情報を取り出す
以降で詳しく説明します。
HTMLの構造
今回取得する表の構造は以下のようになります。
<div class="table_box">...</div>
///
///
<div class="table_box">
<table>
<tbody>
<tr class="****">...</tr>
<tr class="****">...</tr>
<tr class="****">...</tr>
</tbody>
</table>
</div>
HTMLでのテーブルは<table>~</table>という形で表現されます。
またその中に<tbody>~</tbody>、<tr>~</tr>というタグが存在しており、このように記載することで階層構造になっています。
今回は<table><tbody>~</tbody></table>というようにtbodyタグを含んだtableタグから情報を抜き出します。
なお上にある<div class=”table_box”>については実コードで説明します
VBAでのコード
実際のコードは以下になります
Sub Table情報取得()
Dim Driver As New Selenium.WebDriver
Dim arr As Variant
Driver.Start "Chrome"
Driver.Get "(URLサイト)"
arr = Driver.FindElementsByClass("table_box")(2).FindElementByTag("table").AsTable.Data
With ThisWorkbook.Worksheets(1)
.Range(.Cells(1, 1), .Cells(UBound(arr, 1), UBound(arr, 2))).Value = arr
.Columns.AutoFit
End With
End Sub
各コードの説明
次に各コードについて説明します
arr = Driver.FindElementsByClass("table_box")(2)
今回の目的は「tableタグから表情報を取り出す」とのことでした。
ただし一般的にサイトにはTableが含まれるタグが複数存在します。
この場合一つを特定するのは困難です(なお検索の仕方は補足をどうぞ)。
その為まずは上位の要素にあたるtable_boxというクラス名を持つ要素を取得します。
この要素も同じタグを持つ場合がありますがFindElements(index)で取得することが可能です。
(なお1個であればFindElementでもOKです。また詳しく記事にします)
今回はこのタグの名前を持つ2つ目の要素を取得するのがこのコードになります。
FindElementByTag("table")
ここではFindElementsByClass(“table_box”)(2)内にあるTableタグを取得します。
前回までで上位の階層を絞ったので今回は中にある1つのTableタグのみで取得することが可能です。
AsTable.Data
FindElementに対するメソッドです。AsTableとすることでテーブル型に変更します。
またDataメソッドでhtml型のテーブルからデータを二次元配列として取得します。
実際取得したarrをローカルウィンドウで見てみると・・・(途中Stop等を入れて止めてください)
2次元配列として取得できていることがわかります。
なおこのAsTableメソッドはtbodyを持つ要素からしかテーブル型を作成できません。
違うTableで作成すると・・・
このようなエラーが出てとまります。
Expected=table.tbodyと書かれていることからtbodyタグが必須であることに注意ください。
With ThisWorkbook.Worksheets(1)
.Range(.Cells(1, 1), .Cells(UBound(arr, 1), UBound(arr, 2))).Value = arr
.Columns.AutoFit
End With
ここは二次元配列をExcelに出力するコードになります。
今回はarr(50,50)のように50行50列の二次元配列が得られたのでUBound関数を用いてそれぞれの行数と列数を取得して対象範囲に貼り付けています。
最後の.Columns.AutoFitは列幅を自動調整しているだけです。
またTable型の要素をExcelに出力する場合は以下のように1行で記載することもできます。
Driver.FindElementsByClass("table_box")(2).FindElementByTag("table").AsTable.ToExcel [Sheet1!A1]
ToExcelメソッド以下の書き方についてはSelenium documentationに以下のように書かれていますのでご参考ください。
Selenium documentationに関してはこちら
ちなみに貼り付け位置はExcelでのセル参照の書き方と同じでブラケット([])で囲うことになっているので注意ください。
今回のまとめ
今回は
- (tbodyタグを含んだ)tableタグから表情報を取り出す
方法について説明しました。
なお中で説明したようにAsTableメソッドで変換できる要素はtbodyタグを持つTableのみになります。
別のTableについてはこの方法では取得できませんので次回以降に説明しますが、参考にしていただければ幸いです。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
HTMLとCSSを基礎から学びたいという方はこちらの書籍がお勧めです。対話形式で書かれているので読みやすく、スクレイピングをする際にポイントとなるタグについても一つずつ丁寧に説明してくれています。
↓困ったときは相談してみては?私も利用させてもらってます😊。
SeleniumBasicでのWebスクレイピングに関する記事はこちらをどうぞ
Web-APIを用いたデータ取得に関する記事はこちらをどうぞ
【VBA】Web APIを使ってデータを取得する(OpenWeatherMap)1
【VBA】Web APIを使って時間別天気予報を取得する(気象庁API)
【VBA】Web APIを使ってLINE通知を行う(LINE Notify)1
補足
Tableという要素がいくつかあるかは検索ツールを使うことで調べることが可能です。
デベロッパーツールを立ち上げた状態で「Ctrl+Shift+F9」あるいは以下の「検索」をクリックします。
そのうえで出てきた検索窓にTableとクリックすると以下のような表示が出てきます。
ここにはjavascript(ファイル名は~.js).css(ファイル名は~.css)といったものからの検索値も出ています。
今回はhtmlの為下を見ていくと・・・
cvd1.htmlには多くのtableタグが存在することがわかります。
コメント