【Selenium】chromedriverを自動更新するVBSスクリプト

この記事は、windows10でSelenium + GoogleChromeでスクライピングしている方に向けた記事です。
Excel+Seleniumbasicにも対応しているところがポイントです。

# chromedriverは更新が面倒
気づいたら「オートメーションエラー」になるchromedriver。
「はいはい『chromedriver』と検索して……あのサイトに行って……このフォルダに上書きして……」

この単純な作業はvbsにしてワンクリックで完了させましょう。

Pythonにはpipコマンドがあるのでそちらのほうが楽ですが、このvbsコードはHttpリクエストによって実装しているので、Excel+Seleniumbasicなどに対応した汎用でスタンドアロンな自動更新ができます

## コードをメモ帳に貼り付けて.vbsで保存
コードをメモ帳に貼り付け、コード内の「★コメント」の行をあなたのローカル環境に合わせて書き換えて、拡張子「.vbs」で保存してください。
※「.vbs」はSJISで保存しないとエラーになります。最近のテキストエディタはUTF-8が増えていますので注意。

保存したvbsをダブルクリックで実行すれば、今使っているGoogleChromeのバージョンと同じマイナーバージョンを持つchromedriver.exeを自動でダウンロード＆上書きします。



```vb:
'-----------------------------------------------------------------------
' Seleniumのchromedriver.exeを自動で更新するスクリプト
' 更新日:2022-12-07
'-----------------------------------------------------------------------
Call update_driver()
WScript.Quit()
'=======================================================================

Sub update_driver()
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set objShell = WScript.CreateObject("WScript.Shell")
    '-------------------------------------------------------------
    'USER SETTING
    chromeDir = "C:\Program Files\Google\Chrome\Application"           '★chrome.exeのあるディレクトリ(GoogleChromeのフォルダ)
    seleniumDir = fso.getParentFolderName(WScript.ScriptFullName)      '★chromedriver.exeのディレクトリ。デフォルトでこのスクリプトのフォルダ
    msgbox_is = False                                                  '★更新したかメッセージボックスで表示する場合はTrue
    '-------------------------------------------------------------
    If myDir(seleniumDir) <> "" Then
        version = chkVersion(chromeDir, seleniumDir, msgbox_is)
        Call chromedriverDL(version, seleniumDir, msgbox_is)
    End If
End Sub
'=======================================================================

Sub chromedriverDL(version, destDir, msgbox_is)
    'chromedriverをダウンロードする関数
    'version : ダウンロードしたいバージョン。例)「78.0.3904.105」
    'destDir : 新しいchromedriverを置くディレクトリ。
    '例)「78.0.3904.105」= [メジャー].[マイナー].[ビルド].[リビジョン]どこまで一致させるか
    If version = "" Then Exit Sub
    dots = Split(version, ".")
    version = Left(version, Len(version) - Len(dots(UBound(dots))) - 1)     '"ビルドまで一致"指定：(互換性高。入手性低)
    version = Left(version, Len(version) - Len(dots(UBound(dots))) - 1)     '"マイナーまで一致"指定：(互換性低。入手性高)※この行をコメントアウトで"ビルドまで一致"に変更。
    
    Set objShell = CreateObject("WScript.Shell")
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Set httpReq = CreateObject("MSXML2.XMLHTTP")
    If Err.Number <> 0 Then
        Set httpReq = CreateObject("MSXML.XMLHTTPRequest")
    End If

    Const zipName = "chromedriver_win32.zip"
    workDir = objShell.CurrentDirectory & "\" & zipName         'このvbsの場所を作業フォルダに
    'workDir = ThisWorkbook.path & "\" & zipName

    httpReq.Open "GET", "https://chromedriver.storage.googleapis.com", False
    httpReq.Send
    
    txtS = InStr(httpReq.responseText, version)
    txtE = InStr(txtS, httpReq.responseText, "/chromedriver_linux64.zip</Key>")
    version = Mid(httpReq.responseText, txtS, txtE - txtS)
    
    Url = "https://chromedriver.storage.googleapis.com/" & version & "/chromedriver_win32.zip"
    
    httpReq.Open "GET", Url, False
    httpReq.Send
    
    Set objStream = CreateObject("ADODB.Stream")
    objStream.Open
    objStream.Type = 1
    objStream.write httpReq.responseBody
    objStream.SaveToFile workDir, 2
    objStream.Close

    Call unzip(workDir, destDir)
    fso.DeleteFile workDir

    Set objStream = Nothing
    Set httpReq = Nothing
    '----------------------------------------------
    '更新した履歴(バージョン)をテキストに記録する
    Filename = destDir & "\version.txt"
    Set tso = fso.OpenTextFile(Filename, 2, True)
    tso.write (version)
    tso.Close
    '----------------------------------------------
    If msgbox_is = True Then MsgBox "updated chromedriver : " & version
End Sub
'=======================================================================
'.zipファイルを解凍する関数
Sub unzip(sourcePath, destDir)
    Const FOF_SILENT = &H4                '進捗ダイアログを表示しない。
    Const FOF_NOCONFIRMATION = &H10       '上書き確認ダイアログを表示しない（[すべて上書き]と同じ）。

    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.Namespace(destDir)
    Set FilesInZip = objShell.Namespace(sourcePath).items

    '解凍
    If (Not objFolder Is Nothing) Then
       objFolder.CopyHere FilesInZip, FOF_NOCONFIRMATION + FOF_SILENT
    End If
End Sub
'=======================================================================
'インストールされているGoogleChromeのバージョンをチェックする
Function chkVersion(chromeDir, destDir, msgbox_is)
    '-------------------------------------------------------------
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.getFolder(chromeDir)

    'サブフォルダ一覧
    version = ""
    For Each subfolder In folder.subfolders
        dots = Split(subfolder.Name, ".")
        If UBound(dots) > 2 Then
            version = subfolder.Name
            Exit For
        End If
    Next

    'エラーチェック
    If version = "" Then
        MsgBox "現在のChromeのversionが取得できませんでした。" & vbCrLf & "終了します。"
        WScript.Quit -1
    End If
    '-------------------------------------------------------------
    'このvbsによって最近アップデートしたchromedriverのバージョンと
    'このPCのGoogleChromeのバージョンを比較して、そもそもアップデートが必要なのか判断する
    Filename = destDir & "\version.txt"        'C:\Users\TEST\AppData\Local\SeleniumBasic\version.txt

    If fso.FileExists(Filename) Then
        Set fp = fso.OpenTextFile(Filename, 1)
        curVersion = fp.ReadAll
        fp.Close

        'メジャー.マイナー.ビルド.リビジョン
        dots = Split(curVersion, ".")
        If UBound(dots) > 2 Then
            buildver = Left(curVersion, Len(curVersion) - Len(dots(UBound(dots))) - 1)
            minorver = Left(buildver, Len(buildver) - Len(dots(UBound(dots) - 1)) - 1)

            If InStr(version, buildver) > 0 Then
                If msgbox_is Then
                    MsgBox "Checked build-version." & vbCrLf & "But the driver is as new as chrome." & vbCrLf & " Not updated. " & destDir
                End If
                chkVersion = ""
                Exit Function
            ElseIf InStr(version, minorver) > 0 Then
                If msgbox_is Then
                    MsgBox "Checked build-version." & vbCrLf & "But the driver is as new as chrome." & vbCrLf & " Not updated. " & destDir
                End If
                chkVersion = ""
                Exit Function
            End If
        End If
    Else
        Set tso = fso.OpenTextFile(Filename, 2, True)
        tso.write ("0.0.0.0")
        tso.Close
    End If
    '-------------------------------------------------------------
    chkVersion = version
End Function
'=======================================================================
'DIR関数(パスの存在判定をする:VBAにあってVBSにない関数)
Function myDir(path)
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FolderExists(path) Then
        myDir = path
    Else
        myDir = ""
    End If
    Set fso = Nothing
End Function
'=======================================================================
```

「chromedriverを自動更新するVBSスクリプト」の記事は以上です。

-----------------------------------