こんにちは、blueです。
今回はSelenium Basicを用いたVBAでのTable取得方法2について説明します。
前回の記事はこちら
前回は(tbodyタグを含んだ)tableタグから表情報を取り出すというものを行いました。
この場合はAsTableメソッドで表の一括取得が可能でしたが、異なるテーブルも多く存在します。
今回は別テーブルの取得方法について説明します。
なお、テーブル形式といっても1種類ではありません。その為2回に分けて説明します。
ちなみに他サイトの引用ですがスクレイピングに関しては使用方法によっては違法となるケースも存在します。
スクレイピングは違法?3つの法律問題と対応策を弁護士が5分で解説
IT弁護士に聞く「企業としてのスクレイピングは違法なのか?」
使用に関しては自己判断でお願いします。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
HTMLとCSSを基礎から学びたいという方はこちらの書籍がお勧めです。章ごとの最初にポイントがまとめられていたり、対話形式で理解する部分もあったりで理解しやすいように工夫されています。
今回のゴール
今回のゴールは以下になります。
- (dl,dt,ddを含んだ)tableタグから表情報を取り出す
以降で詳しく説明します。
HTML構造
今回取得する表の構造は以下のようになります(引用元:都道府県の人口一覧 – Wikipedia
ちなみに実際の表は今回の形式ではないのでスクレイピングはできません)
都道府県 | 2020年 |
東京都 | 14,047,594 |
神奈川県 | 9,237,337 |
大阪府 | 8,837,685 |
愛知県 | 7,542,415 |
埼玉県 | 7,344,765 |
千葉県 | 6,284,480 |
兵庫県 | 5,465,002 |
北海道 | 5,224,614 |
福岡県 | 5,135,214 |
静岡県 | 3,633,202 |
表は2列で1列目は重複のない項目になっています。
HTML構造は以下のようになります。
<div class="table">
<table>
<dl>
<dt>都道府県</dt>
<dd>2020年</dd>
<dt>東京都</dt>
<dd>14,047,594</dd>
<dt>...</dt>
<dd>...</dd>
</dl>
</table>
</div>
これは説明(定義)リストと呼ばれます。
dl,dt,ddの意味は以下のようになります。
- dl(description list)= 説明リスト
- dt(description term)= 説明する項目
- dd(definition / description)= 説明文
もともとは定義リストと呼ばれていて、dtの説明をddでするといった辞書的な書き方で使われます。
説明リストについては以下のサイトに詳しく書かれていました。
なお、このdt,ddに関してはdtが1つに対してddが1つというルールもないのですが、今回は1対1であると考えて処理します。
VBAでのコード
実際のコードは以下になります
Sub test()
Dim Driver As New Selenium.WebDriver
Dim elm As WebElement
Dim arr As Variant
Dim dic As New Scripting.Dictionary
Dim i As Long
Dim j As Long
Driver.Start "Chrome"
Driver.Get "(URLサイト)"
'クラス名「table」のタブを取得
Set elm = Driver.FindElementByClass("table")
'テキストデータを改行コード毎に切り分け配列格納
arr = Split(elm.Text, vbLf)
'配列の偶数をKey、奇数をValueとして辞書型に格納
For i = 0 To UBound(arr)
dic.Add arr(i), arr(i + 1)
i = i + 1
Next i
With ThisWorkbook.Worksheets("出力")
'表を出力する1
For j = 0 To dic.Count - 1
.Cells(j + 1, 1).Value = dic.Keys(j)
.Cells(j + 1, 2).Value = dic.Items(j)
Next
End With
End Sub
各コードの説明
次に各コードについて説明します。
Dim dic As New Scripting.Dictionary
今回は連想配列Dictionaryを用いてデータを格納します。
なおDictionaryを用いる際は最初に参照設定が必要になるので注意ください。
Dictionaryに関しては以下に詳しく書かれています。
連想配列は今回のように1列目Key,2列目値といったような項目を取得する際便利です。
'クラス名「table」のタブを取得
Set elm = Driver.FindElementByClass("table")
次に表を特定するためにtableというクラス名を持つ要素を取得します。
'テキストデータを改行コード毎に切り分け配列格納
arr = Split(elm.Text, vbLf)
WebElement.Textで要素内のテキストを全取得します。
この取得したテキストはvbLf(Lf:ラインフィード。次の行へ移るコード)で区切られている一行テキストです。
しかし一行テキストのままでは表として処理できない為Split関数で一次元配列に変換します。
'配列の偶数をKey、奇数をValueとして辞書型に格納
For i = 0 To UBound(arr)
dic.Add arr(i), arr(i + 1)
i = i + 1
Next i
配列の偶数をKey,奇数をValueとしてDictionaryに格納します。
なお格納はAddメソッド Key,値で可能です。
With ThisWorkbook.Worksheets(1)
'表を出力する
j = 1
For Each key In dic.Keys
.Cells(j, 1).Value = key
.Cells(j, 2).Value = dic.Item(key)
j = j + 1
Next
End With
ここではDictonaryに格納した配列を出力しています。
DictionaryのKeysメソッドはKeyの一覧を一次元配列として返してくれます。
Dictionaryの中身の出力に関しては以下の記事が参考になります。
この性質を利用して一次元配列から一つずつKeyを取り出してKeyと値をセルに格納しています。
このようにして、説明リスト型のテーブルを出力できます。
今回のまとめ
今回は
- (dl,dt,ddを含んだ)tableタグから表情報を取り出す
方法について説明しました。
なお今回はテーブル内の全データを取得したのちに2次元配列に成形しています。
2次元配列の作成方法さえ理解していれば、普通の配列でも今回のような連想配列でも問題ありません。
前回のようにAsTableで表全体を一括取得できる方法がない場合は参考ください。
↓困ったときは以下が頼りになります。私も利用させてもらってます😊。
Selenium-VBAでのWebスクレイピングに関する記事はこちらをどうぞ
【ExcelVBA‐Selenium】【永久保存版】スクレイピングに必要なSeleniumのインストール方法教えます
【Selenium-VBA】Yahooメールへのログイン方法をわかりやすく説明する
ChromeでのWebスレイピングをできる限りわかりやすく説明する(Excel VBA)
【ExcelVBA‐Selenium】Chrome driverのバージョンエラーが出た時の対処法(2021/10/7更新)
【Selenium-VBA】Seleniumを用いたスクレイピングでテーブル情報を取得する1
【Selenium-VBA】スクレイピングをするのに必要なHTMLについて説明します1
【Selenim-VBA】起動済みのChromeを用いてSeleniumによるスクレイピングを行う
【Selenium-VBA】JavaScriptを使ってスクレイピングをしてみる1
【VBA】SeleniumBasicにおけるクラス、メソッド、プロパティ一覧(日本語版)
Web-APIを用いたデータ取得に関する記事はこちらをどうぞ
【VBA】Web APIを使ってデータを取得する(OpenWeatherMap)1
【VBA】Web APIを使って時間別天気予報を取得する(気象庁API)
【VBA】Web APIを使ってLINE通知を行う(LINE Notify)1
コメント