ExcelマクロVBA技術解説
VBAのスクレイピングを簡単楽にしてくれるSelenium

ExcelマクロVBAの問題点と解決策、エクセルVBAの技術的解説
最終更新日:2019-05-07

VBAのスクレイピングを簡単楽にしてくれるSelenium


VBAでWebスクレイピングする方法としてIE自動操作がありますが、VBA記述が結構面倒になります、
もっと簡単にスマートにVBAを書きたいと思ったら…SeleniumBasicを使ってみましょう。


SeleniumBasicは、エクセルVBAでのWeb閲覧を自動化することを強力かつ簡単に実現してくれます。

今回は、ブラウザはChromeを使っての自動操作を解説します。
Google Chromeは別途インストールしておいてください。

IE操作については以下を参照

WEBページのいろいろな取得方法については以下を参照


以下では、VBAについては相応の知識があることを前提に、Seleniumの使い方のみ解説しています。
少なくとも、メソッドという単語の理解が不安な場合は、そちらを確認してからお読みください。



SeleniumBasicのインストール

以下よりダウンロードします。
http://florentbr.github.io/SeleniumBasic/
中断のRelease pageへ、
https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0
執筆時点では、
SeleniumBasic-2.0.9.0.exe
これをダウンロードしてインストールします。

VBA Selenium Basic

画面指示に従って、そのままインストールします。

Selenium VBA
Selenium Basicは、以前はSelenium VBAと呼ばれていました。

https://code.google.com/archive/p/selenium-vba/
ダウンロードは、
https://code.google.com/archive/p/selenium-vba/downloads

既に開発は停止していて、後継として先のSelenium Basicに移行されています。

chromedriver.exe
以下より、お使いのChromeバージョンに合わせて、「chromedriver.exe」を入れ替えてください。

https://sites.google.com/a/chromium.org/chromedriver/downloads

http://chromedriver.chromium.org/downloads

「chromedriver.exe」を入れ替える場所(Windows10で普通にインストールした場合)は、
C:\Users\ユーザー\AppData\Local\SeleniumBasic
exeを差し替えてください。
Chromeバージョンが変更された場合は、そのバージョンに合わせて入れ替えしてください。
執筆時点では、

VBA Selenium Basic

https://chromedriver.storage.googleapis.com/index.html?path=74.0.3729.6/

こちらを使用しました。
chromedriverのバージョンが違うと動作しません。

VBEでの参照設定


VBA Selenium Basic

参照できているか確認

VBA Selenium Basic

Selenium.には、以下もあります。
ChromeDriver
EdgeDriver
FirefoxDriver
Startメソッドでブラウザを指定するので、とりあえずWebDriverにしておけば良いでしょう。

WEBサイトを表示してみましょう

何はともあれ、お決まりのヤホーを表示してみましょう。

Sub sample()
  Dim Driver As New Selenium.WebDriver
  Driver.Start "chrome"
  Driver.Get "https://www.yahoo.co.jp/"
  Stop
End Sub

プロシージャーが終了するとブラウザが閉じてしまうのでStopしています。

ブラウザ起動・終了の定型文としては以下のようにしておけば良いでしょう。

Sub sample()
  Dim Driver As New Selenium.WebDriver
  Driver.Start "chrome", "https://www.yahoo.co.jp/"
  Driver.Get "/"
  '・・・
  Driver.Close
  Set driver = Nothing
End Sub

Seleniumの基本的な使い方(株価情報を取得してみる)

Yahooを表示したので、
「経済」タブの「日経平均株価」を取得してみましょう。

取得するには、そもそもページ全体の中から、取得したいデータの場所を特定しなければなりません。
WEBページはHTMLで作成されています。
どの要素(element)を取得するかをSeleniumに指定しなければなりません。
WEBページのソースをみてHTMLタグ等からだけでは必要な情報(element)がどれかを探すのは大変だったり、たどり着けなかったりします。

Chromeのデベロッパーツールを使用します。

VBA Selenium Basic
「Google Chrome の設定」→「その他のツール」→「デベロッパー ツール」
ショートカットは、F12

VBA Selenium Basic

「デベロッパー ツール」の表示位置は、以下のアイコンで変更できます。

VBA Selenium Basic

下または右にするのが普通でしょうか。
では、まずはこれを使って、Yahooの「経済タブ」の要素を特定します。

VBA Selenium Basic

このアイコンをクリックすると、要素(element)の選択モードになります。
element選択モードを解除するには、もう一度このアイコンをクリックしてください。
WEBページ内をクリックしても選択モードは解除されます。
element選択モードで、マウスカーソルをWEBページ内で移動すると、

VBA Selenium Basic

このように、カーソル下が色付けされて表示されるのが分かるようになっています。
適当にカーソルを動かしてみて、色付けされている範囲が変更されることを確認してください。
この色付けされている範囲が、ページを構成している要素(element)になります。
このエレメントは入れ子になっていて、
エレメントの中にエレメントがあり、そのエレメントの中にもさらにエレメントがはいっている作りになっています。

上図のように、「経済」が選択された状態でクリックすると、
「デベロッパー ツール」内の該当箇所が選択されます。

VBA Selenium Basic

今度は、「デベロッパー ツール」内でマウスを移動させてみてください。
「デベロッパー ツール」のマウスカーソル位置に該当するWEBページの当該箇所が色付けされます。

element選択モードで、WEBページ内から目的の箇所を探したり、
デベロッパー ツール内の選択から目的の箇所を探したりと、双方向で探すことができます。

目的のエレメントに到達したら、デベロッパー ツールのelementを右クリックします。

VBA Selenium Basic

そして、「Copy」から「Copy selecter」をクリックしてください。
クリップボードに、CSSセレクターが入ります。
「経済」タブは、
#economy
とコピーされたはずです。
これを使って、seleniumで「経済」タブをクリックしてみましょう。

前出のコードに追記します。

VBA Selenium Basic

エレメントを見つけるので、Find○○というメソッドになります。
.FindElementByClass
.FindElementByCss
.FindElementById
.FindElementByLinkText
.FindElementByName
.FindElementByPartialLinkText
.FindElementByTag
.FindElementByXPath
いろいろなメソッドが用意されていることを確認しておきましょう。
どれを使うかは、その時々で変わってきますが、
今回は、CSSセレクターなので、
FindElementByCss
これになります。
この引数に先ほどCopyしたCSSを入れます。
そして、それをクリックなので、Clickメソッドを使用します。

VBA Selenium Basic

Sub sample()
  Dim Driver As New Selenium.WebDriver
  Driver.Start "chrome", "https://www.yahoo.co.jp/"
  Driver.Get "/"
  Driver.FindElementByCss("#economy").Click
  Stop '確認するため
  Driver.Close
  Set Driver = Nothing
End Sub

これで「経済」タブが表示されたので、

VBA Selenium Basic

クリック→elementを右クリック→Copy selector
#economyfb > div.topicscatch > div > dl > dd:nth-child(2)
これがコピーされますので、これを使って、

Sub sample()
  Dim Driver As New Selenium.WebDriver
  Driver.Start "chrome", "https://www.yahoo.co.jp/"
  Driver.Get "/"
  Driver.FindElementByCss("#economy").Click
  Dim txt As String
  txt = Driver.FindElementByCss("#economyfb > div.topicscatch > div > dl > dd:nth-child(2)").Text
  Debug.Print txt
  Driver.Close
  Set Driver = Nothing
End Sub

もうお分かりいただけると思います。
文字列を取得するのですから、Textメソッドを使用します。
結果は、イミディエイトに、
22,258.73
このように表示され、ブラウザも閉じられます。
(当たり前すぎますが、株価は実行日によって変わりますよ。)

色々なパターンでのseleniumの使い方

画面最大化
Driver.Window.Maximize

ブラウザで見えていないエレメントにはアクセスできないページもあるので、
最大化しておいた方がとりあえずは扱いやすいと思います。

Wait処理
Driver.Wait ミリ秒

Seleniumは、画面が表示されるまで自動で待ってから戻ってくるので、ページロード待ちはあまり気にする必要はありません。
なのですが、それだけでは対応できないページもあります、といいますか、結構多いです。
そこで、ページによっては明示的にwaitを入れる必要が出てきます。

必要なエレメントが見つかるまでループさせる方法にしたほうが良いのですが、
単純に、1〜3秒程度待たせてしまったほうが、VBA自体は簡単になります。


テキストボックスに文字を入れる
Sub sampla1()

  Dim Driver As New Selenium.WebDriver
  Dim sKey As New Selenium.Keys
  Dim elm As Selenium.WebElement
  Driver.Start "chrome", "https://www.google.co.jp/"
  Driver.Get "/"
  Set elm = Driver.FindElementByXPath("//*[@id=""tsf""]/div[2]/div/div[1]/div/div[1]/input")
  elm.Clear
  elm.SendKeys "エクセルの神髄"
  elm.SendKeys sKey.Enter
  Stop '確認
  Driver.Close
  Set Driver = Nothing
End Sub

ここではVBAサンプルとして、Googleで「エクセルの神髄」を検索しています。
エレメント検索のバリエーションとしてXPathをにしています。
そして、サンプルとしてエレメントをオブジェクト変数にセットするようにしています。
文字列の送信は、SendKeysになりますが、
既に文字が入っている場合はその後ろに入ってしまうので一旦Clearするようにしています。


ドロップダウン(プルダウン)メニューの選択
AsSelectメソッドを使います。

Driver.FindElementByCss(css文字列).AsSelect.SelectByText "値"

Driver.FindElementByCss(css文字列).AsSelect.SelectByIndex 2

上記のほか、SelectByValueやSelectByOptionもあります。

VBA Selenium Basic


WEBサイトの操作は、マウスクリックとキーボード入力で全て操作できます。
従って基本としては、ClickとSendKeysで操作することになりますが、seleniumで操作するときにいくつか専用の使い方が必要なものがあります。

色々組み合わせて目的の画面にたどり着きます
Yahooで以下の操作を行います。
「経済」→「日経平均株価」→「銘柄コード」に4689→「検索」→「アラート設定」
→「ID」入力→「次へ」→「パスワード」入力→「次へ」→「値上がり率」に15%

Option Explicit

Sub sample2()
  Dim Driver As New Selenium.WebDriver
  Dim elm As Selenium.WebElement
  Driver.Start "chrome", "https://www.yahoo.co.jp/"
  Driver.Get "/"
  Driver.Window.Maximize
  '「経済」
  Driver.FindElementByCss("#economy").Click
  '「日経平均株価」
  Driver.FindElementByCss("#economyfb > div.topicscatch > div > dl > dt:nth-child(1) > a").Click
  '「銘柄コード」に4689
  Driver.FindElementByCss("#searchText").SendKeys "4689"
  '「検索」
  Driver.FindElementByCss("#searchButton").Click
  '「アラート設定」
  Driver.FindElementByCss("#settings > span.alerts > a").Click
  '「ID」入力
  Driver.FindElementByCss("#username").SendKeys "ID"
  '「次へ」
  Driver.FindElementByCss("#btnNext").Click
  '「パスワード」入力:そのまま続けるとエラーとなるのでWait対応
  Set elm = WaitForElement(Driver, "#passwd")
  If elm Is Nothing Then
    MsgBox "「#passwd」見つかりません。"
    End
  End If
  If Not WaitForSendKeys(Driver, elm, "パスワード") Then
    MsgBox "パスワードを入力できませんでした。"
    End
  End If
  '「次へ」
  Driver.FindElementByCss("#btnSubmit").Click
  '「値上がり率」に15%
  Driver.FindElementByCss("#up_0").AsSelect.SelectByText "15%"
  Stop '確認
  Driver.Close
  Set Driver = Nothing
End Sub

Function WaitForElement(ByVal Driver As WebDriver, ByVal sCss As String) As Selenium.WebElement
  Dim cnt As Long
  On Error Resume Next
  Do
    cnt = cnt + 1
    Set WaitForElement = Driver.FindElementByCss(sCss)
    If Not Err Then
      Exit Function
    End If
    Driver.Wait 100
    If cnt > 100 Then Exit Do
  Loop
  Set WaitForElement = Nothing
End Function

Function WaitForSendKeys(ByVal Driver As WebDriver, _
             ByVal elm As WebElement, _
             ByVal sText As String) As Boolean
  Dim cnt As Long
  On Error Resume Next
  Do
    cnt = cnt + 1
    Err.Clear
    elm.Clear
    If Err.Number = 0 Then
      Err.Clear
      elm.SendKeys sText
      If Err.Number = 0 Then
        WaitForSendKeys = True
        Exit Function
      End If
    End If
    Driver.Wait 100
    If cnt > 100 Then Exit Do
  Loop
  WaitForSendKeys = False
End Function

Seleniumでブラウザを起動すると、
クッキー等は全て無効になっているので画面によっては、通常操作では必要ないログインを求められます。

Yahooのこのページでは、パスワード入力がそのままではエラーとなってしまいます。
1秒程度のWaitで問題なく進めますが、
上記ではサンプルの意味も兼ねて、エレメントへの設定が正しく行われるまで繰り返すようにしています。

最後のドロップダウンのoptionを確認する場合、
デベロッパーツールで、ドロップダウンをクリック後に、

VBA Selenium Basic

"down_0>…</select>この…をダブルクリッククリックすると、optionの中が展開されます。

VBA Selenium Basic


elementをコレクションで取得する
tdタグやliタグのように、同一タグの繰り返しを順次処理する場合は、
指定タグのエレメントをコレクションで取得し、For〜Eachで処理します。

以下では、Yahooのトピック一覧を取得しています。

Sub sample4()
  Dim Driver As New Selenium.WebDriver
  Dim elm1 As Selenium.WebElement
  Dim elm2 As Selenium.WebElement
  Driver.Start "chrome", "https://www.yahoo.co.jp/"
  Driver.Get "/"
  Set elm1 = Driver.FindElementByCss("#topicsfb > div.topicsindex > ul.emphasis")
  For Each elm2 In elm1.FindElementsByTag("li")
    Debug.Print elm2.Text
  Next
  Driver.Close
  Set Driver = Nothing
End Sub

Find○○メソッドには、オブジェクト単体の取得とコレクションの取得が容易されています。
FindElementとFindElementsが存在します。
コレクションとして取得する場合は、FindElementsを使用します。

.FindElementsByClass
.FindElementsByCss
.FindElementsById
.FindElementsByLinkText
.FindElementsByName
.FindElementsByPartialLinkText
.FindElementsByTag
.FindElementsByXPath

新規ページが開かれる場合

クリックによって新規ページが開かれるような場合、新規ページへ移動する必要があります。
まずは特に何もしない場合の動作状況になります。

Sub sample3()
  Dim Driver As New Selenium.WebDriver
  Driver.Start "chrome"
  Driver.Get "https://excel-ubara.com/EXCEL/EXCEL918.html"
  Driver.FindElementByLinkText("Excelシートの複雑な計算式を解析するVBAの関数構文").Click
  Debug.Print Driver.FindElementByTag("h1").Text
  Stop '確認
  Driver.Close
  Set Driver = Nothing
End Sub

これでイミディエイトに出力されるのは、
「VBAリファレンス
Excelワークシート関数一覧(2010以降)」
このように、クリックする前の元のページのh1が取得されてしまいます。
そこで、次ページへ移動する必要があります。

Sub sample3()
  Dim Driver As New Selenium.WebDriver
  Driver.Start "chrome"
  Driver.Get "https://excel-ubara.com/EXCEL/EXCEL918.html"
  Driver.FindElementByLinkText("Excelシートの複雑な計算式を解析するVBAの関数構文").Click
  Driver.SwitchToNextWindow
  Debug.Print Driver.FindElementByTag("h1").Text
  Driver.Close
  Set Driver = Nothing
End Sub

これでイミディエイトに、以下のように出力されます。
「ExcelマクロVBAサンプル集
Excelシートの複雑な計算式を解析するVBAの関数構文」

複数開いている場合は、タイトルを保存しておいて、
Driver.SwitchToWindowByTitle "タイトル"
これで移動可能です。

以下のようなVBAコードを追加して、画面遷移を確認してみると良いでしょう。
Debug.Print "1:" & Driver.window.Title
Driver.SwitchToNextWindow
Debug.Print "2:" & Driver.window.Title
Debug.Print Driver.FindElementByTag("h1").Text

最後に

今まで筆者はSeleniumVBAを使っていたのですが、SeleniumBasicではメソッドが結構変更になっていました。
実際に動作確認しながら本記事を書きましたが、細部においてはより効率的な使い方があるかもしれません。
ただし全体的には、SeleniumVBAより使いやすくなっているように感じました。

クローリング&スクレイピングは、サイトごとのクセを見極めることが面倒な作業になります。
特にJavaScriptでマウスオーバーにより切り替わるような場合はかなり面倒です。
SeleniumでJavaScriptのコードを実行(.ExecuteScript)することもできますが、
このようなサイトでは、結構頻繁にサイトが更新されてしまう為になかなか安定運用できない場合が多いようにも思われます。
いずれにしても、クローリング&スクレイピングではサイト変更によってVBAを変更しなければならないものです。
従って、いつでも簡単にVBA修正して運用できる環境であることが望まれます。
もし、そのような運用が難しい場合(開発会社に依頼して作ってもらう等の場合)は、
サイト変更時の対応を事前に良く確認しておくことをお勧めします。




同じテーマ「マクロVBA技術解説」の記事

Dictionary(ディクショナリー)のパフォーマンスについて
VBAでのInternetExplorer自動操作
VBAでのSQLの基礎(SQL:Structured Query Language)
VBAで正規表現を利用する(RegExp)
VBAでメール送信する(CDO:Microsoft Collaboration Data Objects)
VBAでのOutlook自動操作
ADO(ActiveX Data Objects)の使い方の要点
特殊フォルダの取得(WScript.Shell,SpecialFolders)
参照設定、CreateObject、オブジェクト式の一覧
VBAのスクレイピングを簡単楽にしてくれるSelenium
VBA+SeleniumBasicで検索順位チェッカー作成

新着記事NEW ・・・新着記事一覧を見る

VBA+SeleniumBasicで検索順位チェッカー作成|VBA技術解説(5月18日)
テーブル操作のVBAコード(ListObject)|VBA入門(5月12日)
テーブル操作の概要(ListObject)|VBA入門(5月12日)
VBAのスクレイピングを簡単楽にしてくれるSelenium|VBA技術解説(5月6日)
Excelワークシート関数一覧(2010以降)|VBAリファレンス(4月22日)
クラスとCallByNameとポリモーフィズム(多態性)|VBA技術解説(4月6日)
VBAでのタイマー処理(SetTimer,OnTime)|VBA技術解説(4月3日)
クラスとイベントとマルチプロセス並列処理|VBA技術解説(4月2日)
エクセルの日付と時刻のまとめ|エクセル関数超技(3月6日)
Excelシートの複雑な計算式を解析するVBA|VBAサンプル集(2月18日)

アクセスランキング ・・・ ランキング一覧を見る

1.ひらがな⇔カタカナの変換|エクセル基本操作
2.最終行の取得(End,Rows.Count)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.RangeとCellsの使い方|ExcelマクロVBA入門
6.変数とデータ型(Dim)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.繰り返し処理(For Next)|ExcelマクロVBA入門
9.とにかく書いて見よう(Sub,End Sub)|VBA入門
10.セルに文字を入れるとは(Range,Value)|VBA入門



  • >
  • >
  • >
  • VBAのスクレイピングを簡単楽にしてくれるSelenium

    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。






    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。

    本文下部へ