zoukankan      html  css  js  c++  java
  • 获取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_USERSoftwareGoogleChromeBLBeaconversion中得到;

    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'SoftwareGoogleChromeBLBeacon')
      
              _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:pypracchromedriver.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:pypracchromedriver.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 
      "
          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

    • 欢迎指正交流!!!

  • 相关阅读:
    shell 算术运算符
    shell 关系运算符
    shell 布尔运算符
    shell逻辑运算符
    shell 字符串运算符
    shell 文件测试运算符
    shell 运算符
    shell 循环总结
    Shell echo命令
    利用WHID为隔离主机建立隐秘通道
  • 原文地址:https://www.cnblogs.com/z417/p/13785734.html
Copyright © 2011-2022 走看看