VBAでIE操作(InternetExplorer操作)
ExcelVBAマクロでIEを操作し、Webスクレイピング、Webクローリングをする事が可能です。
マクロがインターネットエクスプローラーを自動で操作し、
WEBのデータ取得・登録などの、各種WEB操作します。
VBAでIE操作のエラーで困ること
どの環境でも出るのであれば、コードがおかしい為デバッグ処理をすれば問題ありません。
しかし、エラーはパソコンや回線の環境、サイトによってエラー発生するタイミングが異なることです。
エラーに負けず、うまく付き合っていく必要があります。
エラーに負けない
エラーが出るタイミングは同一でなくても、対策は立てられます。
InternetExplorerMediumで起動する
IE側の設定で保護モードが悪い影響を与えるケースがあります。
急に保護モードが切り替わることで、エラーが発生します。
(セキュリティゾーンをまたぐと、セッション維持できない)
下記のように「New InternetExplorerMedium」を使用して、明示します。
'■CreateObjectで作成しない(保護モードが明示されていない) Set objIE = CreateObject("InternetExplorer.Application") '■保護モードを中(MediumIL)で明示して起動する Set objIE = New InternetExplorerMedium
objIEは使いまわす
プログラム上で何度もIE起動する場合はobjIEを解放せず、使いまわします。
「objIE = Nothing」としてもNothingにならず、オートメーションエラーが出る場合があります。
下記のようなコードは、すぐに「Set objIE = Nothing」をコメントアウトしてエラー回避しましょう。
objIE.Quit Set objIE = Nothing
IEのプロセスを終了させる
上記のobjIEの使いまわしだけでは、実は不十分です。(使いまわすことでIEのプロセスが残る場合もある)
下記のようにobjIEを起動前にIEのタスクを終了させます。
この動作を入れる事、VBAでのIE操作は安定します。
'■InternetExpolerのタスクを終了する Public Function Call_IE_TaskKill() Dim objShell As Object Dim objExec As Object Set objShell = CreateObject("WScript.Shell") Set objExec = objShell.Exec("taskkill.exe /F /IM iexplore.exe") End Function
BusyやreadyStateは信用しない
前記事のブラウザの読込待ち処理ですが、待機処理が安定しない場合があります。
下記のように何度も待機処理をさせたり、
For i =1 to 5 call Call_IE_WaitTime Next i
objectが急に掴めなくならないように、Shell.ApplicationでIEを掴みなおしたり、
Public Function Call_IE_WaitTime() Dim win As Object Dim winshell As Object Set winshell = CreateObject("Shell.Application") For Each win In winshell.Windows If win.Name = "Internet Explorer" Then Set objIE = win Exit For End If Next Do While objIE.Busy = True DoEvents Loop Do While objIE.readyState <> READYSTATE_COMPLETE DoEvents Loop Application.Wait Now() + TimeValue("00:00:02") End Function
IDの要素がNullでない事を確認したり、
errchk = objIE.document.getElementById("ID")
色々な形でエラーとうまく付き合っていきましょう。
その他
Internet Explorerを使用して、Webスクレイピングは敷居が高い風に捉えられますが、
上記のように、パーツ化して組み合わせ処理するだけです。
Web上のデータを触りたい要望は会社様でも個人様でも多いと思います。
VBA IE操作を覚えて効率化しませんか?
作成が大変であれば弊社で代行開発も可能です。お気軽にお問い合わせください。
コメント
・objectが急に掴めなくならないように、Shell.ApplicationでIEを掴みなおしたり、
この処置でエラーがでなくなりました。
気になるのは複数の”Internet Explorer”が開いているときに、最近開いた”Internet Explorer”に最初にあたるのが保証されているのかが知りたいです。
動作確認してませんが、古いIEから見ていく気がします。
objIE.document.Titleなどで、処理を分岐させて、最近開いたIEを掴むようにしたらいかがでしょうか。
Dim win As Object
Dim winshell As Object
Set winshell = CreateObject(“Shell.Application”)
For Each win In winshell.Windows
If win.Name = “Internet Explorer” Then
Set objIE = win
Exit For
End If
Next
■For Each ~ をやめてインデックスでやれば最新のウィンドウから取得できます。
dim i as long
for i = winshell.Windows.length to 0 step -1
Set win = winshell.windows(CINT(i))
If win.Name = “Internet Explorer” Then
Set objIE = win
Exit For
End If
next
最新の情報ありがとうございます。いつか別記事に致します。
※ほかのコメントも承認できてなくてすみません。
記事作成したら、コメント承認します。