VBA_Selenium_ブラウザ操作（Chrome）

今回はVBAにてSeleniumを使用したブラウザ操作（準備/使用例）についてです。
本投稿はChromeDriverの使用を前提とします。

#### SeleniumBasicの導入
GitHubのリリースページから[SeleniumBasic](https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0)をダウンロードします。
![2023090610_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/d3f6a003-1c19-b1a7-f254-abb7c9951c8f.png)

落としたexeファイルを実行し、セットアップ画面を進めます。
途中で必要なコンポーネントにチェックを入れ、インストール場所を指定して終了です。

#### WebDriverの準備
今回はChromeを操作するので[ChromeDriver](https://sites.google.com/chromium.org/driver/downloads)をダウンロード。
注意点として、ブラウザのバージョンに合わせてDriverを選ぶ必要があります。

＜ブラウザのバージョン確認方法＞
・アドレスバーに「chrome://settings/help」と入力
または 設定>[Chromeについて] より確認
![2023090611_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/d30fe6c2-0428-5336-dcd8-9033924f51eb.png)

#### VBE事前設定
SeleniumBasicが導入されていると 
ツール>参照設定>[Selenium Type Library] が表示されるのでチェックを入れます。
![2023090608_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/32a0a283-1b2d-f326-36be-87d195f0f677.png)

#### クラスやメソッドについて
下記のヘルプファイルに記載されていますが、ご覧の通り英文です。
私は翻訳して使っています。
（フォルダパス：C:\Users\ユーザ名\AppData\Local\SeleniumBasic）
![2023090604_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/dde9e578-14ad-46da-eb27-f31f2bce572e.png)

#### 使用例
##### ブラウザ起動、ページ偏移
・WebDriverクラス Getメソッド：指定したページに偏移
```
Const strUrl   As String = "https://www.google.com"
Dim driver     As New Selenium.ChromeDriver

'ブラウザ起動、指定ページ表示
driver.Get (strUrl)
```

操作中は下の図のように自動操作中と表示されます。
![2023090601_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/19ee074b-4c28-66a7-1df8-857dce9d5d44.png)
また、プロファイルを指定して立ち上げる場合はSetProfileメソッドを使います。
下図では隠しましたが赤枠のところにパスが記載されています。
パスの確認方法は下記のとおり
・指定したいGoogleアカウントにログイン後、
　Chromeのアドレスバーに「chrome://version/」と入力。
・デフォルトだと下記パス直下にあるユーザープロファイルフォルダのパスを指定
　C:\Users\ユーザ名\AppData\Local\Google\Chrome\User Data
![2023090603_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/7cc370e8-c0a3-5de5-9e38-a916a2bb4b74.png)
```
Const strProfile    As String = "hoge" '実際にはプロファイルのパスを指定
'プロファイルの指定
driver.SetProfile strProfile
```
また、プロファイルを指定して起動した際、
既に指定のプロファイルを使用しているウィンドウがある場合、エラーとなります。

##### ブラウザを終了
下記のように、どこまで閉じるかによってメソッドが変わってきます。
・WebDriverクラス Quitメソッド：ブラウザごと閉じる
・WebDriverクラス Closeメソッド：開いているタブを閉じる
```
driver.quit
'driver.close タブを閉じる場合
```

##### 処理待機について
・WebDriverクラス Waitメソッド：次の処理までの待機時間指定（ミリ秒）
```
driver.Wait 1000 '1秒待機
```

##### クリック操作
今回はこちら[Webスクレイピング入門](https://scraping-for-beginner.herokuapp.com/)さんのサイトで動作を確認します。

<b>＜完全一致するリンクテキストをクリックする場合＞</b>
・WebDriverクラス FindElementByLinkTextメソッド：完全一致するリンクテキストの検索

```
Const lnkLogin  As String = "ログイン"
driver.FindElementByLinkText(lnkLogin).Click 'リンク「ログイン」押下
```
<b>＜XPathを指定してクリックする場合＞</b>
ブラウザの開発ツール（ショートカット：F12）より取得できます。
Chromeの場合の手順は下記のとおり。
![2023090605_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/d6cd67e0-7e6a-bb4a-dbff-e09f33e8602f.png)
また、取得したXPathは次のようにダブルクォートを付ける必要があります。
変更前："//*[<span>@</span>id="nav-mobile"]/li[1]/a"
変更後："//*[<span>@</span>id=""nav-mobile""]/li[1]/a"

・WebDriverクラス FindElementByXPathメソッド
```
Const lnkLogin  As String = "//*[@id=""nav-mobile""]/li[1]/a"
driver.FindElementByXPath(lnkLogin).Click
```
##### テキストの送信
ログインページの赤枠部分の送信です。
上記手順と同じくXPathを取得します。
![2023090607_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/b3521025-a8ae-335d-e6fe-a24fce1e7b6e.png)

XPathを取得したら、入力したいテキストをSendkeysの後ろに指定します。
削除する場合はClearを使用します。
```
Const txtLoginUser  As String = "//*[@id=""username""]" '赤枠部分
Const strUserName   As String = "test"
'ユーザ名入力
driver.FindElementByXPath(txtLoginUser).SendKeys strUserName
'削除する場合
driver.FindElementByXPath(txtLoginUser).Clear
```

ログインボタン押下もXPathを取得し、先程と同様にクリック処理をします。
```
Const btnLogin      As String = "//*[@id=""login-btn""]"
'ログインボタン押下
driver.FindElementByXPath(btnLogin).Click
```

ログインに失敗すると、下記画面のように「ログインに失敗しました」と表示されるようです。この表示を拾って次の処理に繋げてみます。
![2023090609_qt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552400/414859d3-9733-efda-efdd-ca2ee285c70b.png)

ログインページにて、エラー文言が表示されたら処理を中断する場合

```
Const errLogin      As String = "/html/body/main/center/h5"
Dim strMsg          As String

'表示されたテキストを取得し識別
strMsg = driver.FindElementByXPath(errLogin).Text
If strMsg = "ログインに失敗しました" Then
    driver.Quit
End If
```

#### おわりに
（Seleniumを使用して良い環境ということを前提で）
定型業務にかける時間の削減や、人為的な操作ミスがなくなる、
といった便利な点がある一方、
当然、アクセス先になるべく負荷を与えないよう注意する必要があります。
WebDriverの更新やダイアログ操作についても今後書けたらと思います。

参考サイト：
・https://scraping-for-beginner.readthedocs.io/ja/latest/src/1.html

使用サイト：
・https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0
・https://sites.google.com/chromium.org/driver/downloads
・https://scraping-for-beginner.herokuapp.com/

エンジニアファーストの会社 [株式会社CRE-CO](https://www.cre-co.jp/#top)　S.K