作ったプログラムの備忘録
はじめに
- 社内LAN環境においてwebdriver_managerが上手く動かないので、webdriver_managerを使わないでも、webdriverの読込みエラーが出た際にレジストリからバージョン確認して、自動更新するようにした
- 需要はあまりないとは思うがメモとして記載
- 毎日実行しているが、気づいたら更新されているので、個人的には非常に便利に使っている
- またexe化して配布する際の初回起動時にwebdriverを同梱しなくても勝手にダウンロードしてくれるのでとても便利
動作テスト環境
OS: Windows 10 Pro 64bit
言語: Python 3.9.13
ライブラリ:Selenium 4.7.2
ソースコード
[2023.04.11追記]importの例外読み込みと例外処理にWebDriverExceptionを追加しました。
全体コード(Edgeの場合)
import os
import winreg
import shutil
import urllib.request
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service
from selenium.common.exceptions import SessionNotCreatedException
from selenium.common.exceptions import WebDriverException
driver_path = 'edgedriver_win64/msedgedriver.exe'
edge_service = Service(executable_path=driver_path)
try:
if not os.path.isfile(f'{os.getcwd()}/{driver_path}'):
raise FileNotFoundError()
driver = webdriver.Edge(service=edge_service)
except (FileNotFoundError, SessionNotCreatedException, WebDriverException):
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Edge\BLBeacon')
ver = winreg.QueryValueEx(key, 'version')[0]
site = r'https://msedgedriver.azureedge.net/'
folder_name = 'edgedriver_win64'
if os.path.exists(folder_name): shutil.rmtree(folder_name)
webdriver_dl = urllib.request.urlopen(f'{site}{ver}/{folder_name}.zip').read()
with open(f'{folder_name}.zip', mode="wb") as f:
f.write(webdriver_dl)
shutil.unpack_archive(f'{folder_name}.zip', folder_name)
os.remove(f'{folder_name}.zip')
driver = webdriver.Edge(service=edge_service)
解説
1. Webdriverのエラー検出
try:
if not os.path.isfile(f'{os.getcwd()}/{driver_path}'):
raise FileNotFoundError()
driver = webdriver.Edge(service=edge_service)
- そもそもwebdriverが存在しない場合を想定して、
FileNotFoundErrorを定義 - ここの
driver = webdriver.Edge(service=edge_service)でwebdriverのバージョンに起因するエラーが発生するとSessionNotCreatedException(またはWebDriverException)の例外が発生するので、以下のexcept部でwebdriverを自動更新する
2. 例外の定義
except (FileNotFoundError, SessionNotCreatedException, WebDriverException):
- webdriverが存在しない場合とバージョンが合わない場合に発生する3つの例外を想定
※WebDriverExceptionは記事投稿後に発生したのですが、SessionNotCreatedExceptionとの発生条件の違いがいまいちわかっていません。ただどちらの例外もWebDriverを削除して新しいものに入れ替えないと動かなかったので、例外に追加しています。
3. ブラウザバージョンの確認
Edgeのバージョン確認方法
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Edge\BLBeacon')
ver = winreg.QueryValueEx(key, 'version')[0]
chromeのバージョン確認方法
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r"Software\Google\Chrome\BLBeacon")
ver = winreg.QueryValueEx(key, 'version')[0]
- レジストリからブラウザのバージョンを取得するコード
- winregでレジストリの
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Edge\BLBeaconHKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon
にあるversion部分を読みに行っている - レジストリはオブジェクトとしてtupleでまとめられているので、
QueryValueEX以外にもver = winreg.EnumValue(key, 0)[1]などでも取得可能 - winregの詳細:https://docs.python.org/ja/3.7/library/winreg.html
4. webdriverのダウンロード元情報の定義
edgeの場合のURLとファイル名
site = r'https://msedgedriver.azureedge.net/'
folder_name = 'edgedriver_win64'
chromeの場合のURLとファイル名
site = r'https://chromedriver.storage.googleapis.com/'
folder_name = 'chromedriver_win32'
- webdriverのダウンロード元のURLとファイル名を定義
5. 既存のwebdriverの削除
if os.path.exists(folder_name): shutil.rmtree(folder_name)
- 既存のwebdriverが存在したら削除
6. webdriverをダウンロード・保存・解凍・zip削除
webdriver_dl = urllib.request.urlopen(f'{site}{ver}/{folder_name}.zip').read()
with open(f'{folder_name}.zip', mode="wb") as f:
f.write(webdriver_dl)
shutil.unpack_archive(f'{folder_name}.zip', folder_name)
os.remove(f'{folder_name}.zip')
- webdriverをダウンロードして保存、解凍、zipの削除を実行
7. 新しいwebdriverの読み込み
driver = webdriver.Edge(service=edge_service)
- 最後に自動更新したwebdriverを読み出す
関数化・外部モジュール化
最近は関数化したり、外部モジュール化しておいて、driverを読み込むようにしています。
def load_webdriver():
driver_path = 'edgedriver_win64/msedgedriver.exe'
service = Service(executable_path=driver_path)
# optionsはなくてもOK
options = EdgeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
options.add_argument('--window-size=1000,1000')
try:
if not os.path.isfile(f'{os.getcwd()}/{driver_path}'):
raise FileNotFoundError()
driver = webdriver.Edge(service=service, options=options)
except (FileNotFoundError, SessionNotCreatedException, WebDriverException):
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Edge\BLBeacon')
ver = winreg.EnumValue(key, 0)[1]
site = r'https://msedgedriver.azureedge.net/'
folder_name = 'edgedriver_win64'
if os.path.exists(folder_name):
shutil.rmtree(folder_name)
webdriver_dl = urllib.request.urlopen(f'{site}{ver}/{folder_name}.zip').read()
with open(f'{folder_name}.zip', mode="wb") as f:
f.write(webdriver_dl)
shutil.unpack_archive(f'{folder_name}.zip', folder_name)
os.remove(f'{folder_name}.zip')
driver = webdriver.Edge(service=service, options=options)
return driver
def main():
driver = load_webdriver()