ChromeDriver を自動更新する Python スクリプト

投稿者: ytyng 1年, 6ヶ月 前

最新版の ChromeDrier と適合するテスト版 Chrome をインストールするスクリプトを書いた。 (バージョン115以上対応)

sudo パスワードの入力を求めます。

#!/usr/bin/env python3
"""
ChromeDriver と Chrome テスト版を自動更新するスクリプト
"""
import getpass
import shutil
import subprocess
import pathlib
from contextlib import contextmanager

import requests
import os

USER_AGENT = '@ytyng/upgrade_chromedriver'

default_request_headers = {
    'User-Agent': USER_AGENT
}

DOWNLOAD_DIR = os.path.expanduser('~/Downloads')


@contextmanager
def set_directory(path: pathlib.Path):
    """Sets the cwd within the context

    Args:
        path (Path): The path to the cwd

    Yields:
        None
    """

    origin = pathlib.Path().absolute()
    try:
        os.chdir(path)
        yield
    finally:
        os.chdir(origin)


def get_cpu_architecture() -> str:
    """
    CPU のアーキテクチャを取得する
    """
    return subprocess.run(
        ['uname', '-m'],
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT
    ).stdout.decode('utf-8').strip()


def get_current_machine_platform():
    """
    JSON の platform に適合する文字列を返す。
    mac-arm64, mac-x64 の他に、linux64, win32, win64 があるが、
    現状は mac のみ対応する。
    """
    a = get_cpu_architecture()
    if a == 'arm64':
        return 'mac-arm64'
    else:
        return 'mac-x64'


json_url = 'https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json'

_rdata = requests.get(json_url, headers=default_request_headers).json()

# chrome と chromedriver が両方存在するもののみにフィルター
_versions = [v for v in _rdata['versions'] if
             v['downloads'].get('chromedriver') and v['downloads'].get(
                 'chrome')]

_versions = sorted(_versions,
                   key=lambda x: tuple(map(int, x['version'].split('.'))),
                   reverse=True)


def download_latest_version(version_dict, app_name: str):
    """
    ファイルをダウンロードする
    :param app_name: str 'chrome' or 'chromedriver'
    """
    print(f'Downloading {app_name}...')
    _platform = get_current_machine_platform()
    target_url = [d for d in version_dict['downloads'][app_name] if
                  d['platform'] == _platform][0]['url']
    file_binary = requests.get(target_url, headers=default_request_headers)

    file_name = DOWNLOAD_DIR + '/' + target_url.split('/')[-1]
    with open(file_name, 'wb') as f:
        f.write(file_binary.content)
    print('Downloaded:', file_name)


# 最新版
download_latest_version(_versions[0], 'chrome')
download_latest_version(_versions[0], 'chromedriver')

print('Input sudo password')
sudo_password = (getpass.getpass() + '\n').encode()


def _install_chromedriver(sudo_password):
    print('Installing chromedriver...', flush=True)
    _platform = get_current_machine_platform()
    _zip_file_path = f'{DOWNLOAD_DIR}/chromedriver-{_platform}.zip'
    _extracted_dir_path = f'{DOWNLOAD_DIR}/chromedriver-{_platform}'

    with set_directory(DOWNLOAD_DIR):
        if os.path.exists(_extracted_dir_path):
            shutil.rmtree(_extracted_dir_path, ignore_errors=True)
        unzip_output = subprocess.run(
            ['unzip', _zip_file_path],
            stdout=subprocess.PIPE, stderr=subprocess.STDOUT
        ).stdout.decode('utf-8').strip()
        print(unzip_output)

        exists_chromedriver_path = shutil.which('chromedriver')
        print('exists_chromedriver_path:', exists_chromedriver_path)

        install_output = subprocess.run(
            ['sudo', '-S', 'mv', f'{_extracted_dir_path}/chromedriver',
             exists_chromedriver_path], input=sudo_password, check=True
        )
        print('Chromedriver installed.', install_output)


_install_chromedriver(sudo_password)


def _install_chrome(sudo_password):
    print('Installing chrome...', flush=True)
    _platform = get_current_machine_platform()
    _zip_file_path = f'{DOWNLOAD_DIR}/chrome-{_platform}.zip'
    _extracted_dir_path = f'{DOWNLOAD_DIR}/chrome-{_platform}'
    _installed_chrome_path = '/Applications/Google Chrome for Testing.app'

    with set_directory(DOWNLOAD_DIR):
        if os.path.exists(_extracted_dir_path):
            shutil.rmtree(_extracted_dir_path, ignore_errors=True)

        if os.path.exists(_installed_chrome_path):
            shutil.rmtree(_installed_chrome_path, ignore_errors=True)

        unzip_output = subprocess.run(
            ['unzip', _zip_file_path],
            stdout=subprocess.PIPE, stderr=subprocess.STDOUT
        ).stdout.decode('utf-8').strip()
        print(unzip_output)

        install_output = subprocess.run(
            ['sudo', '-S', 'mv',
             f'chrome-{_platform}/Google Chrome for Testing.app',
             '/Applications/'], input=sudo_password, check=True
        )

        print('Chrome for Testing installed.', install_output)


_install_chrome(sudo_password)
現在未評価

コメント

アーカイブ

2024
2023
2022
2021
2020
2019
2018
2017
2016
2015
2014
2013
2012
2011