どうも、マサヤです!
今日からVBA IE操作編の連載をスタートします!
VBAでのIE操作が初めて or 慣れていない方向けに『Webサイト・システムの情報を取得・設定する方法』をお伝えしていくシリーズです!
IE操作を習得すれば、webサイトのデータを取得・登録することができます。
- 1週間毎で特定サイトのデータを取得し、トレンドなどを分析してビジネスに役立てる。
- 手動で行っていたwebシステムへのデータ登録を自動化し生産性を向上させる。
- 複数サイトから料金を取得して相場を把握、最適なプライシングに役立てる。
等々、アイディア次第で様々なことが可能となります。
Webサイトからデータを取得する、いわゆるスクレイピングやクローリングといった方法は古くからあり、関連するサービスも多々リリースされています。
本連載では、ExcelのVBAを使って無料かつ目的に沿ったデータ取得や登録を可能とする方法を紹介していきます。
最初の一歩である今回は、IEオブジェクトを作成、IEを起動して、目的のWebサイトを開く。
そして、Webサイトからデータを一つ取得するまでをお伝えしていきます!
【動画】Webサイトを開いて、データ取得
まずは、紹介するコードの実際の動きを動画で見てみましょう!
Webサイト(当ブログ)開いて、一番最初の記事タイトルを取得しています。
取得してきた記事タイトルを画面下部のイミディエイトウィンドウに表示させています。
VBA IE起動からデータ取得するまでのコード
実際のコードはこちら!
Sub ieGetData() 'IEオブジェクトを作成 Dim ie As InternetExplorer Set ie = CreateObject("InternetExplorer.Application") '開きたいURLを変数に代入 Dim strUrl As String strUrl = "https://mmm-program.com/" 'IEを表示(見えるようにする) ie.Visible = True '指定したURLをIEで開く ie.Navigate strUrl 'サイトの読み込みが完了するまで待つ Do While ie.Busy = True Or ie.readyState < READYSTATE_COMPLETE DoEvents Loop '一番最初の記事タイトルをイミディエイトに表示する Debug.Print ie.document.getElementsByClassName("entry-card-title")(0).innerText End Sub
コード自体は短いですね! 一つずつ説明していきます。
1. 参照設定
まずは参照設定をしましょう!
参照設定するライブラリは下記の2つになります。
- Microsoft HTML Object Library
- Microsoft Internet Controls
VBE画面で、「ツール」⇒「参照設定」⇒必要ライブラリにチェックを入れる⇒「OK」
これを設定することで、IE操作を行う準備が整います。
2. IEオブジェクトを作成
参照設定で準備が整いましたので、コードに見ていきましょう。
まずは、VBAでIEをコントロールするためオブジェクト作成します。
'IEオブジェクトを作成 Dim ie As InternetExplorer Set ie = CreateObject("InternetExplorer.Application")
このコードでIE操作できるオブジェクトを作成できました。
※PC画面には表示されませんが、裏でIEが起動している感じになります。
作成オブジェクトである ie を使ってコーディングしています。
3. VisibleでIEを表示する
下記コードでIEを見える化(表示)します。
IEが実際に起動しているのをPC画面で確認できるようになります。
'IEを表示(見えるようにする) ie.Visible = True
別に見えないままでもデータ取得・設定ができるので、表示させる必要がない場合は不要です。
最初は表示させて、どこかのタイミングで非表示したい場合は、 ie.Visible = False とすることでIEを非表示にできます。
4. Navigateで指定サイトを開く
次は、指定したサイトをie.Navigate strUrlで開きます。
strUrlは変数で、この変数内のURLを変更することで違うサイトを開くことが可能になります。
'指定したURLをIEで開く ie.Navigate strUrl
5. Busyでサイトの読み込みを待つ
下記コードでサイトが完全に開くまで、次のコードを実行するのを待ちます。
これを行わない場合、ページを開かずにデータを取得しようとしてエラーが発生したり、中途半端なデータを取得する等の問題が発生します。
'サイトの読み込みが完了するまで待つ Do While ie.Busy = True Or ie.readyState < READYSTATE_COMPLETE DoEvents Loop
Busyはieオブジェクトが処理中かどうかを表します。
readyStateはデータ読み込みの進捗を表します。
オブジェクトが処理中もしくは全データの読込完了前だった場合、DoEventsを繰り返すコードになってます。
DoEventsは、実行中プログラム以外で待機処理がないかをチェックし、待機待ちが存在していれば、そちらの処理を優先して処理し、また今の処理に戻ってくる関数です。
今回で言うとIEが読込完了前であれば、一度他の待機処理を優先させ、ループ処理に戻りIE読込状態を確認し、読込完了していれば次のコードへ、読込前ならまた他の待機処理を優先させるといった動きになります。
6. document.getElementsByClassName innerTextでテキスト取得
最後のコードですね。
'一番最初の記事タイトルをイミディエイトに表示する Debug.Print ie.document.getElementsByClassName("entry-card-title")(0).innerText
なんか色々と出てきましたね(笑)
ドットでつなげているだけなので一つずつ見ていけば大丈夫です。
結果として、「HTML中のClass名「entry-card-title」が付いている0番目の要素にあるテキストを取得する」といったコードになります。
社内Webサイト・システム・保護モードによるエラー発生の可能性
下記の2つの条件が揃っている場合、紹介したコードでエラーが発生する可能性が高くなります。
- 対象のWebサイト・システムのアドレスがIE設定のイントラネットに登録されている。
- IE設定にあるイントラネットの保護モードのチェックが外れている(OFFになっている)。
まず簡単な対処方法は、IE設定を変更することで解決できます。
ただ、会社PCとなるとネットワーク管理者により意図的に設定されいる場合が多いです。
なので、IE設定は触らずにコード側で対処する方法を紹介します。
‘RegisterAsBrowser’メソッドは失敗しました
先に具体的に発生するエラーを紹介します。
コードを実行すると、まずは下図のようなエラーが発生します。
デバッグ後、再開(F5)を押すと、
下図エラーが発生します(オートメーションエラーです。起動されたオブジェクトはクライアント・・・)
エラー対応コード
エラーに対応するコードは下記となります。
Sub ieGetData() 'IEオブジェクトを作成 Dim ie As InternetExplorer 'Set ie = CreateObject("InternetExplorer.Application")を↓に変更 Set ie = New InternetExplorerMedium '開きたいURLを変数に代入 Dim strUrl As String strUrl = "https://mmm-program.com/" 'IEを表示(見えるようにする) ie.Visible = True '指定したURLをIEで開く ie.Navigate strUrl 'サイトの読み込みが完了するまで待つ Do While ie.Busy = True Or ie.readyState < READYSTATE_COMPLETE DoEvents Loop '一番最初の記事タイトルをイミディエイトに表示する Debug.Print ie.document.getElementsByClassName("entry-card-title")(0).innerText End Sub
といっても、先ほどのコードの一箇所を変更(5行目を6行目に)するだけです。
↓
新)Set ie = New InternetExplorerMedium
これで、IE操作できるようになります。
まとめ
IE操作編 1回目 基本のIE起動からサイト展開・データ取得の流れをお伝えしました。
私がハマった社内Webサイト・システムで使う時に発生しやすいエラーの対処法も紹介しました。
正直、今回紹介したコードは実用性は高くないので、「もっと先まで一気に紹介するほうがいいのでは?」と考えもしました。
しかし、私がVBAでIE操作に慣れた頃にぶち当たったエラーの解決法、その時に学び直した知識をガッツリお伝えしたほうがきっと良いはずと思い、ここまでを一記事とすることにしました。
さて、次回のIE操作編 2回目は具体的にWebサイトからデータを取得する方法をお届けします!
お楽しみに!
コメント