Excel VBAからIEを操作する
はじめに
何番煎じかわかりませんが,ExcelからIE操作をトライしました.
モチベーションは以下の通りです. * VBAの練習 * 自然言語処理の題材として,スクレイピングをやってみたい
自然言語処理のイメージとしては,SNSの情報を吸いだしてデマの検証をするとか,株価の予想をするとか,そういったものを想像しています.なお,私のAI系の知識はcourseraの機械学習のコースを修了した程度です.要するに,得た知識を使ってみたいというのがモチベーションですね.
IEの起動
IEを起動してそのインスタンスを取得するのは簡単で,以下の1行で出来ます.
Set ie = CreateObject("InternetExplorer.Application")
これを用いたIEの取得及び表示設定の初期化を行う以下の関数を作りました.
'IEオブジェクトを取得して初期化する Private Function init_ie_obj() As Object Dim ie As Object Set ie = CreateObject("InternetExplorer.Application") With ie 'ieの表示設定 .AddressBar = False'アドレスバー非表示 .MenuBar = False'メニューバー非表示 .StatusBar = False'ステータスバー非表示 .Toolbar = False'ツールバー非表示[f:id:kshige00:20200811031514p:plain] .Visible = True'画面表示を有効にする End With Set init_ie_obj = ie'取得したieオブジェクトを戻り値として返す End Function
IEオブジェクトからのデータの入出力方法
取得したIEオブジェクトからアクセス先のwebページにデータを入力する(ボタンクリック,テキスト入力など)もしくは読み出す(テキスト,画像など)ためには,アクセス先のwebページのデータ構造を把握する必要があります. これは,IE上で右クリック→ソースの表示をクリックすると見ることができます.
google翻訳でやってみると以下のような画面になり,画面下部にデータ構造が表示されます.
この画面上で,欲しい情報を持つ要素を右クリック→要素の検査をクリックすると,その要素に対応するコードがハイライトされます. 翻訳したい英文を入力するテキストボックスについて行うと,以下の画面となります.
英文を入力するテキストボックスのクラス名は"orig tlid-source-text-input goog-textarea"で,idは"source"であることが分かりました.
取得したい要素のクラス名もしくはidが分かれば,以下のコードでその要素のオブジェクトを取得することができます.
idを使う場合:
Set ElementObj = ie.document.getElementById("id name")
クラス名を使う場合:
Set ElementObj = ie.document.getElementsByClassName("class name")(0)
クラス名を使う場合は文末に(0)が付きます.これは,getElementsByClassNameは"class name"をクラス名に含む要素を全て取得して配列風に返すメソッドだからです.目的の要素だけを取り出すためには,配列の1番目の要素を取得するという意味で(0)をつけてやる必要があります.なお,"class name"に該当する要素が複数個ある場合は,欲しい要素が該当する番号を設定すればよいです.
idを用いる場合はこのような番号指定の必要はありません.これは,idはdocumentオブジェクト内で固有であり,要素を一意に指定できるためです.idが分かる場合は,idを用いて要素にアクセスするのが便利だと言えます.
要素のオブジェクトを取得出来たら,VBAのエディター上のローカルウインドウでオブジェクト内のデータを見ることができます. オブジェクトのメンバである.innerTextや.textContentを読み書きすることで,テキストデータの入出力が可能です. また,.clickメソッドを使うことで,対象の要素(ボタンなど)をクリックすることができます.
(参考サイト)
google翻訳の自動化
以上の情報を使って,google翻訳の自動化ソフトを作ってみました. 1列目の英文を1つずつgoogle翻訳に投げて,2列目に結果を入れていくというものです.
全コードは以下になります.
'IEオブジェクトを取得して初期化する Private Function init_ie_obj() As Object Dim ie As Object Set ie = CreateObject("InternetExplorer.Application") With ie 'ieの表示設定 .AddressBar = False 'アドレスバー非表示 .MenuBar = False 'メニューバー非表示 .StatusBar = False 'ステータスバー非表示 .Toolbar = False 'ツールバー非表示 .Visible = True '画面表示を有効にする End With Set init_ie_obj = ie '取得したieオブジェクトを戻り値として返す End Function 'ieがビジー状態じゃなくなるまで待つ Private Sub wait_ie_ready(ByRef ie As Object) Const READYSTATE_COMPLETE = 4 Do While ie.Busy = True Or ie.ReadyState <> READYSTATE_COMPLETE DoEvents Loop End Sub '引数のテキストをgoogle翻訳する Private Function GoogleTranslate(ByVal text As String, ByRef ie As Object) Dim url As String Dim ElemObj As Object Dim try_cnt Dim try_cnt_max try_cnt_max = 10 'ieがgoogle翻訳を開いていない場合,google翻訳にアクセスする url = "https://translate.google.co.jp/?hl=ja" If InStr(ie.LocationURL, url) = 0 Then ie.Navigate url End If wait_ie_ready ie 'ieがビジー状態の間待機 '翻訳する文章を入力欄に入力 Set ElemObj = ie.document.getElementById("source") ElemObj.innerText = text wait_ie_ready ie 'ieがビジー状態の間待機 GoogleTranslate = "error" try_cnt = 0 Do While try_cnt < try_cnt_max Application.Wait Now() + TimeValue("00:00:01") On Error Resume Next Set ElemObj = ie.document.getElementsByClassName("result-shield-container tlid-copy-target")(0) '翻訳結果を取得 GoogleTranslate = ElemObj.innerText On Error GoTo 0 If GoogleTranslate = "error" Then try_cnt = try_cnt + 1 Else Exit Do End If Loop End Function Sub sample() Dim wb Dim ws Dim str_en As String Dim str_jp As String Set wb = ThisWorkbook Set ws = wb.Worksheets("Sheet1") Dim ie As Object Dim cnt 'IEを起動 Set ie = init_ie_obj() '1列目を走査して,データがある限り翻訳を行う.結果は2列目に書き込む. cnt = 0 While (ws.Cells(cnt + 6, 1)) <> "" empty_cnt = 0 Application.Goto Cells(cnt + 5, 1), True If ws.Cells(cnt + 6, 2).text = "" Or ws.Cells(cnt + 6, 2).text = "error" Then str_en = ws.Cells(cnt + 6, 1).text str_jp = GoogleTranslate(str_en, ie) ws.Cells(cnt + 6, 2) = str_jp End If cnt = cnt + 1 Wend 'IEを終了 ie.Quit End Sub
Twitterのスクレイピング
いよいよスクレイピング!ということで,同様のやり方でTwitterのスクレイピングツールを作りました.作った直後は動いていたのですが(5月),その後IEでのTwitter閲覧のサポートが打ち切られてしまったらしく,IEからTwitterを見ることは出来なくなってしまいました...(2020/8/11現在)
chromeなどを使ったやり方に切り替えていく必要があるようです. これはSeleniumなるものを使えばできるようです.そのうちトライしようと思います.
まとめ
VBAからのIE操作にトライし,その基本的な方法をまとめました.IEの起動や更新方法などについては解説しているサイトが多く,すんなり出来たのですが,抽出したい要素のオブジェクトを取得したり,その内部のデータを読み書きする方法については結構嵌まりました(私のweb関係の知識不足のせい).苦労した点について多少詳しく解説したつもりです.何かの役に立ちましたら幸いです.