1. 程式人生 > 其它 >python - selenium windows下自動根據chrome版本下載最新驅動

python - selenium windows下自動根據chrome版本下載最新驅動

前言

在編寫自動化測試框架時,chrome瀏覽器總是會自動更新版本,時不時會導致編寫指令碼時,chromedriver不可用。所以編寫以下指令碼完成自動更新檢測,在每次啟動時,更新或者替換chormedriver,只針對於winodws系統。

程式碼分解,完整程式碼放在最後。

1、從windows登錄檔中獲取chrome版本號

# logger是自己封裝的日誌模組,可以用print代替!!!
import winreg  # 和登錄檔互動


def get_chrome_version():
    """
    通過windows登錄檔獲取chrome版本號
    :return: 版本號(str)
    """
    try:
        # 從登錄檔中獲得版本號
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon')
        _v, _type = winreg.QueryValueEx(key, 'version')
        logger.info('Chrome瀏覽器版本號為: {}'.format(_v))
        return _v  # 返回版本號

    except WindowsError as e:
        logger.error(f"檢查Chrome失敗: {e}")

2、從chromedriver驅動中獲取當前驅動版本號

import subprocess  # 用於執行cmd命令


def get_driver_version(abs_path):
    """
    獲取driver版本號
    :param abs_path: chromedriver.exe的絕對路徑
    :return: 版本號(str)
    """
    cmd = r'{} --version'.format(abs_path)  # 拼接成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]  # 拆分回顯字串,獲取版本號
        logger.info('chromedriver驅動版本號為:{}'.format(_v))
        return _v
    except IndexError as e:
        logger.error(f'檢查driver驅動失敗:{e}')
        return 0

3、下載並解壓chromedriver。

import urllib.request  # 傳送http請求
import urllib.parse  # 拼接url
import zipfile  # 操作.zip檔案


def get_driver_version(abs_path):
    """
    獲取driver版本號
    :param abs_path: chromedriver.exe的絕對路徑
    :return: 版本號(str)
    """
    cmd = r'{} --version'.format(abs_path)  # 拼接成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]  # 拆分回顯字串,獲取版本號
        logger.info('chromedriver驅動版本號為:{}'.format(_v))
        return _v
    except IndexError as e:
        logger.error(f'檢查driver驅動失敗:{e}')
        return 0

4、主方法執行版本檢測並下載

import urllib.request  # 傳送http請求
import urllib.parse  # 拼接url


def check_version_match(driver_path=''):
    if platform.system() == "Windows":
        chrome_version = get_chrome_version()
        # 拼接映象下載路徑
        url = f"https://cdn.npmmirror.com/binaries/chromedriver/{chrome_version}/chromedriver_win32.zip"
        if os.path.exists(driver_path):
            logger.info(f'Chrome版本與chromedriver版本比較')
            driver_version = get_driver_version(driver_path)
            if str(chrome_version) != str(driver_version):
                # 下載檔案的儲存路徑,與chromedriver同級
                down_load_driver(url, driver_path)  # call下載檔案的方法
            else:
                logger.info("版本號一致,忽略下載~")
            return driver_path
        else:
            logger.error(f"不存在的路徑:【{driver_path}】")
            sys.exit()

5、完整程式碼

import os
import platform
import winreg  # 和登錄檔互動
import subprocess  # 用於執行cmd命令

import urllib.request  # 傳送http請求
import urllib.parse  # 拼接url
import zipfile  # 操作.zip檔案
from config.log_config import logger
import sys


def get_chrome_version():
    """
    通過windows登錄檔獲取chrome版本號
    :return: 版本號(str)
    """
    try:
        # 從登錄檔中獲得版本號
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon')
        _v, _type = winreg.QueryValueEx(key, 'version')
        logger.info('Chrome瀏覽器版本號為: {}'.format(_v))
        return _v  # 返回版本號

    except WindowsError as e:
        logger.error(f"檢查Chrome失敗: {e}")


def get_driver_version(abs_path):
    """
    獲取driver版本號
    :param abs_path: chromedriver.exe的絕對路徑
    :return: 版本號(str)
    """
    cmd = r'{} --version'.format(abs_path)  # 拼接成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]  # 拆分回顯字串,獲取版本號
        logger.info('chromedriver驅動版本號為:{}'.format(_v))
        return _v
    except IndexError as e:
        logger.error(f'檢查driver驅動失敗:{e}')
        return 0


def down_load_driver(url, original_driver_path):
    """
    下載driver驅動
    :param url: 下載地址
    :param original_driver_path: 原始driver驅動存放地址
    :return:
    """
    # 訪問淘寶映象首頁
    logger.info(f'下載url為: {url}')
    # 指定下載的檔名和儲存位置
    save_d = os.path.dirname(original_driver_path)
    logger.info(f'driver檔案儲存位置為: {save_d}')
    # 開始下載,並顯示下載進度(progressFunc)
    urllib.request.urlretrieve(url, os.path.join(save_d, 'chromedriver_win32.zip'))
    # 壓縮包路徑
    z_file_path = os.path.join(save_d, 'chromedriver_win32.zip')
    # 下載完成後解壓
    zFile = zipfile.ZipFile(z_file_path, 'r')
    for fileM in zFile.namelist():
        zFile.extract(fileM, save_d)
    zFile.close()
    logger.warning("----------------------【driver檔案下載完成】---------------------")
    # 刪除壓縮包
    os.remove(z_file_path)
    logger.warning("----------------------【刪除[chromedriver_win32.zip]壓縮包】---------------------")


def check_version_match(driver_path=''):
    if platform.system() == "Windows":
        chrome_version = get_chrome_version()
        # 拼接映象下載路徑
        url = f"https://cdn.npmmirror.com/binaries/chromedriver/{chrome_version}/chromedriver_win32.zip"
        if os.path.exists(driver_path):
            logger.info(f'Chrome版本與chromedriver版本比較')
            driver_version = get_driver_version(driver_path)
            if str(chrome_version) != str(driver_version):
                # 下載檔案的儲存路徑,與chromedriver同級
                down_load_driver(url, driver_path)  # call下載檔案的方法
            else:
                logger.info("版本號一致,忽略下載~")
            return driver_path
        else:
            logger.error(f"不存在的路徑:【{driver_path}】")
            sys.exit()