Seleniumを使ってVBAからchromeブラウザ操作(VBA編)

excelvbaエクセル

ここではSeleniumを使ってVBAからchromeブラウザ操作するVBAプログラムについて解説します。

※自動化した処理は接続先にトラフィックを送ります。過度になった場合は異常アクセスとされることがありますので使用にはご注意ください。

まずはchromeとseleniumがインストールされていない場合はインストールをしましょう。

Seleniumを使ってVBAからchromeブラウザ操作(インストール編)

それではVBAでよく使われる手法を見ていきましょう。

 

スポンサーリンク

ブラウザ設定と起動や終了

sub test()
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

基本のブラウザを開いてURLにアクセスしそれを終了するプログラムです。

「driver」がブラウザのオブジェクトになりますので、これに様々な処理をしていきます。

最後のリセットは変数を空(未設定)にしておくものです。

終了時は「.Close」を使用していますが「.quit」も使用できます。

.quitは

このドライバを使用して、関連するすべてのウィンドウを閉じます。停止と同じです。

.closeは

現在のウィンドウを閉じます

 

ソースを取得する

sub test()
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
source = driver.PageSource
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

ソースのスクレイピングなどの時は「source」を加工したりすることによって色々な情報が取得できます。

 

属性やセレクタを指定して取得する

sub test()
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
Set objIdNameid = driver.FindElementById("id属性名")
Set objIdNameclass = driver.FindElementsByClass("class属性名").Item("出現番号(0~)")
Set objIdNamename = driver.FindElementsByName("name属性名").Item("出現番号(1~)")
Set objIdNamesele = driver.FindElementByCss("cssセレクター")
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

「.FindElement~」が様々な方法で指定したものを取得するものです。

cssセレクターは「#id > div > div > div.class-1」のよう記述方式で、ブラウザのデバック機能などで確認できます。

 

エレメントがあるかを確認

sub test()
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
Dim By As New By
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
id_judge = driver.IsElementPresent(By.Css(IdNamename))
if id_judge = True then
Debug.Print "存在します"
end if
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

IsElementPresent」はエレメントが存在するかをBoolean(True,False)で返します。

エレメントに対して処理をする際、存在しない場合はエラーになってしまいますので、エラー処理をする場合に有効です。

ループ処理などにして応答を待つということもできます。

chromedriveは基本的にページの応答は待ってくれますが、javascriptなどで出現するエレメントは待ちません。

そのような場合は自分で待機する処理を入れる必要があります。

#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If

sub test()
id_judge = driver.IsElementPresent(By.Css(IdNamename))
HT_loop_num = 0
Do While id_judge = False
If HT_loop_num > 6 Then
"エラー処理"
End If
HT_loop_num = HT_loop_num + 1
Sleep 5000
DoEvents
id_judge = driver.IsElementPresent(By.Css(IdNamename))
Loop
end sub

冒頭の青い部分はsleepを使うための宣言です。

上記のようにするとエレメントが出現するまで6回ループし、なければエラー処理をします。

 

フォームに入力したりキーボード操作を送る

sub test()
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
Dim Keys As New Selenium.Keys 'sendkeyでブラウザにkeyを送るために使う
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
Set objIdNameid = driver.FindElementById("id属性名")
Set objIdNamesubmit = driver.FindElementById("id属性名(submit)")
objIdNameid.Clear
objIdNameid.SendKeys "テスト"
objIdNameid.SendKeys Keys.Enter
objIdNamesubmit.submit
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

ID属性でテキストエリアを指定してクリアしてからテキストを挿入しています。

その後改行を入れるためにキーボードの「Enter」を押下しています。

その後submitしています。

.submitは.clickでも大丈夫なことが多いです。

objIdNamesubmit.click

尚、長い文章をフォームなどに挿入する場合はSendKeysは向きません。処理に時間がかかるからです。

javascriptを実行する方法が圧倒的に速いのでこちらも参照してください。

SendKeysで文章入力が重たい場合

ブラウザの操作を画面表示しない

sub test()
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
driver.AddArgument "headless"
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

ヘッドレスモードというもので画面に表示せずバックグラウンドで処理をします。

chromeで処理中は前面にブラウザが来てしまいます。

他の作業の邪魔にならないようにするにはバックグラウンド処理がいいでしょう。

また、ブラウザの表示がしませんので非表示のほうが端末への負荷が減りますので処理も早くなります。

 

画面サイズを指定して開く

sub test()
driver.AddArgument "window-size=1500,1000"
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
source = driver.PageSource
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

画面サイズ指定はスクリーンショットを取るときなどに設定すると一律したサイズで取得できます。

 

スクリーンショットを取得する

sub test()
driver.AddArgument "window-size=1500,1000"
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定
driver.Start "chrome" 'chromeを起動
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く
driver.TakeScreenshot.SaveAs "保存先パスとファイル名"
driver.Close 'chromeを閉じる
Set driver = Nothing 'driveをリセットする
end sub

「.TakeScreenshot」でスクショを取って「.SaveAs」で保存します。

保存先にはファイル名も含みます。

この機能はデバックにも使えます。

バックグラウンドで実行している場合、実際に処理をしている画面を確認したいときに便利です。

ツイッターなどで自動でログインさせない方法

ツイッターなどではログインページにアクセスすると、一度ログインしている場合ユーザー情報がブラウザに残っていて勝手にログインすることがあります。

ですが、ログインできたりできていなかったりだと、ログイン状態の確認をする必要がありますがなかなか面倒です。

そんな時に毎回必ずログインするようにできれば確認の作業が必要なくなります。

通常はブラウザのユーザー情報は

C:/Users/ユーザ名/AppData/Local/Google/Chrome/User Data

あたりに格納されていますので子の格納場所を変えてあげて毎回削除するばログイン画面から始められます。

尚、下記ではエクセルファイルと同階層に「tmp」というフォルダを作成しておきます。

sub test() 
driver.AddArgument "window-size=1500,1000" 
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定 
PROFILE_PATH = "tmp"
driver.AddArgument ("user-data-dir=" & PROFILE_PATH)
driver.Start "chrome" 'chromeを起動 
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く 
driver.Close 'chromeを閉じる Set driver = Nothing 'driveをリセットする 
Dim fso As FileSystemObject
Set fso = New FileSystemObject
Dim fl As Folder
Set fl = fso.GetFolder(PROFILE_PATH) ' フォルダを取得
Dim f As File
For Each f In fl.Files
    f.Delete (True) ' ファイルを削除
Next
Set fso = Nothing
end sub

最初にデータを格納するフォルダを設定します。

処理が終わったらユーザーデータを削除するという具合です。

逆に普段使っているアカウント以外で自動ログインしたい時などは、chromedrive用にユーザーデータを格納しておけばキャッシュクリアされるまではアクセスが可能です。

ブラウザでF5を押すようなリフレッシュをする

処理の途中で画面をリフレッシュしたいときもあると思います。

sub test() 
driver.AddArgument "window-size=1500,1000" 
Dim driver As New Selenium.ChromeDriver 'ブラウザ設定 
driver.Start "chrome" 'chromeを起動 
driver.Get "https://www.google.com/?hl=ja" 'URLを指定して開く 
driver.Refresh
source = driver.PageSource driver.Close 'chromeを閉じる 
Set driver = Nothing 'driveをリセットする 
end sub

javascriptで処理をして、リロードしないと情報が更新されない場合などに使えるかと思います。

 

seleniumとvbaを使えば様々な自動化が可能です。

他にも色々な機能がありますのでお試しあれ。

 

 

 

コメント

タイトルとURLをコピーしました