VBAのスクレイピングを簡単楽にしてくれるSelenium
VBAでWebスクレイピングする方法としてIE自動操作がありますが、VBA記述が結構面倒になります、
もっと簡単にスマートにVBAを書きたいと思ったら…SeleniumBasicを使ってみましょう。
今回は、ブラウザはChromeを使っての自動操作を解説します。
Google Chromeは別途インストールしておいてください。
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
これをダウンロードしてインストールします。

ダウンロードは、
https://code.google.com/archive/p/selenium-vba/downloads
C:\Users\ユーザー\AppData\Local\SeleniumBasic
exeを差し替えてください。
Chromeバージョンが変更された場合は、そのバージョンに合わせて入れ替えしてください。
執筆時点では、

chromedriverのバージョンが違うと動作しません。
しかし、エラーで動きません・・・
そうです、「.NET Framework 3.5」が必要だったのです。
この際なので、「TinySeleniumVBA」に変更しようかとも思いましたが、複数ファイルがあり変更するのも面倒なので「.NET Framework 3.5」を入れることにしました。
VBEでの参照設定


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の基本的な使い方(株価情報を取得してみる)
「経済」タブの「日経平均株価」を取得してみましょう。
WEBページはHTMLで作成されています。
WEBページのソースをみてHTMLタグ等からだけでは必要な情報(element)がどれかを探すのは大変だったり、たどり着けなかったりします。

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


では、まずはこれを使って、Yahooの「経済タブ」の要素を特定します。

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

適当にカーソルを動かしてみて、色付けされている範囲が変更されることを確認してください。
この色付けされている範囲が、ページを構成している要素(element)になります。
エレメントの中にエレメントがあり、そのエレメントの中にもさらにエレメントが入っている作りになっています。
「デベロッパー ツール」内の該当箇所が選択されます。

「デベロッパー ツール」のマウスカーソル位置に該当するWEBページの当該箇所が色付けされます。
デベロッパー ツール内の選択から目的の箇所を探したりと、双方向で探すことができます。

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

.FindElementByCss
.FindElementById
.FindElementByLinkText
.FindElementByName
.FindElementByPartialLinkText
.FindElementByTag
.FindElementByXPath
どれを使うかは、その時々で変わってきますが、
今回は、CSSセレクターなので、
FindElementByCss
これになります。
そして、それをクリックなので、Clickメソッドを使用します。

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
これで「経済」タブが表示されたので、

#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するようにしています。
ドロップダウン(プルダウン)メニューの選択
Driver.FindElementByCss(css文字列).AsSelect.SelectByText "値"
Driver.FindElementByCss(css文字列).AsSelect.SelectByIndex 2
上記のほか、SelectByValueやSelectByOptionもあります。

フレームを切り替える
HTMLは以下のようなものになります。
<iframe id="identiFier" src="https://・・・"
Driver.SwitchToFrame "identiFier"
iframe内に切り替えた後は、普通にFindElement○で要素を取得できます。
従って基本としては、ClickとSendKeysで操作することになりますが、seleniumで操作するときにいくつか専用の使い方が必要なものがあります。
色々組み合わせて目的の画面にたどり着きます
「経済」→「日経平均株価」→「銘柄コード」に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でブラウザを起動すると、
クッキー等は全て無効になっているので画面によっては、通常操作では必要ないログインを求められます。
1秒程度のWaitで問題なく進めますが、
上記ではサンプルの意味も兼ねて、エレメントへの設定が正しく行われるまで繰り返すようにしています。
デベロッパーツールで、ドロップダウンをクリック後に、


elementをコレクションで取得する
指定タグのエレメントをコレクションで取得し、For~Eachで処理します。
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を使用します。
.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以降)」
そこで、次のウィンドウへ移動する必要があります。
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 "タイトル"
これで移動可能です。
Debug.Print "1:" & Driver.window.Title
Driver.SwitchToNextWindow
Debug.Print "2:" & Driver.window.Title
Debug.Print Driver.FindElementByTag("h1").Text
上手くいかない特殊な場合の対処方法
そのような場合は、個別の対処方法を考える必要があります。
以下に代表的な対処方法の例を載せておきます。
あくまで一例ですので、使う場合は個別に工夫してお使いください。
テキストボックスに1回で文字列を入れられない場合
Function SendKeysTextBox(ByVal argText As String, _
ByVal sCss As String, _
Optional ByVal waitTime As Long = 200, _
Optional ByVal maxTime As Long = 2000) As Boolean
On Error Resume Next
SendKeysTextBox = False
Dim t As Double
t = Timer
Do
Driver.FindElementByCss(sCss).Clear
Driver.FindElementByCss(sCss).SendKeys argText
If Driver.FindElementByCss(sCss).Value = argText Then Exit Do
If Timer > t + maxTime Then Exit Function
Driver.Wait waitTime
Loop
Driver.Wait waitTime
SendKeysTextBox = True
On Error GoTo 0
End Function
クリック後に新ページ移動前にseleniumから戻ってきてしまう場合
Function ClickToNewPage(ByVal sCss As String, _
Optional ByVal waitTime As Long = 200, _
Optional ByVal maxTime As Long = 2000) As Boolean
On Error Resume Next
ClickToNewPage = False
Dim sUrl As String
Dim t As Double
t = Timer
sUrl = Driver.Url
Do
Driver.FindElementByCss(sCss).Click
If sUrl <> Driver.Url Then Exit Do
If Timer > t + maxTime Then Exit Function
Driver.Wait waitTime
Loop
Driver.Wait waitTime
ClickToNewPage = True
On Error GoTo 0
End Function
画面ロード完了前にseleniumから戻ってきてしまう場合
Function ExistElement(ByVal sCss As String, _
Optional ByVal waitTime As Long = 200, _
Optional ByVal maxTime As Long = 2000) As Boolean
On Error GoTo 0
ExistElement = False
Dim t As Double
t = Timer
Dim elms As Selenium.WebElements
Do
Set elms = Driver.FindElementsByCss(sCss)
If elms.Count > 0 Then Exit Do
If Timer > t + maxTime Then Exit Function
Driver.Wait waitTime
Loop
Driver.Wait waitTime
ExistElement = True
On Error GoTo 0
End Function
遷移後のURLに直接移動する
Driver.Get Driver.Url & "?xxx&yyy"
最後の手段になりますが、遷移後のURLに移動してしまう方法も結構有効です。
クリック後にURLパラメーターが追加になるような場合は、直接パラメーターを追加したURLを指定してしまう方法になります。
これらの状態によって、追加するパラメーターは適宜変更が必要になります。
クエスチョンマーク"?"をURLの末尾に付け、「変数(パラメータ)=値」の形式で指定します。
複数のパラメーターはアンパサンド(&)でつなげます。
Seleniumの実践例例
最後に
実際に動作確認しながら本記事を書きましたが、細部においてはより効率的な使い方があるかもしれません。
ただし全体的には、SeleniumVBAより使いやすくなっているように感じました。
特にJavaScriptでマウスオーバーにより切り替わるような場合はかなり面倒です。
SeleniumでJavaScriptのコードを実行(.ExecuteScript)することもできますが、
このようなサイトでは、結構頻繁にサイトが更新されてしまう為になかなか安定運用できない場合が多いようにも思われます。
従って、いつでも簡単にVBA修正して運用できる環境であることが望まれます。
もし、そのような運用が難しい場合(開発会社に依頼して作ってもらう等の場合)は、
サイト変更時の対応を事前に良く確認しておくことをお勧めします。
同じテーマ「マクロVBA技術解説」の記事
VBAで正規表現を利用する(RegExp)
VBAでメール送信する(CDO:Microsoft Collaboration Data Objects)
VBAでのOutlook自動操作
ADO(ActiveX Data Objects)の使い方の要点
特殊フォルダの取得(WScript.Shell,SpecialFolders)
参照設定、CreateObject、オブジェクト式の一覧
VBAのスクレイピングを簡単楽にしてくれるSelenium
VBA+SeleniumBasicで検索順位チェッカー作成
VBA+SeleniumBasicで検索順位チェッカー(改)
.Net FrameworkのSystem.Collectionsを利用
WshNetwork(ネットワークドライブの割り当て等)
新着記事NEW ・・・新着記事一覧を見る
WshNetwork(ネットワークドライブの割り当て等)|VBA技術解説(2025-04-09)
TRANSLATE関数(翻訳) DETECTLANGUAGE関数(言語識別)|エクセル入門(2025-04-08)
QRコード、バーコード作成の覚え書き|エクセル関数応用(2025-04-05)
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ひらがな⇔カタカナの変換|エクセル基本操作
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
10.条件分岐(Select Case)|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- VBAのスクレイピングを簡単楽にしてくれるSelenium
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。