webdriver无法打开Chrome,以下是错误提示

Testing started at 18:51 …
D:\BaiduNetdiskDownload\PyCharm2020.1\testproject\venv\Scripts\python.exe “D:\Program Files\JetBrains\PyCharm 2020.1\plugins\python\helpers\pycharm_jb_pytest_runner.py” --target test_selenium.py::test_selenium
Launching pytest with arguments test_selenium.py::test_selenium in D:\BaiduNetdiskDownload\PyCharm2020.1\testproject

============================= test session starts =============================
platform win32 – Python 3.8.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 – D:\BaiduNetdiskDownload\PyCharm2020.1\testproject\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\BaiduNetdiskDownload\PyCharm2020.1\testproject
collecting … collected 1 item

test_selenium.py::test_selenium FAILED [100%]
test_selenium.py:3 (test_selenium)
self = <selenium.webdriver.chrome.service.Service object at 0x0000023CFC43C190>

def start(self):
    """
    Starts the Service.

    :Exceptions:
     - WebDriverException : Raised either when it can't start the service
       or when it can't connect to the service
    """
    try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
      self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=system() != 'Windows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                        stdin=PIPE,
                                        creationflags=self.creationflags)

venv\lib\site-packages\selenium\webdriver\common\service.py:71:


self = <subprocess.Popen object at 0x0000023CFC43C280>
args = [‘chromedriver’, ‘–port=62549’], bufsize = -1, executable = None
stdin = -1, stdout = -3, stderr = -3, preexec_fn = None, close_fds = False
shell = False, cwd = None
env = environ({‘ALLUSERSPROFILE’: ‘C:\ProgramData’, ‘ANDROID_SDK_HOME’: ‘D:\android-studio3.2’, ‘APPDATA’: ‘C:\Users\861…VIRTUAL_PROMPT’: ‘$P$G’, ‘TEAMCITY_VERSION’: ‘LOCAL’, ‘PYTEST_CURRENT_TEST’: ‘test_selenium.py::test_selenium (call)’})
universal_newlines = None, startupinfo = None, creationflags = 0
restore_signals = True, start_new_session = False, pass_fds = ()

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=True,
             shell=False, cwd=None, env=None, universal_newlines=None,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None, text=None):
    """Create new Popen instance."""
    _cleanup()
    # Held while anything is calling waitpid before returncode has been
    # updated to prevent clobbering returncode if wait() or poll() are
    # called from multiple threads at once.  After acquiring the lock,
    # code must re-check self.returncode to see if another thread just
    # finished a waitpid() call.
    self._waitpid_lock = threading.Lock()

    self._input = None
    self._communication_started = False
    if bufsize is None:
        bufsize = -1  # Restore default
    if not isinstance(bufsize, int):
        raise TypeError("bufsize must be an integer")

    if _mswindows:
        if preexec_fn is not None:
            raise ValueError("preexec_fn is not supported on Windows "
                             "platforms")
    else:
        # POSIX
        if pass_fds and not close_fds:
            warnings.warn("pass_fds overriding close_fds.", RuntimeWarning)
            close_fds = True
        if startupinfo is not None:
            raise ValueError("startupinfo is only supported on Windows "
                             "platforms")
        if creationflags != 0:
            raise ValueError("creationflags is only supported on Windows "
                             "platforms")

    self.args = args
    self.stdin = None
    self.stdout = None
    self.stderr = None
    self.pid = None
    self.returncode = None
    self.encoding = encoding
    self.errors = errors

    # Validate the combinations of text and universal_newlines
    if (text is not None and universal_newlines is not None
        and bool(universal_newlines) != bool(text)):
        raise SubprocessError('Cannot disambiguate when both text '
                              'and universal_newlines are supplied but '
                              'different. Pass one or the other.')

    # Input and output objects. The general principle is like
    # this:
    #
    # Parent                   Child
    # ------                   -----
    # p2cwrite   ---stdin--->  p2cread
    # c2pread    <--stdout---  c2pwrite
    # errread    <--stderr---  errwrite
    #
    # On POSIX, the child objects are file descriptors.  On
    # Windows, these are Windows file handles.  The parent objects
    # are file descriptors on both platforms.  The parent objects
    # are -1 when not using PIPEs. The child objects are -1
    # when not redirecting.

    (p2cread, p2cwrite,
     c2pread, c2pwrite,
     errread, errwrite) = self._get_handles(stdin, stdout, stderr)

    # We wrap OS handles *before* launching the child, otherwise a
    # quickly terminating child could make our fds unwrappable
    # (see #8458).

    if _mswindows:
        if p2cwrite != -1:
            p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0)
        if c2pread != -1:
            c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0)
        if errread != -1:
            errread = msvcrt.open_osfhandle(errread.Detach(), 0)

    self.text_mode = encoding or errors or text or universal_newlines

    # How long to resume waiting on a child after the first ^C.
    # There is no right value for this.  The purpose is to be polite
    # yet remain good for interactive users trying to exit a tool.
    self._sigint_wait_secs = 0.25  # 1/xkcd221.getRandomNumber()

    self._closed_child_pipe_fds = False

    if self.text_mode:
        if bufsize == 1:
            line_buffering = True
            # Use the default buffer size for the underlying binary streams
            # since they don't support line buffering.
            bufsize = -1
        else:
            line_buffering = False

    try:
        if p2cwrite != -1:
            self.stdin = io.open(p2cwrite, 'wb', bufsize)
            if self.text_mode:
                self.stdin = io.TextIOWrapper(self.stdin, write_through=True,
                        line_buffering=line_buffering,
                        encoding=encoding, errors=errors)
        if c2pread != -1:
            self.stdout = io.open(c2pread, 'rb', bufsize)
            if self.text_mode:
                self.stdout = io.TextIOWrapper(self.stdout,
                        encoding=encoding, errors=errors)
        if errread != -1:
            self.stderr = io.open(errread, 'rb', bufsize)
            if self.text_mode:
                self.stderr = io.TextIOWrapper(self.stderr,
                        encoding=encoding, errors=errors)
      self._execute_child(args, executable, preexec_fn, close_fds,
                            pass_fds, cwd, env,
                            startupinfo, creationflags, shell,
                            p2cread, p2cwrite,
                            c2pread, c2pwrite,
                            errread, errwrite,
                            restore_signals, start_new_session)

D:\Program Files\lib\subprocess.py:854:


self = <subprocess.Popen object at 0x0000023CFC43C280>
args = ‘chromedriver --port=62549’, executable = None, preexec_fn = None
close_fds = False, pass_fds = (), cwd = None
env = environ({‘ALLUSERSPROFILE’: ‘C:\ProgramData’, ‘ANDROID_SDK_HOME’: ‘D:\android-studio3.2’, ‘APPDATA’: ‘C:\Users\861…VIRTUAL_PROMPT’: ‘$P$G’, ‘TEAMCITY_VERSION’: ‘LOCAL’, ‘PYTEST_CURRENT_TEST’: ‘test_selenium.py::test_selenium (call)’})
startupinfo = <subprocess.STARTUPINFO object at 0x0000023CFC43C310>
creationflags = 0, shell = False, p2cread = Handle(336), p2cwrite = 12
c2pread = -1, c2pwrite = Handle(352), errread = -1, errwrite = Handle(664)
unused_restore_signals = True, unused_start_new_session = False

def _execute_child(self, args, executable, preexec_fn, close_fds,
                   pass_fds, cwd, env,
                   startupinfo, creationflags, shell,
                   p2cread, p2cwrite,
                   c2pread, c2pwrite,
                   errread, errwrite,
                   unused_restore_signals, unused_start_new_session):
    """Execute program (MS Windows version)"""

    assert not pass_fds, "pass_fds not supported on Windows."

    if isinstance(args, str):
        pass
    elif isinstance(args, bytes):
        if shell:
            raise TypeError('bytes args is not allowed on Windows')
        args = list2cmdline([args])
    elif isinstance(args, os.PathLike):
        if shell:
            raise TypeError('path-like args is not allowed when '
                            'shell is true')
        args = list2cmdline([args])
    else:
        args = list2cmdline(args)

    if executable is not None:
        executable = os.fsdecode(executable)

    # Process startup details
    if startupinfo is None:
        startupinfo = STARTUPINFO()
    else:
        # bpo-34044: Copy STARTUPINFO since it is modified above,
        # so the caller can reuse it multiple times.
        startupinfo = startupinfo.copy()

    use_std_handles = -1 not in (p2cread, c2pwrite, errwrite)
    if use_std_handles:
        startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES
        startupinfo.hStdInput = p2cread
        startupinfo.hStdOutput = c2pwrite
        startupinfo.hStdError = errwrite

    attribute_list = startupinfo.lpAttributeList
    have_handle_list = bool(attribute_list and
                            "handle_list" in attribute_list and
                            attribute_list["handle_list"])

    # If we were given an handle_list or need to create one
    if have_handle_list or (use_std_handles and close_fds):
        if attribute_list is None:
            attribute_list = startupinfo.lpAttributeList = {}
        handle_list = attribute_list["handle_list"] = \
            list(attribute_list.get("handle_list", []))

        if use_std_handles:
            handle_list += [int(p2cread), int(c2pwrite), int(errwrite)]

        handle_list[:] = self._filter_handle_list(handle_list)

        if handle_list:
            if not close_fds:
                warnings.warn("startupinfo.lpAttributeList['handle_list'] "
                              "overriding close_fds", RuntimeWarning)

            # When using the handle_list we always request to inherit
            # handles but the only handles that will be inherited are
            # the ones in the handle_list
            close_fds = False

    if shell:
        startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = _winapi.SW_HIDE
        comspec = os.environ.get("COMSPEC", "cmd.exe")
        args = '{} /c "{}"'.format (comspec, args)

    if cwd is not None:
        cwd = os.fsdecode(cwd)

    sys.audit("subprocess.Popen", executable, args, cwd, env)

    # Start the process
    try:
      hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                                 # no special security
                                 None, None,
                                 int(not close_fds),
                                 creationflags,
                                 env,
                                 cwd,
                                 startupinfo)

E FileNotFoundError: [WinError 2] 系统找不到指定的文件。

D:\Program Files\lib\subprocess.py:1307: FileNotFoundError

During handling of the above exception, another exception occurred:

def test_selenium():
  driver=webdriver.Chrome()

test_selenium.py:5:


venv\lib\site-packages\selenium\webdriver\chrome\webdriver.py:70: in init
super(WebDriver, self).init(DesiredCapabilities.CHROME[‘browserName’], “goog”,
venv\lib\site-packages\selenium\webdriver\chromium\webdriver.py:90: in init
self.service.start()


self = <selenium.webdriver.chrome.service.Service object at 0x0000023CFC43C190>

def start(self):
    """
    Starts the Service.

    :Exceptions:
     - WebDriverException : Raised either when it can't start the service
       or when it can't connect to the service
    """
    try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
        self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=system() != 'Windows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                        stdin=PIPE,
                                        creationflags=self.creationflags)
    except TypeError:
        raise
    except OSError as err:
        if err.errno == errno.ENOENT:
          raise WebDriverException(
                "'%s' executable needs to be in PATH. %s" % (
                    os.path.basename(self.path), self.start_error_message)

E selenium.common.exceptions.WebDriverException: Message: ‘chromedriver’ executable needs to be in PATH. Please see ChromeDriver - WebDriver for Chrome

venv\lib\site-packages\selenium\webdriver\common\service.py:81: WebDriverException

================================== FAILURES ===================================
________________________________ test_selenium ________________________________

self = <selenium.webdriver.chrome.service.Service object at 0x0000023CFC43C190>

def start(self):
    """
    Starts the Service.

    :Exceptions:
     - WebDriverException : Raised either when it can't start the service
       or when it can't connect to the service
    """
    try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
      self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=system() != 'Windows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                        stdin=PIPE,
                                        creationflags=self.creationflags)

venv\lib\site-packages\selenium\webdriver\common\service.py:71:


self = <subprocess.Popen object at 0x0000023CFC43C280>
args = [‘chromedriver’, ‘–port=62549’], bufsize = -1, executable = None
stdin = -1, stdout = -3, stderr = -3, preexec_fn = None, close_fds = False
shell = False, cwd = None
env = environ({‘ALLUSERSPROFILE’: ‘C:\ProgramData’, ‘ANDROID_SDK_HOME’: ‘D:\android-studio3.2’, ‘APPDATA’: ‘C:\Users\861…VIRTUAL_PROMPT’: ‘$P$G’, ‘TEAMCITY_VERSION’: ‘LOCAL’, ‘PYTEST_CURRENT_TEST’: ‘test_selenium.py::test_selenium (call)’})
universal_newlines = None, startupinfo = None, creationflags = 0
restore_signals = True, start_new_session = False, pass_fds = ()

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=True,
             shell=False, cwd=None, env=None, universal_newlines=None,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None, text=None):
    """Create new Popen instance."""
    _cleanup()
    # Held while anything is calling waitpid before returncode has been
    # updated to prevent clobbering returncode if wait() or poll() are
    # called from multiple threads at once.  After acquiring the lock,
    # code must re-check self.returncode to see if another thread just
    # finished a waitpid() call.
    self._waitpid_lock = threading.Lock()

    self._input = None
    self._communication_started = False
    if bufsize is None:
        bufsize = -1  # Restore default
    if not isinstance(bufsize, int):
        raise TypeError("bufsize must be an integer")

    if _mswindows:
        if preexec_fn is not None:
            raise ValueError("preexec_fn is not supported on Windows "
                             "platforms")
    else:
        # POSIX
        if pass_fds and not close_fds:
            warnings.warn("pass_fds overriding close_fds.", RuntimeWarning)
            close_fds = True
        if startupinfo is not None:
            raise ValueError("startupinfo is only supported on Windows "
                             "platforms")
        if creationflags != 0:
            raise ValueError("creationflags is only supported on Windows "
                             "platforms")

    self.args = args
    self.stdin = None
    self.stdout = None
    self.stderr = None
    self.pid = None
    self.returncode = None
    self.encoding = encoding
    self.errors = errors

    # Validate the combinations of text and universal_newlines
    if (text is not None and universal_newlines is not None
        and bool(universal_newlines) != bool(text)):
        raise SubprocessError('Cannot disambiguate when both text '
                              'and universal_newlines are supplied but '
                              'different. Pass one or the other.')

    # Input and output objects. The general principle is like
    # this:
    #
    # Parent                   Child
    # ------                   -----
    # p2cwrite   ---stdin--->  p2cread
    # c2pread    <--stdout---  c2pwrite
    # errread    <--stderr---  errwrite
    #
    # On POSIX, the child objects are file descriptors.  On
    # Windows, these are Windows file handles.  The parent objects
    # are file descriptors on both platforms.  The parent objects
    # are -1 when not using PIPEs. The child objects are -1
    # when not redirecting.

    (p2cread, p2cwrite,
     c2pread, c2pwrite,
     errread, errwrite) = self._get_handles(stdin, stdout, stderr)

    # We wrap OS handles *before* launching the child, otherwise a
    # quickly terminating child could make our fds unwrappable
    # (see #8458).

    if _mswindows:
        if p2cwrite != -1:
            p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0)
        if c2pread != -1:
            c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0)
        if errread != -1:
            errread = msvcrt.open_osfhandle(errread.Detach(), 0)

    self.text_mode = encoding or errors or text or universal_newlines

    # How long to resume waiting on a child after the first ^C.
    # There is no right value for this.  The purpose is to be polite
    # yet remain good for interactive users trying to exit a tool.
    self._sigint_wait_secs = 0.25  # 1/xkcd221.getRandomNumber()

    self._closed_child_pipe_fds = False

    if self.text_mode:
        if bufsize == 1:
            line_buffering = True
            # Use the default buffer size for the underlying binary streams
            # since they don't support line buffering.
            bufsize = -1
        else:
            line_buffering = False

    try:
        if p2cwrite != -1:
            self.stdin = io.open(p2cwrite, 'wb', bufsize)
            if self.text_mode:
                self.stdin = io.TextIOWrapper(self.stdin, write_through=True,
                        line_buffering=line_buffering,
                        encoding=encoding, errors=errors)
        if c2pread != -1:
            self.stdout = io.open(c2pread, 'rb', bufsize)
            if self.text_mode:
                self.stdout = io.TextIOWrapper(self.stdout,
                        encoding=encoding, errors=errors)
        if errread != -1:
            self.stderr = io.open(errread, 'rb', bufsize)
            if self.text_mode:
                self.stderr = io.TextIOWrapper(self.stderr,
                        encoding=encoding, errors=errors)
      self._execute_child(args, executable, preexec_fn, close_fds,
                            pass_fds, cwd, env,
                            startupinfo, creationflags, shell,
                            p2cread, p2cwrite,
                            c2pread, c2pwrite,
                            errread, errwrite,
                            restore_signals, start_new_session)

D:\Program Files\lib\subprocess.py:854:


self = <subprocess.Popen object at 0x0000023CFC43C280>
args = ‘chromedriver --port=62549’, executable = None, preexec_fn = None
close_fds = False, pass_fds = (), cwd = None
env = environ({‘ALLUSERSPROFILE’: ‘C:\ProgramData’, ‘ANDROID_SDK_HOME’: ‘D:\android-studio3.2’, ‘APPDATA’: ‘C:\Users\861…VIRTUAL_PROMPT’: ‘$P$G’, ‘TEAMCITY_VERSION’: ‘LOCAL’, ‘PYTEST_CURRENT_TEST’: ‘test_selenium.py::test_selenium (call)’})
startupinfo = <subprocess.STARTUPINFO object at 0x0000023CFC43C310>
creationflags = 0, shell = False, p2cread = Handle(336), p2cwrite = 12
c2pread = -1, c2pwrite = Handle(352), errread = -1, errwrite = Handle(664)
unused_restore_signals = True, unused_start_new_session = False

def _execute_child(self, args, executable, preexec_fn, close_fds,
                   pass_fds, cwd, env,
                   startupinfo, creationflags, shell,
                   p2cread, p2cwrite,
                   c2pread, c2pwrite,
                   errread, errwrite,
                   unused_restore_signals, unused_start_new_session):
    """Execute program (MS Windows version)"""

    assert not pass_fds, "pass_fds not supported on Windows."

    if isinstance(args, str):
        pass
    elif isinstance(args, bytes):
        if shell:
            raise TypeError('bytes args is not allowed on Windows')
        args = list2cmdline([args])
    elif isinstance(args, os.PathLike):
        if shell:
            raise TypeError('path-like args is not allowed when '
                            'shell is true')
        args = list2cmdline([args])
    else:
        args = list2cmdline(args)

    if executable is not None:
        executable = os.fsdecode(executable)

    # Process startup details
    if startupinfo is None:
        startupinfo = STARTUPINFO()
    else:
        # bpo-34044: Copy STARTUPINFO since it is modified above,
        # so the caller can reuse it multiple times.
        startupinfo = startupinfo.copy()

    use_std_handles = -1 not in (p2cread, c2pwrite, errwrite)
    if use_std_handles:
        startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES
        startupinfo.hStdInput = p2cread
        startupinfo.hStdOutput = c2pwrite
        startupinfo.hStdError = errwrite

    attribute_list = startupinfo.lpAttributeList
    have_handle_list = bool(attribute_list and
                            "handle_list" in attribute_list and
                            attribute_list["handle_list"])

    # If we were given an handle_list or need to create one
    if have_handle_list or (use_std_handles and close_fds):
        if attribute_list is None:
            attribute_list = startupinfo.lpAttributeList = {}
        handle_list = attribute_list["handle_list"] = \
            list(attribute_list.get("handle_list", []))

        if use_std_handles:
            handle_list += [int(p2cread), int(c2pwrite), int(errwrite)]

        handle_list[:] = self._filter_handle_list(handle_list)

        if handle_list:
            if not close_fds:
                warnings.warn("startupinfo.lpAttributeList['handle_list'] "
                              "overriding close_fds", RuntimeWarning)

            # When using the handle_list we always request to inherit
            # handles but the only handles that will be inherited are
            # the ones in the handle_list
            close_fds = False

    if shell:
        startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = _winapi.SW_HIDE
        comspec = os.environ.get("COMSPEC", "cmd.exe")
        args = '{} /c "{}"'.format (comspec, args)

    if cwd is not None:
        cwd = os.fsdecode(cwd)

    sys.audit("subprocess.Popen", executable, args, cwd, env)

    # Start the process
    try:
      hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                                 # no special security
                                 None, None,
                                 int(not close_fds),
                                 creationflags,
                                 env,
                                 cwd,
                                 startupinfo)

E FileNotFoundError: [WinError 2] 系统找不到指定的文件。

D:\Program Files\lib\subprocess.py:1307: FileNotFoundError

During handling of the above exception, another exception occurred:

def test_selenium():
  driver=webdriver.Chrome()

test_selenium.py:5:


venv\lib\site-packages\selenium\webdriver\chrome\webdriver.py:70: in init
super(WebDriver, self).init(DesiredCapabilities.CHROME[‘browserName’], “goog”,
venv\lib\site-packages\selenium\webdriver\chromium\webdriver.py:90: in init
self.service.start()


self = <selenium.webdriver.chrome.service.Service object at 0x0000023CFC43C190>

def start(self):
    """
    Starts the Service.

    :Exceptions:
     - WebDriverException : Raised either when it can't start the service
       or when it can't connect to the service
    """
    try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
        self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=system() != 'Windows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                        stdin=PIPE,
                                        creationflags=self.creationflags)
    except TypeError:
        raise
    except OSError as err:
        if err.errno == errno.ENOENT:
          raise WebDriverException(
                "'%s' executable needs to be in PATH. %s" % (
                    os.path.basename(self.path), self.start_error_message)

E selenium.common.exceptions.WebDriverException: Message: ‘chromedriver’ executable needs to be in PATH. Please see ChromeDriver - WebDriver for Chrome

venv\lib\site-packages\selenium\webdriver\common\service.py:81: WebDriverException
=========================== short test summary info ===========================
FAILED test_selenium.py::test_selenium - selenium.common.exceptions.WebDriver…
============================== 1 failed in 0.41s ==============================

Process finished with exit code 1

Assertion failed

Assertion failed

需要下载chromedriver到你的PATH变量里。

我把下载的路径添加到了path环境变量里了

请问解决了吗?
我的浏览器升级后重新下载的驱动,替换了原来的,也报你这个错了

驱动(chromedriver)不能放在中文路径下