【Selenium】WebDriverの自動更新(力技)

備忘録．

みんなあるよね，プロキシエラー．
## はじめに
Seleniumを使用して動的サイトのデータを自動取得するスクリプトを作成したが，ブラウザの自動更新（数週間に1回）によって，ダウンロードしたWebDriverのバージョンと合わなくなり動かなくなる．

 社内LAN環境において，プロキシの影響でwebdriver_managerやurllibが機能しない．（キミ，ガッチガチすぎんで...）
どうにかブラウザのバージョンに合ったWebDriverをダウンロードできないか，もがいてみた．↓

## 動作環境情報
- Windows 10 Pro 64bit（OS）
- Python 3.11.5（開発言語）
- Selenium 4.15.2（ライブラリ）
- PyAutoGUI 0.9.54（ライブラリ）
- Microsoft Edge 119.0.2151.58 64bit（ブラウザ）

※上記ライブラリをインストールしていない場合は以下のコマンド実行でインストール可能．
```
pip install selenium
pip install pyautogui
```

## 手法
URLをurllib以外で開いてみる．
標準ライブラリに含まれている"webbrowser"モジュールを使用する．

### ソースコード
```webdriver_update.py
import os
import time
import winreg
import zipfile
import webbrowser
import pyautogui as pag
from selenium import webdriver
from selenium.webdriver.edge.service import Service

downloadDir = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\Downloads\\"
outputDir = r"C:\Work"
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Edge\BLBeacon')
ver = winreg.QueryValueEx(key, 'version')[0]
sURL = "https://msedgedriver.azureedge.net/" + ver + "/edgedriver_win64.zip"
webbrowser.open(sURL)
time.sleep(5)

pag.keyDown("ctrl")
pag.press("w")
pag.keyUp("ctrl")

zipFile = downloadDir + "edgedriver_win64.zip"
zip_f = zipfile.ZipFile(zipFile)
zip_f.extractall(outputDir)
zip_f.close()
os.remove(zipFile)

driver_path = outputDir + "\\msedgedriver.exe"
svc = Service(executable_path = driver_path)
driver = webdriver.Edge(service = svc)
```

## 解説
### 1. フォルダ指定
```
downloadDir = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\Downloads\\"
outputDir = r"C:\Work"
```
- downloadDir : カレントユーザーのダウンロードフォルダ
- outputDir : msedgedriver.exeの出力先フォルダ（任意）

### 2. ブラウザのバージョン取得
```
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Edge\BLBeacon')
ver = winreg.QueryValueEx(key, 'version')[0]
```
- winreg... Windowsレジストリの読み書きが可能
(詳細)"https://docs.python.org/ja/3.11/library/winreg.html"
- winregでレジストリの"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Edge\BLBeacon\version"を取得している

### 3. URL指定 / WebDriverをダウンロード
```
sURL = "https://msedgedriver.azureedge.net/" + ver + "/edgedriver_win64.zip"
webbrowser.open(sURL)
time.sleep(5)
```
- sURL : 2.で取得したバージョン情報より，WebDriverのダウンロード元情報を設定
- webbrowser.open(sURL) : WebDriverをダウンロード
※webbrowserを使用すると残り香（ウィンドウ）があるため，後述4.でウィンドウを閉じる
- time.sleep : ダウンロード待ち時間
※今回は簡易的に5秒 Sleep．ちゃんとしたいならダウンロードフォルダのファイル数の変化を検知したり...ﾗｼﾞﾊﾞﾝﾀﾞﾘ...

### 4. ウィンドウを閉じる
```
pag.keyDown("ctrl")
pag.press("w")
pag.keyUp("ctrl")
```
ここで3. の残り香を排除します．パワーです．
見てお気づきになったと思います，そう「Ctrl+W」を実行しています．
<INS>ただここの懸念点として，前述3.のダウンロード開始から5秒（任意）の間に他のウィンドウに触れてしまうと，ソイツが消えてしまいます</INS>．闇のゲームの始まりだぜ！！

### 5. zipファイルの解凍 / 元zipファイル削除
```
zipFile = downloadDir + "edgedriver_win64.zip"
zip_f = zipfile.ZipFile(zipFile)
zip_f.extractall(outputDir)
zip_f.close()
os.remove(zipFile)
```
保存したzipを解凍し，不要なモノは削除
- zip_f : zipファイルオブジェクト指定
- zip_f.extractall(outputDir) : zipファイルを任意の場所に解凍
※同じフォルダに"msedgedriver.exe"（WebDriver）がある場合，上書きされる
- zip_f.close() : アーカイブファイルをクローズ
- os.remove(zipFile) : ダウンロードフォルダにあるzipファイルを削除

## 関連記事
WebDriverの自動更新でお困りの方は以下の記事も参考にしてみてください．

https://qiita.com/aokym/items/bf4a74da767cd676a2c8

https://qiita.com/takafi/items/a0cf8f8025032f9354b4

## おわりに
ログオン時に限定されるが，とりあえずWebDriverの自動更新が実行できて良かった．
基本的に作成した自動化スクリプトはタスクスケジューラで定期実行しているので，どうにかしてログオフ時でも動くようにしたい...