
photo credit: Cristian Ştefănescu He was a friend of mine via photopin (license)
みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
エクセルVBAでIEスクレイピングをするときに便利なクラスの作り方をお伝えしております。
前回の記事はこちら。

リンクテキストでa要素を探してリンクする方法でした。
今回のテーマはテーブルデータの取得です。
普通に処理書くとわりと面倒なので、クラスのメンバーとして定義しておけば簡単にできそうですよね…!
ということで、エクセルVBAでIEを操作するクラスにテーブルのデータを取得するメソッドを追加する方法です。
では、行ってみましょう!
前回のおさらい
では、前回のおさらいからです。
まずIEを操作するクラスIEObjectです。
Public IE As InternetExplorer Public Document As HTMLDocument Private Sub Class_Initialize() Set IE = New InternetExplorer IE.Visible = True End Sub Private Sub Class_Terminate() IE.Quit End Sub Public Sub Navigate(ByVal url As String) IE.Navigate url Wait Set Document = IE.Document End Sub Public Sub Wait() Do While IE.Busy = True Or IE.readyState < READYSTATE_COMPLETE DoEvents Loop End Sub Public Function GetElementByLinkText(ByVal text As String) As HTMLAnchorElement Set GetElementByLinkText = Nothing Dim anchor As HTMLAnchorElement For Each anchor In Document.Links If anchor.innerText = text Then Set GetElementByLinkText = anchor Exit Function End If Next anchor End Function
前回は、GetElementByLinkTextメソッドを作りました(今回の内容で関わるメンバーだけ掲載しています)。
検証するための標準モジュールのプロシージャがこちらでした。
Sub MySub() Dim ieObj As IEObject: Set ieObj = New IEObject ieObj.Navigate "https://tonari-it.com" Dim text As String: text = "詳細・お申込はこちら" Dim anchor As HTMLAnchorElement Set anchor = ieObj.GetElementByLinkText(text) If Not anchor Is Nothing Then ieObj.Navigate anchor.href Else Debug.Print text; "をテキストとするa要素はありませんでした" End If Stop End Sub
Webページのテーブルデータを取得する
今回はガラっとネタが変わりまして、Webページのテーブルデータを取得する便利メソッドを作っていきます。
こちらのYahooファイナンスの時価総額ランキングのページから、時価総額順位のテーブルデータを取得していこうというものです。
ページを開いたイメージはこちらです。
幸い、このページにはテーブル要素はひとつしかありませんので、その取得は容易です。
あとは、その内部のtr要素、そしてさらにその配下のth要素、td要素をループで取り出せればOKということですね。
テーブルデータを取得して出力するメソッド
まずは、table要素を渡すと、その内部のデータをイミディエイトウィンドウに出力するPrintTableDataメソッドを作ってみました。
こちらです。
Public Sub PrintTableData(ByVal table As HTMLTable) Dim tr As HTMLTableRow For Each tr In table.getElementsByTagName("tr") Dim th As HTMLTableCell For Each th In tr.getElementsByTagName("th") Debug.Print th.innerText, Next th Dim td As HTMLTableCell For Each td In tr.getElementsByTagName("td") Debug.Print td.innerText, Next td Debug.Print Next tr End Sub
複雑そうに見えますが、テーブルの構造がわかっていれば以外と簡単です。
まず、table要素をHTMLTableオブジェクトとしてパラメータtableで受けます。
その配下には行を表すtr要素がありますから、その全てについてループを回します。それが4~17行目からのループです。
さらに、行の中には見出しセルを表すth要素、もしくはtd要素がありますから、それぞれ存在するすべてについてループを回して、その内容をinnerTextプロパティで取得してデバッグ出力しています。
テーブルデータ取得メソッドの動作確認
では、このPrintTableDataメソッドを動作確認してみましょう。
以下のプロシージャを標準モジュールに記述して実行してみます。
Sub MySub() Dim ieObj As IEObject: Set ieObj = New IEObject With ieObj .Navigate "https://info.finance.yahoo.co.jp/ranking/?kd=4" .PrintTableData .Document.getElementsByTagName("table")(0) End With End Sub
かなりシンプルに書けますよね。
実質、URLのアクセスをするNavigateメソッドと、テーブルを指定して出力するPrintTableDataメソッドの2行だけです。
実行をすると、イミディエイトウィンドウに、以下のようにテーブル内のデータが出力されます。
まとめ
以上、エクセルVBAでIEを操作するクラスにテーブルのデータを取得するメソッドを追加する方法をお伝えしました。
テーブルの構造がきれいに揃っていないとちょっとうまくいかない場合もあるので注意です。
さて、次回はせっかくデータを取得したので、シートに出力をするように変更していきたいと思います。
どうぞお楽しみに!