以前通过ChromeDriverManager().install()的方式自动下载驱动的方式,现在行不通了,访问不通下载网址,会报错:requests.exceptions.ConnectionError: Could not reach host. Are you offline?
所以想着换一个下载地址和方式,通过国内的镜像https://registry.npmmirror.com/binary.html?path=chrome-for-testing/下载。
通过接口返回分析发现该网站获取驱动版本的地址为:https://registry.npmmirror.com/-/binary/chrome-for-testing/ ,最终的下载地址前缀为 https://cdn.npmmirror.com/binaries
于是有了下面 的代码,通过windowsAPI获取安装的浏览器的版本,通过上面的地址获取浏览器驱动版本列表信息,找到与浏览器大版本号相同的最新版本的驱动版本,拼接成最终的下载地址。下载驱动压缩包,用解压缩出来的驱动exe文件替换原来的旧文件,然后删除解压缩文件和下载的压缩文件。
"""
根据浏览器版本,更新驱动为对应版本的驱动文件
pip install requests
pip install pywin32
"""
import os
import zipfile
import requests
from win32com import client
import shutil
def get_version_by_path(exe_path):
"""通过谷歌浏览器的安装路径下的.exe获取浏览器版本
exe_path 浏览器exe程序文件完整路劲,
如:"C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
"""
# 判断路径文件是否存在
if not os.path.isfile(exe_path):
raise FileNotFoundError(f"{exe_path} is not found.")
version = client.Dispatch('Scripting.FileSystemObject').GetFileVersion(exe_path)
return version.strip()
def get_download_url(version, browser_name='chrome'):
""" 获取与版本适配的驱动文件的下载地址
version为浏览器版本
browsern_name为浏览器名称
"""
download_url = 'https://cdn.npmmirror.com/binaries'
root = 'https://registry.npmmirror.com/-/binary/'
chrome_path = 'chrome-for-testing/'
edge_path = 'edgedriver/'
gecko_path = 'geckodriver/'
version_url = root + chrome_path
if browser_name == 'edge':
version_url = root + edge_path
# 获取与当前版本匹配的最大版本的下载地址
response = requests.get(url=version_url)
if response.status_code == 200:
version_list = eval(response.text)
for i in range(len(version_list)):
dic = version_list[i]
if int(dic['name'].split('.')[0]) > int(version.split('.')[0]):
driver_version = version_list[i - 1]['name']
if browser_name == 'chrome':
download_url = f'{download_url}/chrome-for-testing/{driver_version}win64/chromedriver-win64.zip'
if browser_name == 'edge':
download_url = f'{download_url}/edgedriver/{driver_version}edgedriver_win64.zip'
return download_url
def download_driver(url, file_path, browser_name='chrome'):
""" 下载驱动文件到指定路径
url 为文件下载地址
filepath 为文件保存下载文件的文件夹
"""
driver_file = 'chromedriver.exe'
if browser_name == 'edge':
driver_file = 'msedgedriver.exe'
# 通过requests下载文件
save_path = f"{file_path}{os.sep}{url.split('/')[-1]}"
response = requests.get(url, stream=True)
response.raise_for_status()
with open(save_path, "wb") as file:
for chunk in response.iter_content(chunk_size=16384):
file.write(chunk)
# 如果原来存在驱动文件,则先删除原有的驱动文件
if os.path.exists(f"{file_path}{os.sep}{driver_file}"):
os.remove(f"{file_path}{os.sep}{driver_file}")
# 解压下载的压缩文件,并将驱动文件复制到filepath下
with zipfile.ZipFile(save_path, 'r') as zip_file:
file_list = zip_file.namelist()
for file in file_list:
if file.endswith(driver_file):
zip_file.extract(file, path=file_path)
if '/' in file:
shutil.copy(f"{file_path}{os.sep}{file}", f"{file_path}{os.sep}{driver_file}")
shutil.rmtree(f"{file_path}{os.sep}{file.split('/')[0]}") # 删除解压后的文件夹
break
os.remove(save_path) # 删除下载的压缩文件
def update_driver(driver_path, browser_name, browser_exe_file):
"""更新驱动文件为当前浏览器版本对应的驱动
driver_path 为保存驱动文件的路径
browser_name 为浏览器的名称
browser_exe_file 为浏览器安装路径下的.exe文件的完整文件名
"""
browser_version = get_version_by_path(browser_exe_file)
download_url = get_download_url(browser_version, browser_name)
download_driver(download_url, driver_path, browser_name)
if __name__ == '__main__':
driver_path = './'
browser_name = 'chrome'
browser_exe = "C:/Program Files/Google/Chrome/Application/chrome.exe"
update_driver(driver_path, browser_name, browser_exe)