selenium自動化之chrome與chromedriver版本兼容問題

  大家都知道,我們藉助python+selenium來驅動chrome等瀏覽器時,需要有chromedriver的支持。近來,chrome瀏覽器的主版本號基本保持每月一更新的頻次。當我們的chromedriver版本如果落後chrome主版本超過1,則chromedriver會提示版本不兼容,大概顯示信息如下:“selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 80”。

  解決此問題有兩個方法,先來說說治標的方法:早期的chromedriver並不嚴格校驗chrome瀏覽器的版本,而且面對最新的chrome,它依然夠用,畢竟大多數時候我們常用的chrome的api功能都沒變過。所以,我們可以使用舊版本chromedriver來規避這個問題,比如ChromeDriver 2.35.528161就不存在這個問題;

  接下來小爬重點說說相對治本的方法:我們在腳本中分別獲取chromedriver和chrome的版本號,比較其主版本號的差異,觸發條件後,自動在chromedriver mirror上下載與chrome相對應版本的chromedriver,解壓,替換原chrome driver文件,一氣呵成。

  chrome的版本,我們一般通過瀏覽器地址欄輸入“chrome://settings/help”來查看:

 

也可以右鍵chrome.exe文件來查看版本號:

    

 

在python的世界裏,我們可以這樣去讀取一個文件(如chrome)的“屬性-詳細信息-產品版本信息”(需要提前安裝pywin32模塊),返回值是一個版本號的字符串:“87.0.4280.141”:

from win32com.client import Dispatch
allInfo=Dispatch("Scripting.FileSystemObject")
version = allInfo.GetFileVersion(r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")

我們也可以通過註冊表的方式來獲取chrome的版本號:

import winreg
def get_Chrome_version():
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon')
    version, types = winreg.QueryValueEx(key, 'version')
    return version

  接下來,我們在cmd或者powershell裏,CD到chromedriver所在目錄,可以這樣得到版本號:.\chromedriver.exe --V  ,返回結果大概這樣:“ChromeDriver 2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73)”,該字符串按照空格符進行分段,第二段就是我們要的版本信息了。那麼在python的世界裏,我們又該如何去跟終端交互拿到這個chromedriver版本號呢,其實很簡單:

import os
def get_version():
    '''查詢系統內的Chromedriver版本'''
    outstd2 = os.popen('chromedriver --version').read()
    return outstd2.split(' ')[1]

有了這些手段,我們還需要定義個方法來自動下載”ChromeDriver Mirror (taobao.org)“上的chromedriver:

 

下載路徑(URL)諸如:“https://cdn.npm.taobao.org/dist/chromedriver/80.0.3987.16/chromedriver_win32.zip”,這用requests庫就可以輕鬆實現這一需求:

import requests
def download_driver(download_url):
    '''下載文件'''
    file = requests.get(download_url)
    with open("chromedriver.zip", 'wb') as zip_file:        # 保存文件到腳本所在目錄
        zip_file.write(file.content)
        print('下載成功')

你也可以指定完整路徑,讓下載的chromedriver.zip文件放到指定目錄。

緊接着,小爬再定義個方法來自動解壓zip文件,拿到裏面的chromedriver.exe文件,自動覆蓋舊版本chrome driver:

import zipfile
def unzip_driver(path):
    '''解壓Chromedriver壓縮包到指定目錄'''
    f = zipfile.ZipFile("chromedriver.zip",'r')
    for file in f.namelist():
        f.extract(file, path)

小爬將這些功能做成一個py文件,可以import到我們的任何其他相關項目中,完整的示例代碼如下:

import requests,winreg,zipfile,re,os
url='http://npm.taobao.org/mirrors/chromedriver/' # chromedriver download link
def get_Chrome_version(): key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon') version, types = winreg.QueryValueEx(key, 'version') return version def get_latest_version(url): '''查詢最新的Chromedriver版本''' rep = requests.get(url).text time_list = [] # 用來存放版本時間 time_version_dict = {} # 用來存放版本與時間對應關係 result = re.compile(r'\d.*?/</a>.*?Z').findall(rep) # 匹配文件夾(版本號)和時間 for i in result: time = i[-24:-1] # 提取時間 version = re.compile(r'.*?/').findall(i)[0] # 提取版本號 time_version_dict[time] = version # 構建時間和版本號的對應關係,形成字典 time_list.append(time) # 形成時間列表 latest_version = time_version_dict[max(time_list)][:-1] # 用最大(新)時間去字典中獲取最新的版本號 return latest_version
def get_server_chrome_versions(): '''return all versions list''' versionList=[] url="http://npm.taobao.org/mirrors/chromedriver/" rep = requests.get(url).text result = re.compile(r'\d.*?/</a>.*?Z').findall(rep) for i in result: # 提取時間 version = re.compile(r'.*?/').findall(i)[0] # 提取版本號 versionList.append(version[:-1]) # 將所有版本存入列表 return versionList def download_driver(download_url): '''下載文件''' file = requests.get(download_url) with open("chromedriver.zip", 'wb') as zip_file: # 保存文件到腳本所在目錄 zip_file.write(file.content) print('下載成功') def get_version(): '''查詢系統內的Chromedriver版本''' outstd2 = os.popen('chromedriver --version').read() return outstd2.split(' ')[1] def unzip_driver(path): '''解壓Chromedriver壓縮包到指定目錄''' f = zipfile.ZipFile("chromedriver.zip",'r') for file in f.namelist(): f.extract(file, path) def check_update_chromedriver(): chromeVersion=get_Chrome_version() chrome_main_version=int(chromeVersion.split(".")[0]) # chrome主版本號 driverVersion=get_version() driver_main_version=int(driverVersion.split(".")[0]) # chromedriver主版本號 download_url="" if driver_main_version!=chrome_main_version: print("chromedriver版本與chrome瀏覽器不兼容,更新中>>>") versionList=get_server_chrome_versions() if chromeVersion in versionList: download_url=f"{url}{chromeVersion}/chromedriver_win32.zip" else: for version in versionList: if version.startswith(str(chrome_main_version)): download_url=f"{url}{version}/chromedriver_win32.zip" break if download_url=="": print("暫無法找到與chrome兼容的chromedriver版本,請在http://npm.taobao.org/mirrors/chromedriver/ 覈實。") download_driver(download_url=download_url) path = get_path() unzip_driver(path) os.remove("chromedriver.zip") print('更新後的Chromedriver版本爲:', get_version()) else: print("chromedriver版本與chrome瀏覽器相兼容,無需更新chromedriver版本!") if __name__=="__main__": check_update_chromedriver()

 

 有了這套方法,任由你的本地chrome如何更新,我們的項目中的chromedriver總能自動更新,兼容瀏覽器的版本,可謂是一勞永逸了~~有這類困擾的童鞋,趕緊用上面的方法動手試試吧!

 

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