こんにちは!あつもり(@atumori17)です。
VBScriptでIEを操作してWEBスクレイピング!の第8回目で~す。
前回は「ページ内にあるhタグを取得してHTMLとして書き出す」ところまでやりました。
今回は「ページ内にあるテーブル要素を取得してCSVファイルとして書き出す」方法を紹介します。
前回のhタグはHTMLファイルとして書き出しましたが、今回はCSVファイルに書き出していきます。
というのも取得した情報をCSVファイルで書き出しておけば、他のアプリケーションへの流用が効くので便利だからです。特にエクセルとの相性は抜群ですっ。
テーブル要素を取得してCSVファイルで書き出すスクリプト
ではまずスクリプトの全文を紹介します。テキストエディタを開き下記のコードを入力します。全て入力し終わったら「テーブル要素をCSVで書き出す.vbs」のファイル名でデスクトップに保存します。
Option Explicit Dim objIE Dim objLink Set objIE = CreateObject("InternetExplorer.Application") objIE.Visible = True 'IEを開く objIE.navigate "http://elze.tanosii.net/d/kenmei.htm" 'ページが読み込まれるまで待つ Do While objIE.Busy = True Or objIE.readyState <> 4 WScript.Sleep 100 Loop Dim objTr,objTh,objTd Dim el 'tr要素をコレクションとして取得して変数にセット Set objTr = objIE.document.getElementsByTagName("tr") 'テーブル要素をcsvファイルに書き出す For each el In objTr If instr(el.outerhtml,"<th>") > 0 then Set objTh = el.getElementsByTagName("th") OutputText objTh(0).innerText & "," & objTh(1).innerText & "," & objTh(2).innerText Else Set objTd = el.getElementsByTagName("td") OutputText objTd(0).innerText & "," & objTd(1).innerText & "," & objTd(2).innerText End If next 'テキストファイルへ出力 Function OutputText(ByVal strMsg) Dim objFSO Dim objText Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Set objText = objFSO.OpenTextFile("C:\work\テーブル要素の書き出し結果.csv", 8, True) objText.write strMsg objText.write vbCrLf objText.close Set objFSO = Nothing Set objText = Nothing End Function
プログラムコードの解説
全体の流れは以下のようになります。
- IEでページを開く
- IEの読み込み待ちをする
- tr要素をコレクションとして取得する
- th、td要素をコレクションとして取得する
- 取得したth、td要素をCSVファイルに書き出す
今回はまずtr要素をコレクションとして取得してから、th、tdの要素内容をCSVファイルに書き出していきます。
HTMLのテーブル要素の仕組み
コードの説明に入る前にHTMLのテーブルの仕組みについて少しお話したいと思います。
HTMLで言うテーブルとは表のことです。テーブルは<table>、<tr>、<td>といったタグでできています。
今回テーブル要素を取得するのに下記のサイトを参考にさせていただきました。
エルゼの森というサイトで全国の県庁所在地の情報が載っています。
それではまずは下の画像を見て下さい。
大枠のテーブルはtable要素からできていて、その中に行を定義するtr要素が入っています。
さらにtr要素の中に見出しを定義するth要素、表のデータを定義するtd要素が入っています。
table要素→tr要素→th要素、td要素というように入れ子になっているんですね。
実際のHTMLコードと見比べてみると何となくイメージがつかめると思います。
tableタグの中にtrタグ、thタグ、tdタグが入れ子になっているのがわかると思います。
<table> <tr> <th></th> <td></td> </tr> </table>
同じような名前のタグが並ぶので始めは理解しずらいかもしれませんね。しかしHTMLのテーブル構造はWEBスレイピングを行ううえでとても重要になりますので、しっかり覚えておきましょう。
getElementsByTagNameメソッドでテーブル内のデータを取得する
それでは早速テーブル要素を取得してみたいと思います。
まずはtr要素をコレクションとして取得し、For Each文を使って取得したtr要素ぶんだけ繰り返す処理を行います。上記プログラムコードの21~34行目になります。
'tr要素をコレクションとして取得して変数にセット Set objTr = objIE.document.getElementsByTagName("tr") 'テーブル要素をcsvファイルに書き出す For each el In objTr 'th、td要素を書き出す処理 next
outerhtmlプロパティでtr要素をタグごと取得する
For Each文でtr要素ぶんだけ繰り返しますが、まずtr要素をouterhtmlプロパティを使ってタグごと抜き出します。
今回の場合、outerhtmlで抜き出したデータは
のようになります。
InStr関数を使ってタグ名ごとに処理を変える
続いてouterhtmlで抜き出したtr要素にthタグが含まれているかを調べます。そのためにInStr関数を使います。
InStr関数は検索対象の文字列に検索したい文字があった場合、その文字がある位置を返す関数です。今回のプログラムではthタグがあるか調べたいので、thを検索したい文字に指定しています。
検索したい文字がなかった場合は0を返します。反対に文字があった場合は整数を返すわけです。そのことを利用して0より大きい場合はIF以下の処理をするというようにしています。
If instr(el.outerhtml,"<th>") > 0 then 'th要素を書き出す処理
つまりInStr関数でtr要素にthタグが含まれているかどうかを調べ、
- thタグだったら、innerTextでth要素内のテキストデータをCSVファイルで書き出す
- thタグでなかったら、innerTextでtd要素内のテキストデータをCSVファイルで書き出す
というように処理を分けています。
なぜ処理を分けるのかというと、取得したtr要素にth要素がなかった場合エラーになるためです。
Set objTh = el.getElementsByTagName("th") OutputText objTh(0).innerText & "," & objTh(1).innerText & "," &
ここでオブジェクト変数objThにth要素のコレクションを入れていますが、取得したコレクションの中にth要素がなかった場合、次の行でエラーになります。OutputText関数に渡す引数であるobjTh(0)が存在しないためです。
th要素をコレクションとして取得してCSVファイルに書き出す
続いてtr要素からth要素をコレクションとして取得します。今回の場合、th要素は表の一番上にある見出し部分だけです。つまり見出しセルに入っていて太字で表示されている、
県番号、都道府県名、県庁所在地
になります。この見出しデータを取り出すには
- tr要素からth要素をコレクションとして取得する
- 取得したコレクションの1~3番目のth要素のテキストをCSVに書き出す
という流れになります。
まずth要素として取得したコレクションをオブジェクト変数objThにをセットします。
取得したth要素のコレクションは配列として0番目から変数objThに格納されますので、0~2番目を指定しています。
CSVファイルに書き出すのはth要素内のテキストデータだけにしたいので、innerTextプロパティを使います。
Set objTh = el.getElementsByTagName("th") OutputText objTh(0).innerText & "," & objTh(1).innerText & "," & objTh(2).innerText
これで表の見出しであるth要素をCSVファイルに書き出すことができました。
td要素をコレクションとして取得してCSVファイルに書き出す
続いてtr要素からtd要素をコレクションとして取得します。td要素は表の中のデータですね。
1、北海道(ほっかいどう)、札幌(さっぽろ)
などのデータになります。th要素と同じ手順で
- tr要素からtd要素をコレクションとして取得する
- 取得したコレクションの1~3番目のtd要素のテキストをCSVに書き出す
というような流れで行います。
さきほとと同じように、CSVファイルに書き出すのはtd要素内のテキストデータだけにしたいので、innerTextプロパティを使います。
Set objTd = el.getElementsByTagName("td") OutputText objTd(0).innerText & "," & objTd(1).innerText & "," & objTd(2).innerText
CSVにデータを書き出す方法については過去の記事で紹介していますので参考にしてみてください。
プログラムコードの解説は以上です。
table要素をCSVファイルで書き出してみる
では実際にアプリケーションを起動してみます。デスクトップにある「table要素をCSVで書き出す.vbs」をダブルクリックします。
C:\workフォルダに「テーブル要素の書き出し結果.csv」ファイルができました。
テキストエディタで開くとテーブル要素が取得されたのがわかりますね。
さらにエクセルで開いてみるとこんな感じでセルごとにデータが分かれて表示されます。エクセルとの相性がいいところが、CSVファイルの良いところですよね~。
まとめ
いかかでしたか?今回の内容をまとめると以下のようになります。
- tableの仕組みを理解することはWEBスクレイピングをやる上で重要なポイントです
- コレクションとして取得したtr要素から、さらにth、td要素をコレクションとして取得する
- CSVファイルで書き出しておくとエクセルで開けるので便利
今回は以上です。それではお疲れさまでした~。
連載目次:VBScriptでお手軽WEBスクレイピング
Windowsを操作できるプログラミング言語「VBScript」を使えば、InternetExplorerを操作してWEBスクレイピングが可能です。 これで日々の情報収集はダブルクリック一発で完了させましょう!- VBScriptでInternet Explorerを使って複数WEBサイトをダブルクリック一発で開く方法
- VBScriptでWEBスクレイピング!ファイルシステムオブジェクトでテキストに書き出す
- VBScriptでWEBスクレイピング!HTMLドキュメントとタイトルを取得する方法
- VBScriptでWEBスクレイピング!ブラウザの読み込み待ちをしてエラーを回避する
- VBScriptでWEBスクレイピング!aタグのリンクURLを全部取得する方法
- VBScriptでWEBスクレイピング!aタグのリンクURLをHTMLとして書き出す
- VBScriptでWEBスクレイピング!hタグを取得してHTMLとして書き出す
- VBScriptでWEBスクレイピング!テーブル要素を取得してCSVファイルで書き出す
- VBScriptでWEBスクレイピング!アメブロの管理画面に自動でログインする方法
- VBScriptでWEBスクレイピング!アメブロの投稿記事一覧をテキストファイルに書き出す方法