Skip to content

Instantly share code, notes, and snippets.

@ytyng
Last active October 31, 2022 12:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ytyng/5e02dd5ef496711a7ef8d117f6ff6098 to your computer and use it in GitHub Desktop.
Save ytyng/5e02dd5ef496711a7ef8d117f6ff6098 to your computer and use it in GitHub Desktop.
ChomeDriver を自動的にアップデートする Python スクリプト。mac用
#!/usr/bin/env python3
import os
import shutil
import subprocess
from typing import Optional
import xmltodict
import requests
def get_cpu_architecture() -> str:
"""
CPU のアーキテクチャを取得する
"""
return subprocess.run(
['uname', '-m'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
).stdout.decode('utf-8').strip()
def is_apple_silicon():
"""
Apple Silicon かどうかを判定する
"""
return get_cpu_architecture() == 'arm64'
def get_current_chromedriver_version_str():
"""
chrome のバージョン文字列。
e.g.: 107.0.5304.87
"""
current_version_path = \
'/Applications/Google Chrome.app/Contents/Frameworks' \
'/Google Chrome Framework.framework/Versions/current'
link = os.readlink(current_version_path)
return link
def get_current_chromedriver_version_list() -> list[str]:
"""
バージョン番号のリスト。文字列のリスト
e.g.: ['107', '0', '5304', '87']
"""
return get_current_chromedriver_version_str().split('.')
def get_published_chromedriver_versions_full_data():
"""
公開されている ChromeDriver のバージョン番号を取得
"""
response = requests.get('https://chromedriver.storage.googleapis.com/')
data = xmltodict.parse(response.content)
return data
def get_enabled_chromedriver_version(
major_version: str
) -> Optional[list[str]]:
"""
major_version に一致する chromedriver のバージョンを探す
"""
available = [] # バージョンのリストのリスト
full_data = get_published_chromedriver_versions_full_data()
# print(published_versions)
arch_str = 'chromedriver_mac64_m1' if is_apple_silicon() \
else 'chromedriver_mac64'
for published_version in full_data['ListBucketResult']['Contents']:
p_version_list = published_version['Key'].split('.')
if p_version_list[0] == major_version and \
len(p_version_list) == 5 and \
p_version_list[-1] == 'zip' and \
p_version_list[-2].endswith(arch_str):
available.append(p_version_list)
if not available:
# 見つからなかった
return None
available.sort()
print(available)
# 一番バージョン番号の高いものを取得
return available[-1]
def download_chromedriver(version: str):
"""
指定したバージョンの Chromedriver をダウンロードする
:param version: バージョン番号 (e.g.: 107.0.5304.62/chromedriver_mac64.zip)
"""
tmp_dir = '/tmp/chromedriver'
if os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)
os.makedirs(tmp_dir, exist_ok=True)
download_file_path = f'{tmp_dir}/chromedriver.zip'
with open(download_file_path, 'wb') as f:
url = f'https://chromedriver.storage.googleapis.com/{version}'
print('Downloading from', url)
r = requests.get(url)
f.write(r.content)
print('done.', download_file_path)
shutil.unpack_archive(download_file_path, tmp_dir)
new_driver_file_path = f'{tmp_dir}/chromedriver'
if os.path.exists(new_driver_file_path):
return new_driver_file_path
return None
def deploy_chromedriver(driver_path: str):
"""
ダウンロードした chromedriver のバイナリを
/usr/local/bin にコピーし、実行を許可する
"""
destination_path = '/usr/local/bin/chromedriver'
# chromedriver を /usr/local/bin にコピー
shutil.copy(driver_path, destination_path)
# chromedriver のパーミッションを変更
subprocess.run(
['chmod', '755', destination_path],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# 実行を許可する (バイナリを信頼する)
subprocess.run([
'xattr', '-dr', 'com.apple.quarantine', destination_path
], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def main():
current_version = get_current_chromedriver_version_list()
print('current version:', current_version)
major_version = current_version[0]
enabled_version = get_enabled_chromedriver_version(major_version)
if not enabled_version:
print('No chromedriver version for major version: {}'.format(
major_version))
return
print('enabled version:', enabled_version)
driver_path = download_chromedriver('.'.join(enabled_version))
if not driver_path:
print('Failed to download chromedriver')
return
deploy_chromedriver(driver_path)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment