獲取Chrome版本並下載匹配的chromedriver


問題背景

在selenium驅動的web自動化中,經常會碰Chrome和chromedriver版本不匹配的狀況;
本篇解決的是如何自動下載與本地Chrome版本相匹配的chromedriver。

更新日志

  1. 增加了對Chromium 和 MS Edge 的支持

  2. 支持Windows, Linux, Mac OS 平台

  3. 增加了對chromedriver官網來源的支持(國內還是用阿里吧)

  4. 修改了原方案中獲取瀏覽器版本號的方式

  5. 項目地址碼雲

大致方案(windows)

  1. 獲取本地Chrome版本號:從注冊表HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon\version中得到;

  2. 獲取本地chromedriver版本號:找到就返回版本號,未找到就返回 0;

  3. 比對版本號:Chrome Version 長這樣"79.0.3945.88",取前三位版本號比對,即“79.0.3945”;

  4. 若不一致:去淘寶鏡像下載匹配的chromedriver;

  5. 最終實現請直接移步到本篇末尾

細節如下(python3實現,最后會打包成 .exe程序,供雙擊運行)

  1. 獲取Chrome版本號

    import winreg  # 和注冊表交互
    import re  # 正則模塊
     
    version_re = re.compile(r'^[1-9]\d*\.\d*.\d*')  # 匹配前3位版本號的正則表達式
     
    def getChromeVersion():
        try:
        # 從注冊表中獲得版本號
            key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon')
    
            _v, type = winreg.QueryValueEx(key, 'version')
    
            print('Current Chrome Version: {}'.format(_v)) # 這步打印會在命令行窗口顯示
    
            return version_re.findall(_v)[0]  # 返回前3位版本號
    
        except WindowsError as e:
            print('check Chrome failed:{}'.format(e))
    
  2. 獲取chromedriver版本號

    • 方式(在chromedriver.exe的目錄下執行cmd命令)

      G:\py\prac\chromedriver.exe --version
      prac 79.0.3945.36 (3582db32b33893869b8c1339e8f4d9ed1816f143-refs/branch-heads/3945@{#614})
      
    • 代碼實現如下

      import subprocess  # 用於執行cmd命令
      
      def getDriverVersion(absPath):
         """
         @param absPath: chromedriver.exe的絕對路徑
         """
         cmd = r'{} --version'.format(absPath)  # 拼接成cmd命令
         
         try:
             # 執行cmd命令並接收命令回顯
             out, err = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
             out = out.decode('utf-8')
             	
             _v = out.split(' ')[1] # 拆分回顯字符串,獲取版本號
             print('Current chromedriver Version:{}'.format(_v))
      
             return version_re.findall(_v)[0]
         except IndexError as e:
             print('check chromedriver failed:{}'.format(e))
             return 0
      
  3. 建個配置文件吧,用來管理chromedriver的路徑(當然你也可以寫在代碼里,就不用本步操作了)

    • 配置文件存放路徑:與該程序同級

    • 內容如下:

      [driver]
      ; absolute path of chromedriver
      absPath=G:\py\prac\chromedriver.exe
      
      ; DO NOT modify the url
      url=http://npm.taobao.org/mirrors/chromedriver/
      
    • 定義讀取上述文件的方法

      from configparser import RawConfigParser  # 用於解析.ini格式的配置文件
      
      def get_ini(file):
          _ini = RawConfigParser()
          _ini.read(file, encoding='utf-8')
          return _ini
      
  4. 對比版本號

    import os
     
    def checkVersionMatch():
        # 讀取conf.ini中的配置項
        conf = get_ini('conf.ini')
        absPath = conf.get('driver', 'absPath')
    
        print('Chrome version compares with chromedriver version')
        c_v = getChromeVersion()
        d_v = getDriverVersion(absPath)
    
        if c_v == d_v:
            # 若匹配,在命令行窗口提示下面的信息
            input('Chrome and chromedriver are matched. Press Enter to exit.')
        else:
            # 若不匹配,走下面的流程去下載chromedriver
            _v = c_v
    
            url = conf.get('driver', 'url') # 從conf.ini中獲取淘寶鏡像url
    
            save_d = os.path.dirname(absPath) # 下載文件的保存路徑,與chromedriver同級
    
            downLoadDriver(_v, url, save_d) # call下載文件的方法
    
  5. 下載文件並解壓

    import urllib.request  	# 發送http請求
    import urllib.parse  	# 拼接url
    import zipfile  		# 操作.zip文件
    
    def downLoadDriver(__v, url, save_d):
        # 訪問淘寶鏡像首頁
        rep = urllib.request.urlopen(url).read().decode('utf-8')
        # '<a href="/mirrors/chromedriver/84.0.4147.30/">84.0.4147.30/</a>'
        directory = re.compile(r'>(\d.*?/)</a>').findall(rep)  # 匹配文件夾(版本號)
     	
        # 獲取期望的文件夾(版本號)
        match_list = []
        for i in directory:
            v = version_re.findall(i)[0]
            if __v == v:
                match_list.append(i)
          
        # http://npm.taobao.org/mirrors/chromedriver/83.0.4103.39/chromedriver_win32.zip
        dirUrl = urllib.parse.urljoin(url, match_list[-1])
    
        downUrl = urllib.parse.urljoin(dirUrl, 'chromedriver_win32.zip') # 拼接出下載路徑
        print('will download {}'.format(downUrl))
    
        # 指定下載的文件名和保存位置
        file = os.path.join(save_d, os.path.basename(downUrl))
        print('will saved in {}'.format(file))
    
        # 開始下載,並顯示下載進度(progressFunc)
        urllib.request.urlretrieve(downUrl, file, progressFunc)
    
        # 下載完成后解壓
        zFile = zipfile.ZipFile(file, 'r')
        for fileM in zFile.namelist():
            zFile.extract(fileM, os.path.dirname(file))
        zFile.close()
     	
        input('Complete, press Enter to exit')
    
  6. 顯示下載進度的方法

    import sys
     
    def progressFunc(blocknum, blocksize, totalsize):
        '''作回調函數用
        @blocknum: 已經下載的數據塊
        @blocksize: 數據塊的大小
        @totalsize: 遠程文件的大小
        '''
        percent = 100.0 * blocknum * blocksize / totalsize
    
        if percent > 100:
            percent = 100
        downsize = blocknum * blocksize
    
        if downsize >= totalsize:
            downsize = totalsize
    
        s = "%.2f%%" % (percent) + "====>" + "%.2f" % (downsize / 1024 / 1024) + "M/" + "%.2f" % (totalsize / 1024 / 1024) + "M \r"
        sys.stdout.write(s)
        sys.stdout.flush()
    
        if percent == 100:
            print('')
    
  7. 以線程的方式運行

    import threading
     
    if __name__ == '__main__':
        threading.Thread(target=checkVersionMatch, args=('')).start()
    

打包成 .exe程序(打包教程略過,因為運行.py文件也行)

  • 雙擊運行cdCheck.exe 即可(注意conf.ini中absPath的值)

    avatar

  • .exe下載地址

  • 運行效果圖

    avatar

  • 歡迎指正交流!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM