如何在Python的selenium中自动更新Chrome浏览器的情况下使用特定版本的ChromeDriver?

14
我是Selenium的新手,现在可以使用Chromedriver进行基本的自动化测试,代码运行良好,但问题是Chrome浏览器总是在后台自动更新,导致代码在Chrome更新后无法运行。我知道我需要下载新的Chromedriver来解决这个问题,但我想知道是否有办法在不禁用Chrome浏览器更新的情况下解决这个问题?谢谢。
我正在使用Windows 10 / Chrome版本67 / Python 3.6.4 / Selenium 3.12.0。

也许你可以禁用 Chrome 的自动更新? - Wiggy A.
是的,我知道我可以禁用Chrome的自动更新来解决这个问题,但有时我需要将此脚本发送给不知道如何禁用Chrome自动更新的人,所以我想知道是否有一种解决方案,而不必禁用自动更新。谢谢。 - Hong
下载最新的 Chrome 驱动程序。 - bhupathi turaga
是的,但我需要一遍又一遍地下载驱动程序...因为Chrome更新非常频繁。在代码中指定Chrome版本是否可能? - Hong
如果您使用Ubuntu,请使用以下链接:https://dev59.com/OlYM5IYBdhLWcg3wlQ7I - alchemy
8个回答

9

,更新ChromeDriver的二进制版本是唯一的选择,因为Chrome浏览器会自动更新。


原因

每个Chrome浏览器在某些功能添加、修改和删除后发布。为了符合当前的浏览器特性Chrome团队会定期发布兼容的ChromeDriver二进制文件。这些ChromeDriver二进制文件能够与Chrome浏览器进行交互。以下是某些版本ChromeDriver二进制文件支持的特定范围Chrome浏览器版本(近期的部分):

  • 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
    

结论

为了保持您的脚本/程序与更新的Chrome浏览器交互,您必须根据兼容性将ChromeDriver二进制版本与Chrome浏览器同步。


3
有没有使用ChromeDriver的替代方案?这种不断更新的情况会给我的一些客户带来麻烦。 - Daniel Williams

9

我正在使用一个对我有效的库。

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

项目描述

chromedriver-autoinstaller 自动下载并安装支持当前已安装版本的chrome浏览器驱动程序。该安装程序支持Linux、MacOS和Windows操作系统。

安装

pip install chromedriver-autoinstaller

例子

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

编辑。我也像@ATJ所评论的那样使用选项,但是用于定义Chrome的binary_location()而不是CHROMEDRIVER_PATH。 事实上,我喜欢这个扩展中的一件事情是不需要指定路径,因为它已经照顾好了。在使用它之前,我曾经浪费时间去放路径,搜索它的位置,在项目文件夹或系统路径文件夹中放驱动程序的副本。

我还使用这个快速代码创建了一个模板来使用Selenium,我使用它打开新文件,然后继续。 就是这样:


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)


还有这个快速脚本,在新电脑上第一次使用时可以在终端上运行。


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

-我的模板的实际完整版本(留下注释可以更快地减少重复工作,取消注释可以使其更少依赖)



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)

编辑2 - 我的模板实际完整版本(带二进制文件位置)。 我刚刚测试了此代码与二进制文件位置一起使用也可以正常工作。不知道为什么以前不起作用,这个位置是默认设置,除非用户在安装 Chrome 时更改了它。现在重新访问它是好事,因为我刚刚省去了所有将来使用它时的一行代码。


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)

1
这对我有用[在Mac上使用Python和Chrome]。我确实不得不对我的代码进行额外的更改,即我明确指定了驱动程序的路径[如driver = webdriver.Chrome(executable_path = CHROMEDRIVER_PATH,options = chrome_options)],但必须删除显式提及才能使其正常工作。 (因此,我的代码现在是[driver = webdriver.Chrome(options = chrome_options)]) - ATJ
@ATJ,这应该不是必要的,看一下扩展名是否已经执行了这个操作“# then add chromedriver to path”,如果没有执行,可能它没有正常工作。您可以在 GitHub 项目中打开一个问题 https://github.com/yeongbin-jo/python-chromedriver-autoinstaller/issues?q=is%3Aopen+is%3Aissue - bigubr

3

对于Ubuntu/Linux操作系统:

只需使用以下内容即可更新至最新版本:https://dev59.com/OlYM5IYBdhLWcg3wlQ7I#57306360

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

如果需要更新Chrome,请访问以下链接:https://superuser.com/questions/130260/how-to-update-google-chrome-in-ubuntu

sudo apt-get --only-upgrade install google-chrome-stable

1
对我来说,这解决了问题:
pip install --upgrade --force-reinstall chromedriver-binary-auto

1

可以的。

问题是:“如何在 Python selenium 中使用特定版本的 ChromeDriver,而 Chrome 浏览器会自动更新”。

正如你所指出的那样,Chrome 浏览器会自动更新。如果 ChromeDriver 是计算机上一个特定版本 Chrome 浏览器的静态文件,这意味着每次浏览器更新时都需要下载新的 ChromeDriver。

幸运的是,也有一种方法可以自动更新 ChromeDriver!

你可以使用 webdrive-manager 自动使用正确的 chromedriver。

安装 webdrive-manager:

pip install webdriver-manager

然后在Python中使用驱动程序如下:
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())

1

您可以使用以下shell脚本确保下载正确的Chrome驱动程序版本。您可以在Python中执行类似的操作使其工作,但您可以了解如何朝着解决此问题的方向前进。

%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**

当在Databricks环境中运行定期作业时,我能够使用上述方法获取兼容版本的Chrome浏览器和Chrome驱动程序,并且它完美地运行而没有任何问题。 希望这对他人有所帮助。

0

这是我的构建(还使用来自另一个stackoverflow线程的一些预写代码),它可能适用于您。我每次都将我的脚本设置为从全局驱动程序脚本运行,以确保它使用正确的ChromeDriver.exe文件。

但是,您需要首先确保在遇到此问题之前安装了新驱动程序,这些脚本将自动下载最新版本/查找最新版本的ChromeDriver并将其下载到新的文件夹位置。仅在Chrome版本已更新后才会使用新的文件夹位置。如果浏览器版本的chrome更新,chromedriver.storage.googleapis.com上没有可用版本,则脚本应该优雅地失败。

我在我的os路径中设置了四个脚本,以便我可以全局访问我的驱动程序。以下是我用于更新浏览器的脚本。

希望这有意义。

干杯! Matt

-- getFileProperties.py --

# as per https://dev59.com/Z3RB5IYBdhLWcg3wl4EP

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)

        # \VarFileInfo\Translation 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%04X\parm_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:\Users\Administrator\Downloads\chromedriver_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


0
也许这可以帮到你。 我成功地在JUPYTER中使用了ChromeDriver版本96.0.4664.45,之前我使用的是Pycharm,但它没有响应。

目前你的回答不够清晰,请[编辑]以添加更多细节,帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接