Selenium Basic！Excelでブラウザ自動操作

Excel(VBA)でSeleniumを使いたい場面が。。
使わなくちゃいけない場面が出てきてしまったので、使い方のメモ

Excelでブラウザ操作する際には Selenium Basic を使うと楽々
何もインストールしなくてもWindows標準だけでもできるけど、まぁ苦行
　http://www.ken3.org/cgi-bin/group/vba_ie.asp
　https://www.fastclassinfo.com/entry/vba_ie_control


とりあえずサンプル
　Yahoo を開いて、「スマホ」を検索して、検索件数を取得
　検索結果画面を画像で保存（エクセルにも貼り付け）
な動きをするサンプルです


```vb
Option Explicit

Sub Yahoo検索()

    '// ブラウザ設定
    Dim Driver As New Selenium.ChromeDriver
'    Driver.AddArgument "headless"
'    Driver.AddArgument "window-size=1280,2400"
    
    '// ブラウザを開く
    Driver.Start
    Driver.Get ("http://yahoo.co.jp/")
    Driver.Wait 1000    '// １秒待ち

    '// 検索文字入力
    Driver.FindElementByName("p").Clear
    Driver.FindElementByName("p").SendKeys ("スマホ")
    Driver.Wait 1000    '// １秒待ち
    
    '// 検索ボタンを押す
    Driver.FindElementByXPath("//*[@id=""ContentWrapper""]/header/section[1]/div/form/fieldset/span/button").Click
    Driver.Wait 1000    '// １秒待ち
    
    '// 検索結果の画面を保存（ファイルで）
    Driver.TakeScreenshot(100).SaveAs "C:\yahoo.png"
    
    '// 検索結果の画面を保存（エクセル貼り付け）
    Dim img As Selenium.Image
    Set img = Driver.TakeScreenshot
    img.ToExcel Range("F7")
    
    '// ちょっとリサイズして貼り付け
    Dim img2 As Selenium.Image
    Set img2 = Driver.TakeScreenshot(100)
    img2.Resize (300)
    img2.ToExcel Range("G8")
    
    '// 検索結果件数を取得
    Dim wk As String
    wk = Driver.FindElementByClass("Hits__item").FindElementByTag("span").Text
    
    '// 検索結果件数を表示
    MsgBox ("検索結果の件数：" & wk)
    
    '// ブラウザ終了
    Driver.Close
    Set Driver = Nothing
    
End Sub
```

上記サンプルでは操作対象の絞り込みにいろんな方法を使ってます。



## FindElementByName

```vb
    Driver.FindElementByName("p").SendKeys ("スマホ")
```

HTML上で <b>name=</b>  で定義されている要素を選択

```html
<input type="search" name="p" aria-label="検索したいキーワードを入力してください"
```


## FindElementByClass

HTML上で <b>class=</b>  で定義されている要素を選択

```html
<div class="Hits__item">約<span class="util-Text--bold">748,000,000</span>件
```


## FindElementByXPath

HTML の XPath で要素を選択

```html
[@id="ContentWrapper"]/header/section[1]/div/form/fieldset/span/button")

例： ID要素 [ContentWrapper] の
  <header>
    <section>
      <div>
        <form>
          <fieldset>
            <span>
              <button>
を選択
```

## FindElementById

サンプルでは使ってませんが、 ID で指定できれば一番楽です

```html
<div id="header"
```


でも、実際はこんな簡単に要素を指定できないことが多く、いろんな手法を組み合わせます。
詳しくまとめてくださっている記事（ありがたい）
　[Seleniumで要素を選択する方法まとめ](https://qiita.com/VA_nakatsu/items/0095755dc48ad7e86e2f)



## 表示画面の取得

TakeScreenshot で表示している画面を画像として取得できます。
が、本当に画面に表示している部分しか取れないので、スクロールしないと見えない部分が取れません。。

そこで、ブラウザを非表示にして画面サイズをとっても大きく設定しておけばスクロールしなくても全体が取得できるようになります。

上記サンプルではコメントアウトしている部分を有効にして確認してみてくださいです。

```vb
    '// ブラウザ設定
    Dim Driver As New Selenium.ChromeDriver
'    Driver.AddArgument "headless"                  
'    Driver.AddArgument "window-size=1280,2400"
```

Driver.AddArgument の部分を有効化



以上
とりあえずの使い方メモ




## IE版（Windows標準機能のみ版）

要望があったので一応載せておく
IE。。Selenium ではなくてWindows標準だけでやると、苦行になります
が、Seleniumインストールできない場合は頑張るしかないのか？
詳しくは解説しませんので 三流君に聞いてみてください。
　http://www.ken3.org/cgi-bin/group/vba_ie.asp

```vb
Option Explicit

Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long    '指定したウィンドウをアクティブウィンドウにする

Sub IEサンプル()

    '// ブラウザ準備
    Dim IE As InternetExplorer
    Set IE = CreateObject("InternetExplorer.Application")
    IE.Visible = True

    '// ブラウザを開く
    IE.navigate "http://yahoo.co.jp/"
    Call IEWait(IE)     '// ページ読み込み終了まで待機
    Call WaitFor(3)     '// ３秒待つ

    '// ブラウザをアクティブに
    SetForegroundWindow IE.hwnd
    
    '// 検索文字入力 - Yahooは開くと検索窓にフォーカスがあるので、SendKeysで行けます。。（手抜き。。 Value直接設定だと Yahooがスクリプトを疑って別ページに飛ばされちゃうし。。
    SendKeys "スマホ"
    
    '// 検索文字入力 - ほんとはこんな感じ
'    Dim input検索
'    For Each input検索 In IE.document.getElementsByName("p")
'Debug.Print input検索.outerHTML
'        input検索.Value = "スマホ"
'        Exit For
'    Next input検索
'    Call WaitFor(3)      '// ３秒待つ
    
    '// 検索ボタンを押す
    Dim btn検索
    For Each btn検索 In IE.document.getElementsByTagName("button")
        Debug.Print btn検索.outerHTML
        If InStr(btn検索.outerHTML, "検索") > 0 Then
            btn検索.Click
            Exit For
        End If
    Next
    Call IEWait(IE)     '// ページ読み込み終了まで待機
    Call WaitFor(3)     '// ３秒待つ
    
    '// 検索結果件数を取得
    Dim wk As String
    Dim div
    For Each div In IE.document.getElementsByClassName("Hits__item")
'Debug.Print div.outerHTML
        Dim span
        For Each span In div.getElementsByTagName("span")
'Debug.Print span.outerHTML
            wk = span.innerText
            Exit For
        Next span
        Exit For
    Next div
    
    '// 検索結果件数を表示
    MsgBox ("検索結果の件数：" & wk)
    
    '// ブラウザ終了
    IE.Quit
    Set IE = Nothing
    
End Sub

Private Sub IEWait(ByRef IE As Object)
    Do While IE.Busy = True Or IE.readyState <> 4
        DoEvents
    Loop
End Sub

Private Sub WaitFor(ByVal second As Integer)
    Dim 待機時間 As Date
    待機時間 = DateAdd("s", second, Now)
    Do While Now < 待機時間
        DoEvents
    Loop
End Sub
```

詳しい記事はこちら
[IE自動操作コード一覧（ExcelVBA / VBScript）](https://qiita.com/nezuq/items/93390c4def01991c0354)