How to work with a specific version of ChromeDriver while Chrome Browser gets updated automatically through Python selenium

Question:

I’m new comer of Selenium, and I can use selenium with Chromedriver to do basic auto-test now, the code works fine, but the problem is Chrome browser always update automatically at the backend, and code always fail to run after Chrome update. I know I need to download new chromedriver to solve this issue, but I wonder if there’s any way to solve this issue without disabling chromebrowser update? tks.

I’m using Windows 10 / Chrome Version 67 / Python 3.6.4 / Selenium 3.12.0

Asked By: Hong

||

Answers:

No, there is no other alternative than updating the ChromeDriver binary versions, while the Chrome Browser keeps on getting updated automatically.


Reason

Each Chrome Browser is released after certain feature additions, modifications and removals from the existing features. To comply with the current set of Browser Features, Chrome Team releases the compatible ChromeDriver binary time to time. These ChromeDriver binaries are capable to interact with the Chrome Browser. Certain version of a ChromeDriver binary supports a specific range of Chrome Browser versions (some of the recent) as below:

  • ChromeDriver v84.0.4147.30 (2020-05-28)

    Supports Chrome version 84
    
  • ChromeDriver v83.0.4103.39 (2020-05-05)

    Supports Chrome version 83
    
  • ChromeDriver v82 was intensionally skipped.

  • ChromeDriver v81.0.4044.138 (2020-05-05)

    Supports Chrome version 81
    
  • ChromeDriver v80.0.3987.106 (2020-02-13)

    Supports Chrome version 80
    
  • ChromeDriver v79.0.3945.36 (2019-11-18)

    Supports Chrome version 79
    
  • ChromeDriver v78.0.3904.70 (2019-10-21)

    Supports Chrome version 78
    
  • ChromeDriver v77.0.3865.40 (2019-08-20)

    Supports Chrome version 77
    
  • ChromeDriver v76.0.3809.126 (2019-08-20)

    Supports Chrome version 76
    
  • ChromeDriver v75.0.3770.8 (2019-04-29)

    Supports Chrome version 75
    
  • ChromeDriver v74.0.3729.6 (2019-03-14)

    Supports Chrome version 74
    
  • ChromeDriver v73.0.3683.68 (2019-03-06)

    Supports Chrome version 73
    
  • ChromeDriver v2.46 (2019-02-01)

    Supports Chrome v71-73
    
  • ChromeDriver v2.45 (2018-12-10)

    Supports Chrome v70-72
    
  • ChromeDriver v2.44 (2018-11-19)

    Supports Chrome v69-71
    
  • ChromeDriver v2.43 (2018-10-16)

    Supports Chrome v69-71
    
  • ChromeDriver v2.42 (2018-09-13)

    Supports Chrome v68-70
    
  • ChromeDriver v2.41 (2018-07-27)

    Supports Chrome v67-69
    
  • ChromeDriver v2.40 (2018-06-07)

    Supports Chrome v66-68
    
  • ChromeDriver v2.39 (2018-05-30)

    Supports Chrome v66-68
    
  • ChromeDriver v2.38 (2018-04-17)

    Supports Chrome v65-67
    
  • ChromeDriver v2.37 (2018-03-16)

    Supports Chrome v64-66
    
  • ChromeDriver v2.36 (2018-03-02)

    Supports Chrome v63-65
    
  • ChromeDriver v2.35 (2018-01-10)

    Supports Chrome v62-64
    
  • ChromeDriver v2.34 (2017-12-10)

    Supports Chrome v61-63
    
  • ChromeDriver v2.33 (2017-10-03)

    Supports Chrome v60-62
    
  • ChromeDriver v2.32 (2017-08-30)

    Supports Chrome v59-61
    
  • ChromeDriver v2.31 (2017-07-21)

    Supports Chrome v58-60
    
  • ChromeDriver v2.30 (2017-06-07)

    Supports Chrome v58-60
    
  • ChromeDriver v2.29 (2017-04-04)

    Supports Chrome v56-58
    

Conclusion

To keep your script/program interactive with the updated Chrome Browser you have to keep the version of ChromeDriver binary in sync with the Chrome Browser as per the compatibility.

Answered By: undetected Selenium

This is what I have built (also used some prewritten code from another stackoverflow thread), it could work for you. I set my scripts each time to run from a global Driver script to ensure it uses the proper ChromeDriver.exe file.

But you need to first make sure you are installing the new driver prior to running into this issue, these scripts will automatically download the newest version / look for the newest version of ChromeDriver and download it to a new file folder location. It will only use the new file folders location once your version of Chrome has been updated. The script should fail gracefully if the browser version of chrome updates and there is not an available version on chromedriver.storage.googleapis.com.

I set four scripts in my os path so I can access my driver globally. Below are the scripts I use to update my browser.

Hope this makes sense.

Cheers!
Matt

— getFileProperties.py —

# as per https://stackoverflow.com/questions/580924/python-windows-file-version-attribute

import win32api

#==============================================================================
def getFileProperties(fname):
#==============================================================================
    """
    Read all properties of the given file return them as a dictionary.
    """
    propNames = ('Comments', 'InternalName', 'ProductName',
        'CompanyName', 'LegalCopyright', 'ProductVersion',
        'FileDescription', 'LegalTrademarks', 'PrivateBuild',
        'FileVersion', 'OriginalFilename', 'SpecialBuild')

    props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}

    try:
        # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
        fixedInfo = win32api.GetFileVersionInfo(fname, '\')
        props['FixedFileInfo'] = fixedInfo
        props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
                fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS'] / 65536,
                fixedInfo['FileVersionLS'] % 65536)

        # VarFileInfoTranslation returns list of available (language, codepage)
        # pairs that can be used to retreive string info. We are using only the first pair.
        lang, codepage = win32api.GetFileVersionInfo(fname, '\VarFileInfo\Translation')[0]

        # any other must be of the form StringfileInfo%04X%04Xparm_name, middle
        # two are language/codepage pair returned from above

        strInfo = {}
        for propName in propNames:
            strInfoPath = u'\StringFileInfo\%04X%04X\%s' % (lang, codepage, propName)
            ## print str_info
            strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)

        props['StringFileInfo'] = strInfo
    except:
        pass

    return props

— ChromeVersion.py —

from getFileProperties import *

chrome_browser = #'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' -- ENTER YOUR Chrome.exe filepath


cb_dictionary = getFileProperties(chrome_browser) # returns whole string of version (ie. 76.0.111)

chrome_browser_version = cb_dictionary['FileVersion'][:2] # substring version to capabable version (ie. 77 / 76)


nextVersion = str(int(chrome_browser_version) +1) # grabs the next version of the chrome browser

lastVersion = str(int(chrome_browser_version) -1) # grabs the last version of the chrome browser

— ChromeDriverAutomation.py —

from ChromeVersion import chrome_browser_version, nextVersion, lastVersion


driverName = "\chromedriver.exe"

# defining base file directory of chrome drivers
driver_loc = #"C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\ChromeDriver\" -- ENTER the file path of your exe
# -- I created a separate folder to house the versions of chromedriver, previous versions will be deleted after downloading the newest version.
# ie. version 75 will be deleted after 77 has been downloaded.

# defining the file path of your exe file automatically updating based on your browsers current version of chrome.
currentPath = driver_loc + chrome_browser_version + driverName 
# check file directories to see if chrome drivers exist in nextVersion


import os.path

# check if new version of drive exists --> only continue if it doesn't
Newpath = driver_loc + nextVersion

# check if we have already downloaded the newest version of the browser, ie if we have version 76, and have already downloaded a version of 77, we don't need to run any more of the script.
newfileloc = Newpath + driverName
exists = os.path.exists(newfileloc)


if (exists == False):

    #open chrome driver and attempt to download new chrome driver exe file.

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.chrome.options import Options
    import time
    chrome_options = Options()
    executable_path = currentPath
    driver = webdriver.Chrome(executable_path=executable_path, options=chrome_options)

    # opening up url of chromedriver to get new version of chromedriver.
    chromeDriverURL = 'https://chromedriver.storage.googleapis.com/index.html?path=' + nextVersion 

    driver.get(chromeDriverURL)

    time.sleep(5)
    # find records of table rows
    table = driver.find_elements_by_css_selector('tr')


    # check the length of the table
    Table_len = len(table)

    # ensure that table length is greater than 4, else fail. -- table length of 4 is default when there are no availble updates
    if (Table_len > 4 ):

        # define string value of link
        rowText = table[(len(table)-2)].text[:6]
        time.sleep(1)
        # select the value of the row
        driver.find_element_by_xpath('//*[contains(text(),' + '"' + str(rowText) + '"'+')]').click()
        time.sleep(1)
        #select chromedriver zip for windows 
        driver.find_element_by_xpath('//*[contains(text(),' + '"' + "win32" + '"'+')]').click()

        time.sleep(3)
        driver.quit()

        from zipfile import ZipFile
        import shutil


        fileName = #r"C:UsersAdministratorDownloadschromedriver_win32.zip" --> enter your download path here.




        # Create a ZipFile Object and load sample.zip in it
        with ZipFile(fileName, 'r') as zipObj:
           # Extract all the contents of zip file in different directory
           zipObj.extractall(Newpath)


        # delete downloaded file
        os.remove(fileName)



        # defining old chrome driver location
        oldPath = driver_loc + lastVersion
        oldpathexists = os.path.exists(oldPath)

        # this deletes the old folder with the older version of chromedriver in it (version 75, once 77 has been downloaded)
        if(oldpathexists == True):
            shutil.rmtree(oldPath, ignore_errors=True)



exit()

https://github.com/MattWaller/ChromeDriverAutoUpdate

Answered By: Waller511

For Ubuntu/Linux:

Just use this to update to the latest: https://stackoverflow.com/a/57306360/4240654

version=$(curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
wget -qP "/tmp/" "https://chromedriver.storage.googleapis.com/${version}/chromedriver_linux64.zip"
sudo unzip -o /tmp/chromedriver_linux64.zip -d /usr/bin

And then this if you need to update Chrome: https://superuser.com/questions/130260/how-to-update-google-chrome-in-ubuntu

sudo apt-get --only-upgrade install google-chrome-stable
Answered By: alchemy

Yes you can.

The question: “How to work with a specific version of ChromeDriver while Chrome Browser gets updated automatically through Python selenium”

Like you rightfully pointed out the Chrome Browser updates automatically. If the ChromeDriver is a static file on your computer for one specific version of the Chrome Browser, it means that you will have to download a new ChromeDriver every time the Browser updates.

Luckily there is a way to update the ChromeDriver automatically too!

You can automatically use the correct chromedriver by using the webdrive-manager.

Install the webdrive-manager:

pip install webdriver-manager

Then use the driver in python as follows

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
Answered By: dylanvanw

you can use below shell script to make sure you download the correct version of the chrome driver. You can do something similar to this in python to make it work but you get a idea of how to proceed towards a solution for this problem.

%sh
#downloading compatible chrome driver version
#getting the current chrome browser version
**chromeVersion=$(google-chrome --product-version)**
#getting the major version value from the full version
**chromeMajorVersion=${chromeVersion%%.*}**
# setting the base url for getting the release url for the chrome driver
**baseDriverLatestReleaseURL=https://chromedriver.storage.googleapis.com/LATEST_RELEASE_**
#creating the latest release driver url based on the major version of the chrome
**latestDriverReleaseURL=$baseDriverLatestReleaseURL$chromeMajorVersion**
**echo $latestDriverReleaseURL**
#file name of the file that gets downloaded which would contain the full version of the chrome driver to download
**latestDriverVersionFileName="LATEST_RELEASE_"$chromeMajorVersion**
#downloading the file that would contain the full release version compatible with the major release of the chrome browser version
**wget $latestDriverReleaseURL** 
#reading the file to get the version of the chrome driver that we should download
**latestFullDriverVersion=$(cat $latestDriverVersionFileName)**
**echo $latestFullDriverVersion**
#creating the final URL by passing the compatible version of the chrome driver that we should download
**finalURL="https://chromedriver.storage.googleapis.com/"$latestFullDriverVersion"/chromedriver_linux64.zip"**
**echo $finalURL**
**wget $finalURL**

I was able to get the compatible version of chrome browser and chrome driver using the above approach when running scheduled job on the databricks environment and it worked like a charm without any issues.

Hope it helps others in one way or other.

Answered By: Nikunj Kakadiya

i am using this one library that is working for me .

https://pypi.org/project/chromedriver-autoinstaller/

Project description

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

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

edit. i also use the options like it was commented by @ATJ but for defining chrome’s binary_location() the not the CHROMEDRIVER_PATH.
actually, one of the things that i like in this extension is not having the need to specify this path, because it already takes care of that. before using it i used to loose time puting the path, searching where it was, puting copies of the driver in the projects folders or system path folders.

I also made a template with this quick code to use selenium, i open new files with that and then continue
that is it:


import chromedriver_autoinstaller
from selenium import webdriver
chromedriver_autoinstaller.install()
options = webdriver.ChromeOptions()
options.binary_location = ('C:\Program Files\Google\Chrome\Application\chrome.exe')
driver = webdriver.Chrome(options=options)


and also this quick script to run on terminal on 1st time using in a new pc


import os
os.system("pip install  selenium ")
os.system("pip install  chromedriver_autoinstaller ")

-the actual complete version of mine template(leaving comment is faster and reduce duplicate work, uncommenting makes it more dependence-less)


import chromedriver_autoinstaller
from selenium import webdriver
#from selenium.webdriver.common.keys import Keys
# import os
#    # to use when 1st time on the machine and then leave comented
# os.system("pip install  selenium ")
# os.system("pip install  chromedriver_autoinstaller ")
chromedriver_autoinstaller.install()
options = webdriver.ChromeOptions()
options.headless = False
options.binary_location = ('C:\Program Files\Google\Chrome\Application\chrome.exe')
driver = webdriver.Chrome(options=options)

edit. 2 -the actual complete version of mine template with binary loc.
well . i just tested the code with the binary_location and it works too. well, dont know wy it was not working before, this locations is the default so, should not change unless the person changed when installing chrome. good thing to revisit it now, i just saved a line from all my future uses of this.


import chromedriver_autoinstaller
from selenium import webdriver
#from selenium.webdriver.common.keys import Keys
# import os
#    # to use when 1st time on the machine and then leave comented
# os.system("pip install  selenium ")
# os.system("pip install  chromedriver_autoinstaller ")
chromedriver_autoinstaller.install()
options = webdriver.ChromeOptions()
options.headless = False
driver = webdriver.Chrome(options=options)
Answered By: bigubr

Maybe this will help you.
I managed to use ChromeDriver version 96.0.4664.45 editing in JUPYTER, I was using Pycharm before and it didn’t respond.

Answered By: KingStonne's

For me this resolve the issue:

pip install --upgrade --force-reinstall chromedriver-binary-auto
Answered By: Raj
ChromeDriverManager(version="xxx").install()
Answered By: Demon King