Python+SeleniumでWebDriverを自動管理してくれるクラスを作ってみたら同じような機能を持つパッケージがあったのでソースコードを供養します。
タイトルで終わり!
ソースコード
メイン
"""Google ChromeのWebDriverを管理するクラス """ import os import platform import subprocess from urllib.parse import urlparse import requests from urllib.request import urlretrieve from bs4 import BeautifulSoup as bs from tempfile import NamedTemporaryFile from zipfile import ZipFile class ChromeUpdater(): """ ChromeのWebDriver更新クラス Returns: Chrome: WebDriver更新クラス """ SYS_TO_VER_GETTER_CMD: dict[str, list[str]] = { 'Windows': [ 'powershell', '-command', '(Get-Item "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe").VersionInfo.ProductVersion'], 'Darwin': [ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', '--version'] } SYS_TO_WEBDRIVER_NAME: dict[str, str] = { 'Windows': 'chromedriver.exe', 'Darwin': 'chromedriver' } SYS_TO_ZIP_FILENAME: dict[str, str] = { 'Windows': 'chromedriver_win32.zip', 'Darwin': 'chromedriver_mac64.zip' } MAIN_PAGE_URL: str = 'https://chromedriver.chromium.org/downloads' def __init__(self, webdrivers_basedir:str=os.getcwd()) -> None: """ 初期化処理。実行しているOSを判別し、ファイル名、バージョン取得のコマンドを確定させる。 Args: working_dir (str, optional): WebDriverを管理するディレクトリ. Defaults to os.getcwd(). """ self.basedir = os.path.join(webdrivers_basedir, 'webdrivers','chrome') pfsys = platform.system() self.filename = ChromeUpdater.SYS_TO_WEBDRIVER_NAME[pfsys] self.zipfilename = ChromeUpdater.SYS_TO_ZIP_FILENAME[pfsys] self.version_get_cmd = ChromeUpdater.SYS_TO_VER_GETTER_CMD[pfsys] self.major_version = self._get_version() self.webdriver_dir = os.path.join(self.basedir, self.major_version) self.webdriver_path = os.path.join(self.webdriver_dir, self.filename) def _get_version(self) -> str: """ Chromeバージョンの取得 Returns: str: バージョン番号(メジャー) """ out = subprocess.run( self.version_get_cmd, capture_output=True, text=True, check=True).stdout return out.strip().split()[-1].split('.')[0] def update(self) -> None: """ WebDriverの更新。該当するWebDriverが存在しない場合にのみダウンロードを行う。 """ if os.path.exists(self.webdriver_path): return self.download() def get_webdriver_dl_url(self) -> str: """ WebDriverダウンロードのためのURLの取得 Returns: str: WebDriverのURL """ # ダウンロードページから表示されている res = requests.get(ChromeUpdater.MAIN_PAGE_URL) soup: bs = bs(res.text, 'html.parser') # WebDriverダウンロードサイトから環境と同じバージョンのWebDriverをダウンロードする。 sel = f'p>span>a[href*="path={self.major_version}"]' urls = [a.attrs['href'] for a in soup.select(sel)] dlpage_url = urls[0] # 該当バージョンのダウンロードページURLから直接DLするURLを作成する。 pr = urlparse(dlpage_url) return '{}://{}/{}{}'.format( pr.scheme,pr.netloc,pr.query.split('=')[1],self.zipfilename ) def download(self): """ WebDriverのダウンロード。 """ # 一時ファイルにダウンロードして解凍を行う。 with NamedTemporaryFile() as ntf: urlretrieve(self.get_webdriver_dl_url(), ntf.name) ZipFile(ntf.name).extractall(self.webdriver_dir)
テストコード
今回はテストコードにもチャレンジ。pytestしてみました。
""" ChromeUpdaterのテスト """ import pytest # pylint: disable=W0611 from os import getcwd from os.path import exists,join from tempfile import TemporaryDirectory from twidence.webdriver.chrome import ChromeUpdater def test_init(): curdir = getcwd() crm = ChromeUpdater() assert crm.basedir == join(curdir,'webdrivers','chrome') assert crm.filename == 'chromedriver' assert crm.major_version == '95' assert crm.webdriver_dir == join(curdir,'webdrivers','chrome','95') assert crm.webdriver_path == join(curdir,'webdrivers','chrome','95','chromedriver') assert crm.zipfilename == 'chromedriver_mac64.zip' def test_init_arg1(): with TemporaryDirectory(prefix=join(getcwd(),'test_workdir')) as tmpdir: crm = ChromeUpdater(tmpdir) assert crm.basedir == join(tmpdir,'webdrivers','chrome') assert crm.filename == 'chromedriver' assert crm.major_version == '95' assert crm.webdriver_dir == join(tmpdir,'webdrivers','chrome','95') assert crm.webdriver_path == join(tmpdir,'webdrivers','chrome','95','chromedriver') assert crm.zipfilename == 'chromedriver_mac64.zip' def test_get_webdriver_dl_url(): crm = ChromeUpdater() url = crm.get_webdriver_dl_url() assert url=='https://chromedriver.storage.googleapis.com/95.0.4638.54/chromedriver_mac64.zip' def test_update(): with TemporaryDirectory(prefix=join(getcwd(),'test_workdir_')) as tmpdir: crm = ChromeUpdater(tmpdir) crm.update() assert crm.basedir == join(tmpdir, 'webdrivers', 'chrome') assert exists(join(tmpdir, 'webdrivers')) assert exists(join(tmpdir, 'webdrivers', 'chrome')) assert exists(join(tmpdir, 'webdrivers', 'chrome', '95')) assert exists(join(tmpdir, 'webdrivers', 'chrome', '95', 'chromedriver'))
同じような機能を持つパッケージ、webdriver_manager
参考リンク
以上!