Код для реализации конфигурации драйвера Selenium WebDrive.

1. Условия

1. Используемый браузер — Microsoft Edge.

2. Кратко опишите процесс (реализация кода)

1.pip-установка

2.Скачать

3. Разархивируйте

4. Бегите

3. Нашёл ошибку

1) Причина

Прежде чем дать код, я обнаружил возмутительную ошибку. Пусть автор объяснит медленно и подробно. Сначала устанавливается selenium4.11.2, а также настраивается Edge WebDriver. В одном из проектов интерпретатором является python3.10 и запускается следующий код

from selenium import webdriver
browser = webdriver.Edge()
browser.get('https://www.baidu.com')

Я обнаружил, что было сообщено об ошибке. Причина ошибки была указана в конце.

selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for MicrosoftEdge using Selenium Manager.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location

Если поискать причину в Интернете, то можно найти следующие результаты:

selenium открывает браузер и сообщает об ошибке, успешно решая selenium.common.Exceptions.NoSuchDriverException: Сообщение: невозможно получить... блог _sinnp-CSDN

Жаль, что решение этого босса не подходит для сообщения об ошибке автора. Хотя отчет об ошибке один и тот же, все-таки он разный.Конкретную ситуацию необходимо анализировать детально.

2) Рассуждение

Поэтому автор выписывает все выявленные ошибки.

Traceback (most recent call last):
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\selenium_manager.py", line 124, in run
    stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")
AttributeError: 'str' object has no attribute 'decode'. Did you mean: 'encode'?

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\driver_finder.py", line 38, in get_path
    path = SeleniumManager().driver_location(options) if path is None else path
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\selenium_manager.py", line 90, in driver_location
    output = self.run(args)
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\selenium_manager.py", line 129, in run
    raise WebDriverException(f"Unsuccessful command executed: {command}") from err
selenium.common.exceptions.WebDriverException: Message: Unsuccessful command executed: C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\windows\selenium-manager.exe --browser MicrosoftEdge --output json


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\520\PycharmProjects\pythonProject4\selenium的故事\6.py", line 2, in <module>
    browser = webdriver.Edge()
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\edge\webdriver.py", line 45, in __init__
    super().__init__(
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\chromium\webdriver.py", line 51, in __init__
    self.service.path = DriverFinder.get_path(self.service, options)
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\driver_finder.py", line 41, in get_path
    raise NoSuchDriverException(msg) from err
selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for MicrosoftEdge using Selenium Manager.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location

Начните с браузера = webdriver.Edge().

Спуститесь вниз и перейдите сюда self.service.path = DriverFinder.get_path(self.service, options), зайдите и посмотрите исходный код. Затем введите метод get_path, код следующий

    @staticmethod
    def get_path(service: Service, options: BaseOptions) -> str:
        path = service.path
        try:
            path = SeleniumManager().driver_location(options) if path is None else path

        except Exception as err:
            msg = f"Unable to obtain driver for {options.capabilities['browserName']} using Selenium Manager."
            raise NoSuchDriverException(msg) from err

        if path is None or not Path(path).is_file():
            raise NoSuchDriverException(f"Unable to locate or obtain driver for {options.capabilities['browserName']}")

        return path

Вы можете попробовать распечатать путь.Первый путь пуст, а второй путь не печатается, и сообщается об ошибке. Еще раз просмотрите содержимое отчета об ошибке, включая этот абзац.

Traceback (most recent call last):
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\driver_finder.py", line 38, in get_path
    path = SeleniumManager().driver_location(options) if path is None else path

Он также указал, что существует проблема с этой строкой кода, поэтому введите метод driver_location в этой строке кода, просмотрите содержимое, а затем просмотрите следующий отчет об ошибке.

  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\selenium_manager.py", line 89, in driver_location
    output = self.run(args)

Эту строку кода можно найти в методе driver_location, поэтому я думаю, что с этой строкой кода что-то не так. Вы также можете вывести некоторые переменные, такие как args, и, наконец, подтвердить это предположение.

Итак, введите метод self.run. Основные коды следующие:

    @staticmethod
    def run(args: List[str]) -> dict:
        """
        Executes the Selenium Manager Binary.
        :Args:
         - args: the components of the command being executed.
        :Returns: The log string containing the driver location.
        """
        if logger.getEffectiveLevel() == logging.DEBUG:
            args.append("--debug")
        args.append("--output")
        args.append("json")

        command = " ".join(args)
        logger.debug(f"Executing process: {command}")
        try:
            if sys.platform == "win32":
                completed_proc = subprocess.run(
                    args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=subprocess.CREATE_NO_WINDOW
                )
            else:
                completed_proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")
            stderr = completed_proc.stderr.decode("utf-8").rstrip("\n")
            output = json.loads(stdout)
            result = output["result"]

Посмотрите еще раз отчет об ошибке

Traceback (most recent call last):
  File "C:\Users\520\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\pythonProject4\lib\site-packages\selenium\webdriver\common\selenium_manager.py", line 123, in run
    stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")
AttributeError: 'str' object has no attribute 'decode'. Did you mean: 'encode'?

Очевидно, существует проблема с stdout =complete_proc.stdout.decode("utf-8").rstrip("\n") в self.run. Причина ошибки в том, что str не имеет этого атрибута декодирования. Он имеет нет.

Распечатайте Completed_proc и получите следующие результаты:

CompletedProcess(args=['C:\\Users\\520\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\pythonProject4\\lib\\site-packages\\selenium\\webdriver\\common\\windows\\selenium-manager.exe', '--browser', 'MicrosoftEdge', '--output', 'json'], returncode=0, stdout='{\n  "logs": [\n    {\n      "level": "INFO",\n      "timestamp": 1692601797,\n      "message": "Driver path: C:\\\\Users\\\\520\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python310\\\\msedgedriver.exe"\n    },\n    {\n      "level": "INFO",\n      "timestamp": 1692601797,\n      "message": "Browser path: C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe"\n    }\n  ],\n  "result": {\n    "code": 0,\n    "message": "C:\\\\Users\\\\520\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python310\\\\msedgedriver.exe",\n    "driver_path": "C:\\\\Users\\\\520\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python310\\\\msedgedriver.exe",\n    "browser_path": "C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe"\n  }\n}', stderr=b'')

Возврат представляет собой объект CompletedProcess, да, снова напечатайте Completed_proc.stdout, код следующий

{
  "logs": [
    {
      "level": "INFO",
      "timestamp": 1692601871,
      "message": "Driver path: C:\\Users\\520\\AppData\\Local\\Programs\\Python\\Python310\\msedgedriver.exe"
    },
    {
      "level": "INFO",
      "timestamp": 1692601871,
      "message": "Browser path: C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"
    }
  ],
  "result": {
    "code": 0,
    "message": "C:\\Users\\520\\AppData\\Local\\Programs\\Python\\Python310\\msedgedriver.exe",
    "driver_path": "C:\\Users\\520\\AppData\\Local\\Programs\\Python\\Python310\\msedgedriver.exe",
    "browser_path": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"
  }
}

Результатом является строка.Очевидно, что str не имеет атрибута декодирования. Это основная причина ошибки.

3) Мышление

Почему print(completed_proc.stdout), тип печатаемого объекта - str, очевидно по пониманию кода, его надо печатать как байтовый тип, тогда будет декодирование. Вы можете зайти на официальный сайт, чтобы увидеть объяснение, как показано ниже.

 Возвращается последовательность байтов или строка, что может быть интересно.

Поскольку на моем компьютере установлены python310 и python311, но я использовал python311 в качестве редактора для создания проекта, при запуске кода не было обнаружено ошибок, а напечатанный завершенный_proc.stdout представляет собой последовательность байтов, поэтому об ошибках не сообщалось.

Почему одни и те же коды дают разные результаты при запуске в среде, отличной от Python?Я не знаю причины.

4) Изменить

Поскольку завершенный_proc.stdout является строкой, закомментируйте декодирование напрямую. Код выглядит следующим образом:

            stdout=completed_proc.stdout
            # stdout = completed_proc.stdout.decode("utf-8").rstrip("\n")
            # stderr = completed_proc.stderr.decode("utf-8").rstrip("\n")
            output = json.loads(stdout)

Ошибок при запуске не было.

4.Текст

Приведенный выше отчет об ошибке — всего лишь эпизод. Теперь, чтобы добиться реальной конфигурации, сначала я увидел код этого босса

https://blog.csdn.net/weixin_49958813/article/details/125580029

Хорошо написано, вот и у меня возникла идея.В коде этого босса только обновления. Это кажется незавершенным.

Итак, код выглядит следующим образом:

import time
from xml.dom import minidom as xml
from xml.dom.minicompat import NodeList
from xml.dom.minidom import Element
from tqdm import tqdm
import requests
import re
import getpass
from zipfile import ZipFile
from logging import StreamHandler,getLogger,DEBUG
from colorlog import ColoredFormatter
import sys
from pathlib import Path
import subprocess
class WebDriver:
    def __init__(self,output_path,zip_file=None):
        self.has_zip=False
        self.dom = xml.parse(r'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.VisualElementsManifest.xml')
        self.logger=self.log()
        self.output_path=output_path
        self.zip_file='C:/Users/'+self.user+'/Downloads/edgedriver.zip'
    def log(self):
        """
        日志的配置
        :return:
        """
        colors = {
            'DEBUG': 'bold_red',
            'INFO': 'bold_blue',
            'WARNING': 'bold_yellow',
        }
        logger = getLogger(__file__)
        stream_handler = StreamHandler()
        logger.setLevel(DEBUG)
        color_formatter = ColoredFormatter(
            fmt='%(log_color)s %(asctime)s %(filename)s  %(funcName)s line:%(lineno)d %(levelname)s : %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
            log_colors=colors
        )
        stream_handler.setFormatter(color_formatter)
        logger.addHandler(stream_handler)
        return logger
    def decompression(self,delete_zip=True):
        """
        解压
        :return:
        """
        if self.has_zip:
            zip=ZipFile(self.zip_file)
            zip.extractall(self.output_path)
            zip.close()
            self.logger.info(f'解压成功,webdriver的路径为{self.output_path}')
            if delete_zip:
                Path(self.zip_file).unlink()
                self.logger.debug('删除webdriver.zip文件')
        else:
            self.logger.warning('没有发现webdriver.zip文件')
    def download(self):
        """
        下载webriver
        :return:
        """
        if Path(self.zip_file).exists():
            self.has_zip=True
            self.logger.info('找到webdriver.zip文件,即将积压')
            return
        self.logger.info('没有发现webdriver.zip,即将下载!')
        version=self.get_version
        url = 'https://msedgedriver.azureedge.net/' + version + '/edgedriver_win64.zip'
        self.logger.info('正在发送请求...')
        response=requests.get(url=url)
        self.logger.info('请求成功')
        total=response.headers['Content-Length']
        total = int(total)
        self.logger.info('文件大小为 '+str(total)+' B')
        with open(self.zip_file,'wb') as f:
            with tqdm(total=total,desc="webdriver下载") as p:
                    for i in response.iter_content(1024*100):
                        f.write(i)
                        time.sleep(0.2)
                        p.update(1024*100)
        self.logger.debug('webdriver.zip 下载完成!!')
        self.has_zip=True
    def __display(self):
        """
        安装、运行、更新
        :return:
        """
        try:
            from selenium import webdriver
            from selenium.common.exceptions import SessionNotCreatedException,NoSuchDriverException
            self.logger.info('selenium存在,即将打开edge')
            browser = webdriver.Edge()
            browser.get('https://www.baidu.com')
            browser.quit()
            self.logger.info('edge关闭,运行成功')
        except ModuleNotFoundError as e:
            self.logger.warning('selenium 不存在,即将安装...')
            cmd='pip install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium'
            result=subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            self.logger.debug('安装过程:\n'+result.stdout)
            self.logger.info('下载selenium成功,')
            self.logger.info('等待安装..')
            time.sleep(10)
            self.__display()
        except SessionNotCreatedException as e:
            self.logger.warning('需要更新webdriver!!!!')
            self.download()
            self.decompression()
            self.logger.info('更新成功')
            self.logger.info('再次运行seleniun')
            self.__display()
    def up_to_date(self):
        """
        更新webdriver版本
        :return:
        """
    @property
    def get_version(self):
        """
        得到edge的版本
        :return:
        """
        dom = self.dom.documentElement
        nodeList:NodeList = dom.getElementsByTagName('VisualElements')
        element:Element=nodeList[0]
        text=element.toxml()
        version='.'.join(re.findall('(\d+)\.(\d+)\.(\d+)\.(\d+)', text)[0])
        return version
    @property
    def user(self):
        """
        得到当前的使用者
        :return:
        """
        return getpass.getuser()
    def install(self):
        self.__display()
if __name__ == '__main__':
    webdriver=WebDriver(output_path=sys.path[6])
    webdriver.install()



С помощью этого кода селен и веб-драйвер можно установить напрямую и обновить. Если вы столкнулись с приведенным выше отчетом об ошибке, если содержание отчета об ошибке такое же, вы можете изменить его в соответствии с содержимым. Если есть другие ошибки, вы можете просмотреть свой личный анализ.

Для других браузеров мало что можно найти.

5.Результаты

 Автор обнаружил, что похоже, что msedgedriver.exe будет автоматически загружен при первом запуске, а селен стал продвинутым, чего раньше не было. Путь автора таков

C:/Users/520/.cache/selenium/msedgedriver/win64/115.0.1901.203/msedgedriver.exe

 

Supongo que te gusta

Origin blog.csdn.net/qq_63401240/article/details/132406123
Recomendado
Clasificación