Automatic download of appropriate chromedriver for Selenium in Python
Question:
Unfortunately, Chromedriver always is version-specific to the Chrome version you have installed.
So when you pack your python code AND a chromedriver via PyInstaller in a deployable .exe-file for Windows, it will not work in most cases as you won’t be able to have all chromedriver versions in the .exe-file.
Anyone knows a way on how to download the correct chromedriver from the website automatically?
If not, I’ll come up with a code to download the zip-file and unpack it to temp.
Thanks!
Answers:
Webdriver Manager will do that for you. refer this link https://pypi.org/project/webdriver-manager/
Here is the other solution, where webdriver_manager
does not support. This script will get the latest chrome driver version downloaded.
import requests
import wget
import zipfile
import os
# get the latest chrome driver version number
url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE'
response = requests.get(url)
version_number = response.text
# build the donwload url
download_url = "https://chromedriver.storage.googleapis.com/" + version_number +"/chromedriver_win32.zip"
# download the zip file using the url built above
latest_driver_zip = wget.download(download_url,'chromedriver.zip')
# extract the zip file
with zipfile.ZipFile(latest_driver_zip, 'r') as zip_ref:
zip_ref.extractall() # you can specify the destination folder path here
# delete the zip file downloaded above
os.remove(latest_driver_zip)
Here is one more way
For Python –
import chromedriver_autoinstaller
from selenium import webdriver
opt = webdriver.ChromeOptions()
opt.add_argument("--start-maximized")
chromedriver_autoinstaller.install()
driver = webdriver.Chrome(options=opt)
driver.get('https://stackoverflow.com/')
here is more info
I have a slightly fancier version
It will detected what chrome version you have, grab the correct driver
def download_chromedriver():
def get_latestversion(version):
url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE_' + str(version)
response = requests.get(url)
version_number = response.text
return version_number
def download(download_url, driver_binaryname, target_name):
# download the zip file using the url built above
latest_driver_zip = wget.download(download_url, out='./temp/chromedriver.zip')
# extract the zip file
with zipfile.ZipFile(latest_driver_zip, 'r') as zip_ref:
zip_ref.extractall(path = './temp/') # you can specify the destination folder path here
# delete the zip file downloaded above
os.remove(latest_driver_zip)
os.rename(driver_binaryname, target_name)
os.chmod(target_name, 755)
if os.name == 'nt':
replies = os.popen(r'reg query "HKEY_CURRENT_USERSoftwareGoogleChromeBLBeacon" /v version').read()
replies = replies.split('n')
for reply in replies:
if 'version' in reply:
reply = reply.rstrip()
reply = reply.lstrip()
tokens = re.split(r"s+", reply)
fullversion = tokens[len(tokens) - 1]
tokens = fullversion.split('.')
version = tokens[0]
break
target_name = './bin/chromedriver-win-' + version + '.exe'
found = os.path.exists(target_name)
if not found:
version_number = get_latestversion(version)
# build the donwload url
download_url = "https://chromedriver.storage.googleapis.com/" + version_number +"/chromedriver_win32.zip"
download(download_url, './temp/chromedriver.exe', target_name)
elif os.name == 'posix':
reply = os.popen(r'chromium --version').read()
if reply != '':
reply = reply.rstrip()
reply = reply.lstrip()
tokens = re.split(r"s+", reply)
fullversion = tokens[1]
tokens = fullversion.split('.')
version = tokens[0]
else:
reply = os.popen(r'google-chrome --version').read()
reply = reply.rstrip()
reply = reply.lstrip()
tokens = re.split(r"s+", reply)
fullversion = tokens[2]
tokens = fullversion.split('.')
version = tokens[0]
target_name = './bin/chromedriver-linux-' + version
print('new chrome driver at ' + target_name)
found = os.path.exists(target_name)
if not found:
version_number = get_latestversion(version)
download_url = "https://chromedriver.storage.googleapis.com/" + version_number +"/chromedriver_linux64.zip"
download(download_url, './temp/chromedriver', target_name)
As of Aug-2021, this is the status :-
chromedriver-autoinstaller
Automatically download and install chromedriver that supports the
currently installed version of chrome. This installer supports Linux,
MacOS and Windows operating systems.
Installation
pip install chromedriver-autoinstaller
Usage
Just type import chromedriver_autoinstaller in the module you want to use chromedriver.
Example
from selenium import webdriver
import chromedriver_autoinstaller
chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists
# and if it doesn't exist, download it automatically,
# then add chromedriver to path
driver = webdriver.Chrome()
driver.get("http://www.python.org")
assert "Python" in driver.title
Reference link here
You could use this solution. It will do two things:
- Check locally in your computer for the driver version and compare it with the latest version available online.
- The latest online version will be downloaded if it does not match your local version.
from selenium import webdriver
import requests
import zipfile
import wget
import subprocess
import os
CHROMEDRIVER_PATH = # Insert your Chromedriver path here
CHROMEDRIVER_FOLDER = os.path.dirname(CHROMEDRIVER_PATH)
LATEST_DRIVER_URL = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"
def download_latest_version(version_number):
print("Attempting to download latest driver online......")
download_url = "https://chromedriver.storage.googleapis.com/" + version_number + "/chromedriver_win32.zip"
# download zip file
latest_driver_zip = wget.download(download_url, out=CHROMEDRIVER_FOLDER)
# read & extract the zip file
with zipfile.ZipFile(latest_driver_zip, 'r') as downloaded_zip:
# You can chose the folder path to extract to below:
downloaded_zip.extractall(path=CHROMEDRIVER_FOLDER)
# delete the zip file downloaded above
os.remove(latest_driver_zip)
def check_driver():
# run cmd line to check for existing web-driver version locally
cmd_run = subprocess.run("chromedriver --version",
capture_output=True,
text=True)
# Extract driver version as string from terminal output
local_driver_version = cmd_run.stdout.split()[1]
print(f"Local driver version: {local_driver_version}")
# check for latest chromedriver version online
response = requests.get(LATEST_DRIVER_URL)
online_driver_version = response.text
print(f"Latest online chromedriver version: {online_driver_version}")
if local_driver_version == online_driver_version:
return True
else:
download_latest_version(online_driver_version)
This solution uses default python libraries and will download the closest matching version from internet depending on your current locally installed version of Chrome. My linux laptop has Google Chrome version 97.0.4692.99 loaded, however the closest version from the drivers link was 97.0.4692.71. If needed also, you can change the value of the parameter latest in chrome_driver_url
to force download the latest chrome version.
import os
import ssl, shutil, re, platform
import zipfile
from urllib.request import urlopen
from pathlib import Path
import difflib
def chrome_driver_url(latest=False):
def current_chrome_version():
CHROME_RELEASE_URL = "https://sites.google.com/chromium.org/driver/downloads?authuser=0"
try:
response = urlopen(CHROME_RELEASE_URL,context=ssl.SSLContext(ssl.PROTOCOL_TLS)).read()
except ssl.SSLError:
response = urlopen(CHROME_RELEASE_URL,).read()
downloading_version = re.findall(b"ChromeDriver d{2,3}.0.d{4}.d+", response)
downloading_version = [x.decode().split(" ")[1] for x in downloading_version]
downloading_version.sort(key=lambda x: [int(i) if i.isdigit() else i for i in x.split('.')])
downloading_version.reverse()
osname = platform.system()
if osname == 'Darwin':
installpath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
verstr = os.popen(f"{installpath} --version").read().strip('Google Chrome ').strip()
ver_to_download = difflib.get_close_matches(verstr, downloading_version)
ver_to_download = ver_to_download[0]
return ver_to_download
elif osname == 'Windows':
verstr = os.popen('reg query "HKEY_CURRENT_USERSoftwareGoogleChromeBLBeacon" /v version').read().strip().split(" ")
verstr = verstr[-1]
ver_to_download = difflib.get_close_matches(verstr, downloading_version)
ver_to_download = ver_to_download[0]
return ver_to_download
elif osname == 'Linux':
installpath = "/usr/bin/google-chrome"
verstr = os.popen(f"{installpath} --version").read().strip('Google Chrome ').strip()
ver_to_download = difflib.get_close_matches(verstr, downloading_version)
ver_to_download = ver_to_download[0]
return ver_to_download
else:
raise NotImplemented(f"Unknown OS '{osname}'")
if latest:
CHROME_RELEASE_URL = "https://sites.google.com/chromium.org/driver/downloads?authuser=0"
try:
response = urlopen(CHROME_RELEASE_URL, context=ssl.SSLContext(ssl.PROTOCOL_TLS)).read()
except ssl.SSLError:
response = urlopen(CHROME_RELEASE_URL).read()
downloading_version = re.findall(b"ChromeDriver d{2,3}.0.d{4}.d+", response)[0].decode().split()[1]
else:
downloading_version = current_chrome_version()
system = platform.system()
if system == "Windows":
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_win32.zip"
elif system == "Darwin":
# M1
if platform.processor() == 'arm':
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_mac64_m1.zip"
else:
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_mac64.zip"
elif system == "Linux":
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_linux64.zip"
return url
def download_chrome_driver(drivers_dir):
driver_name = "chromedriver.exe" if platform.system() == "Windows" else "chromedriver"
if (drivers_dir / driver_name).exists():
return
url = chrome_driver_url()
try:
response = urlopen(url, context=ssl.SSLContext(ssl.PROTOCOL_TLS))
except ssl.SSLError:
response = urlopen(url)
zip_file_path = drivers_dir / Path(url).name
with open(zip_file_path, 'wb') as zip_file:
while True:
chunk = response.read(1024)
if not chunk:
break
zip_file.write(chunk)
extracted_dir = drivers_dir / zip_file_path.stem
with zipfile.ZipFile(zip_file_path, "r") as zip_file:
zip_file.extractall(extracted_dir)
os.remove(zip_file_path)
driver_path = drivers_dir / driver_name
try:
(extracted_dir / driver_name).rename(driver_path)
except FileExistsError:
(extracted_dir / driver_name).replace(driver_path)
shutil.rmtree(extracted_dir)
os.chmod(driver_path, 0o755)
if __name__ == "__main__":
chrome_driver_location = Path("chrome_driver")
chrome_driver_location.mkdir(exist_ok=True)
download_chrome_driver(chrome_driver_location)
You can use this
import sys
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import ChromiumOptions
from webdriver_manager.chrome import ChromeDriverManager
chrome_options = ChromiumOptions()
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(chrome_options=chrome_options, service=service)
driver.get("http://www.python.org")
time.sleep(sys.maxsize)
driver.quit()
Unfortunately, Chromedriver always is version-specific to the Chrome version you have installed.
So when you pack your python code AND a chromedriver via PyInstaller in a deployable .exe-file for Windows, it will not work in most cases as you won’t be able to have all chromedriver versions in the .exe-file.
Anyone knows a way on how to download the correct chromedriver from the website automatically?
If not, I’ll come up with a code to download the zip-file and unpack it to temp.
Thanks!
Webdriver Manager will do that for you. refer this link https://pypi.org/project/webdriver-manager/
Here is the other solution, where webdriver_manager
does not support. This script will get the latest chrome driver version downloaded.
import requests
import wget
import zipfile
import os
# get the latest chrome driver version number
url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE'
response = requests.get(url)
version_number = response.text
# build the donwload url
download_url = "https://chromedriver.storage.googleapis.com/" + version_number +"/chromedriver_win32.zip"
# download the zip file using the url built above
latest_driver_zip = wget.download(download_url,'chromedriver.zip')
# extract the zip file
with zipfile.ZipFile(latest_driver_zip, 'r') as zip_ref:
zip_ref.extractall() # you can specify the destination folder path here
# delete the zip file downloaded above
os.remove(latest_driver_zip)
Here is one more way
For Python –
import chromedriver_autoinstaller
from selenium import webdriver
opt = webdriver.ChromeOptions()
opt.add_argument("--start-maximized")
chromedriver_autoinstaller.install()
driver = webdriver.Chrome(options=opt)
driver.get('https://stackoverflow.com/')
here is more info
I have a slightly fancier version
It will detected what chrome version you have, grab the correct driver
def download_chromedriver():
def get_latestversion(version):
url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE_' + str(version)
response = requests.get(url)
version_number = response.text
return version_number
def download(download_url, driver_binaryname, target_name):
# download the zip file using the url built above
latest_driver_zip = wget.download(download_url, out='./temp/chromedriver.zip')
# extract the zip file
with zipfile.ZipFile(latest_driver_zip, 'r') as zip_ref:
zip_ref.extractall(path = './temp/') # you can specify the destination folder path here
# delete the zip file downloaded above
os.remove(latest_driver_zip)
os.rename(driver_binaryname, target_name)
os.chmod(target_name, 755)
if os.name == 'nt':
replies = os.popen(r'reg query "HKEY_CURRENT_USERSoftwareGoogleChromeBLBeacon" /v version').read()
replies = replies.split('n')
for reply in replies:
if 'version' in reply:
reply = reply.rstrip()
reply = reply.lstrip()
tokens = re.split(r"s+", reply)
fullversion = tokens[len(tokens) - 1]
tokens = fullversion.split('.')
version = tokens[0]
break
target_name = './bin/chromedriver-win-' + version + '.exe'
found = os.path.exists(target_name)
if not found:
version_number = get_latestversion(version)
# build the donwload url
download_url = "https://chromedriver.storage.googleapis.com/" + version_number +"/chromedriver_win32.zip"
download(download_url, './temp/chromedriver.exe', target_name)
elif os.name == 'posix':
reply = os.popen(r'chromium --version').read()
if reply != '':
reply = reply.rstrip()
reply = reply.lstrip()
tokens = re.split(r"s+", reply)
fullversion = tokens[1]
tokens = fullversion.split('.')
version = tokens[0]
else:
reply = os.popen(r'google-chrome --version').read()
reply = reply.rstrip()
reply = reply.lstrip()
tokens = re.split(r"s+", reply)
fullversion = tokens[2]
tokens = fullversion.split('.')
version = tokens[0]
target_name = './bin/chromedriver-linux-' + version
print('new chrome driver at ' + target_name)
found = os.path.exists(target_name)
if not found:
version_number = get_latestversion(version)
download_url = "https://chromedriver.storage.googleapis.com/" + version_number +"/chromedriver_linux64.zip"
download(download_url, './temp/chromedriver', target_name)
As of Aug-2021, this is the status :-
chromedriver-autoinstaller
Automatically download and install chromedriver that supports the
currently installed version of chrome. This installer supports Linux,
MacOS and Windows operating systems.
Installation
pip install chromedriver-autoinstaller
Usage
Just type import chromedriver_autoinstaller in the module you want to use chromedriver.
Example
from selenium import webdriver
import chromedriver_autoinstaller
chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists
# and if it doesn't exist, download it automatically,
# then add chromedriver to path
driver = webdriver.Chrome()
driver.get("http://www.python.org")
assert "Python" in driver.title
Reference link here
You could use this solution. It will do two things:
- Check locally in your computer for the driver version and compare it with the latest version available online.
- The latest online version will be downloaded if it does not match your local version.
from selenium import webdriver
import requests
import zipfile
import wget
import subprocess
import os
CHROMEDRIVER_PATH = # Insert your Chromedriver path here
CHROMEDRIVER_FOLDER = os.path.dirname(CHROMEDRIVER_PATH)
LATEST_DRIVER_URL = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"
def download_latest_version(version_number):
print("Attempting to download latest driver online......")
download_url = "https://chromedriver.storage.googleapis.com/" + version_number + "/chromedriver_win32.zip"
# download zip file
latest_driver_zip = wget.download(download_url, out=CHROMEDRIVER_FOLDER)
# read & extract the zip file
with zipfile.ZipFile(latest_driver_zip, 'r') as downloaded_zip:
# You can chose the folder path to extract to below:
downloaded_zip.extractall(path=CHROMEDRIVER_FOLDER)
# delete the zip file downloaded above
os.remove(latest_driver_zip)
def check_driver():
# run cmd line to check for existing web-driver version locally
cmd_run = subprocess.run("chromedriver --version",
capture_output=True,
text=True)
# Extract driver version as string from terminal output
local_driver_version = cmd_run.stdout.split()[1]
print(f"Local driver version: {local_driver_version}")
# check for latest chromedriver version online
response = requests.get(LATEST_DRIVER_URL)
online_driver_version = response.text
print(f"Latest online chromedriver version: {online_driver_version}")
if local_driver_version == online_driver_version:
return True
else:
download_latest_version(online_driver_version)
This solution uses default python libraries and will download the closest matching version from internet depending on your current locally installed version of Chrome. My linux laptop has Google Chrome version 97.0.4692.99 loaded, however the closest version from the drivers link was 97.0.4692.71. If needed also, you can change the value of the parameter latest in chrome_driver_url
to force download the latest chrome version.
import os
import ssl, shutil, re, platform
import zipfile
from urllib.request import urlopen
from pathlib import Path
import difflib
def chrome_driver_url(latest=False):
def current_chrome_version():
CHROME_RELEASE_URL = "https://sites.google.com/chromium.org/driver/downloads?authuser=0"
try:
response = urlopen(CHROME_RELEASE_URL,context=ssl.SSLContext(ssl.PROTOCOL_TLS)).read()
except ssl.SSLError:
response = urlopen(CHROME_RELEASE_URL,).read()
downloading_version = re.findall(b"ChromeDriver d{2,3}.0.d{4}.d+", response)
downloading_version = [x.decode().split(" ")[1] for x in downloading_version]
downloading_version.sort(key=lambda x: [int(i) if i.isdigit() else i for i in x.split('.')])
downloading_version.reverse()
osname = platform.system()
if osname == 'Darwin':
installpath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
verstr = os.popen(f"{installpath} --version").read().strip('Google Chrome ').strip()
ver_to_download = difflib.get_close_matches(verstr, downloading_version)
ver_to_download = ver_to_download[0]
return ver_to_download
elif osname == 'Windows':
verstr = os.popen('reg query "HKEY_CURRENT_USERSoftwareGoogleChromeBLBeacon" /v version').read().strip().split(" ")
verstr = verstr[-1]
ver_to_download = difflib.get_close_matches(verstr, downloading_version)
ver_to_download = ver_to_download[0]
return ver_to_download
elif osname == 'Linux':
installpath = "/usr/bin/google-chrome"
verstr = os.popen(f"{installpath} --version").read().strip('Google Chrome ').strip()
ver_to_download = difflib.get_close_matches(verstr, downloading_version)
ver_to_download = ver_to_download[0]
return ver_to_download
else:
raise NotImplemented(f"Unknown OS '{osname}'")
if latest:
CHROME_RELEASE_URL = "https://sites.google.com/chromium.org/driver/downloads?authuser=0"
try:
response = urlopen(CHROME_RELEASE_URL, context=ssl.SSLContext(ssl.PROTOCOL_TLS)).read()
except ssl.SSLError:
response = urlopen(CHROME_RELEASE_URL).read()
downloading_version = re.findall(b"ChromeDriver d{2,3}.0.d{4}.d+", response)[0].decode().split()[1]
else:
downloading_version = current_chrome_version()
system = platform.system()
if system == "Windows":
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_win32.zip"
elif system == "Darwin":
# M1
if platform.processor() == 'arm':
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_mac64_m1.zip"
else:
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_mac64.zip"
elif system == "Linux":
url = f"https://chromedriver.storage.googleapis.com/{downloading_version}/chromedriver_linux64.zip"
return url
def download_chrome_driver(drivers_dir):
driver_name = "chromedriver.exe" if platform.system() == "Windows" else "chromedriver"
if (drivers_dir / driver_name).exists():
return
url = chrome_driver_url()
try:
response = urlopen(url, context=ssl.SSLContext(ssl.PROTOCOL_TLS))
except ssl.SSLError:
response = urlopen(url)
zip_file_path = drivers_dir / Path(url).name
with open(zip_file_path, 'wb') as zip_file:
while True:
chunk = response.read(1024)
if not chunk:
break
zip_file.write(chunk)
extracted_dir = drivers_dir / zip_file_path.stem
with zipfile.ZipFile(zip_file_path, "r") as zip_file:
zip_file.extractall(extracted_dir)
os.remove(zip_file_path)
driver_path = drivers_dir / driver_name
try:
(extracted_dir / driver_name).rename(driver_path)
except FileExistsError:
(extracted_dir / driver_name).replace(driver_path)
shutil.rmtree(extracted_dir)
os.chmod(driver_path, 0o755)
if __name__ == "__main__":
chrome_driver_location = Path("chrome_driver")
chrome_driver_location.mkdir(exist_ok=True)
download_chrome_driver(chrome_driver_location)
You can use this
import sys
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import ChromiumOptions
from webdriver_manager.chrome import ChromeDriverManager
chrome_options = ChromiumOptions()
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(chrome_options=chrome_options, service=service)
driver.get("http://www.python.org")
time.sleep(sys.maxsize)
driver.quit()