python selenium之chromedriver與chrome版本匹配問題(二) python selenium自動化之chrome與chromedriver版本兼容問題

  很多使用selenium的用戶都會遇到一個問題,我們的chromedriver經常與本地的chrome瀏覽器版本不兼容,導致我們實例化webdriver.Chrome失敗,錯誤信息大致如下:

發生異常: SessionNotCreatedException
 Message: session not created: This version of ChromeDriver only supports Chrome version 90 Current browser version is 95.0.4638.69 with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

  小爬在之前的文中(python selenium自動化之chrome與chromedriver版本兼容問題,封裝了方法來分別獲取chrome版本和chromedriver版本,當兩者版本的主版本號存在差異時,自動聯網在淘寶源倉庫:ChromeDriver Mirror (taobao.org)中下載對應的版本chromedriver,實現chromedriver基於需求的自動更新,使得兩者能長期匹配。

  實際上經過一番摸索,小爬發現有第三方的專業python庫webdriver_manager優雅地解決了這一問題,且其後臺更新chromedriver使用的是谷歌官方的chromedriver倉庫。該URL(http://chromedriver.storage.googleapis.com/index.html)在國內是可以正常訪問的,相對於淘寶源倉庫最大的優勢是,它永遠存有chrome最新版的chromedriver,倉庫更新的頻率更快,如下圖所示:

 

  實上,webdriver-manager庫(通過pip install webdriver-manager安裝即可)也可以用來更新EdgeChromiumDriver、GeckoDriver、IEDriver、OperaDriver文件,具體如何操作呢,其實我們執行時就兩三行代碼:

driver_path=ChromeDriverManager().install() 
driver = webdriver.Chrome(executable_path=driver_path)
  當然,我們如果多具備些探究竟精神,不妨看下其源碼,瞭解其精髓。其中ChromeDriverManager類的源碼如下:
class ChromeDriverManager(DriverManager):
    def __init__(self, version="latest",
                 os_type=utils.os_type(),
                 path=None,
                 name="chromedriver",
                 url="https://chromedriver.storage.googleapis.com",
                 latest_release_url="https://chromedriver.storage.googleapis.com/LATEST_RELEASE",
                 chrome_type=ChromeType.GOOGLE,
                 log_level=logging.INFO,
                 print_first_line=True,
                 cache_valid_range=1):
        super().__init__(path, log_level=log_level, print_first_line=print_first_line,
                         cache_valid_range=cache_valid_range)

        self.driver = ChromeDriver(name=name,
                                   version=version,
                                   os_type=os_type,
                                   url=url,
                                   latest_release_url=latest_release_url,
                                   chrome_type=chrome_type)

    def install(self):
        log(f"Current {self.driver.chrome_type} version is {self.driver.browser_version}", first_line=True)
        driver_path = self._get_driver_path(self.driver)

        os.chmod(driver_path, 0o755)
        return driver_path

chromedriver類的源碼如下:

class ChromeDriver(Driver):
    def __init__(self, name, version, os_type, url, latest_release_url,
                 chrome_type=ChromeType.GOOGLE):
        super(ChromeDriver, self).__init__(name, version, os_type, url,
                                           latest_release_url)
        self.chrome_type = chrome_type
        self.browser_version = get_browser_version_from_os(chrome_type)

    def get_os_type(self):
        if "win" in super().get_os_type():
            return "win32"
        return super().get_os_type()

    def get_latest_release_version(self):
        log(f"Get LATEST driver version for {self.browser_version}")
        resp = requests.get(f"{self._latest_release_url}_{self.browser_version}")
        validate_response(resp)
        return resp.text.rstrip()

該方法會默認調用DriverCache類的find_driver方法:

    def find_driver(self, browser_version, driver_name, os_type, driver_version):
        metadata = self.get_metadata()

        key = f"{os_type}_{driver_name}_{driver_version}_for_{browser_version}"
        if key not in metadata:
            log(f"There is no [{os_type}] {driver_name} for browser {browser_version} in cache")
            return None

        driver_info = metadata[key]

        if not self.__is_valid(driver_info):
            return None

        path = driver_info['binary_path']
        log(f"Driver [{path}] found in cache")
        return path

如果系統能在特定路徑下找到對應版本的driver,則可以直接調用,否則調用get_latest_release_version方法來聯網獲取最新的driver,並放在對應的系統路徑下,比如我電腦上chromedriver最新版統一存儲在下圖所示路徑下,供參考:

 

 

 

 

   因電腦端chrome瀏覽器自動升級策略,導致本地的chromedriver總是不能及時兼容。有這類問題的你,還不趕緊動手試下?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章