Last active
October 31, 2022 12:46
-
-
Save ytyng/5e02dd5ef496711a7ef8d117f6ff6098 to your computer and use it in GitHub Desktop.
ChomeDriver を自動的にアップデートする Python スクリプト。mac用
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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