在python中隐藏chromeDriver控制台

时间:2015-11-29 14:23:49

标签: python selenium selenium-chromedriver

我在Selenium中使用chrome驱动程序打开chrome,登录路由器,按下某些按钮,上传配置等等。所有代码都是用Python编写的。

这是获取驱动程序的代码部分:

chrome_options = webdriver.ChromeOptions()
prefs = {"download.default_directory":  self.user_local}
chrome_options.add_experimental_option("prefs", prefs)
chrome_options.experimental_options.
driver = webdriver.Chrome("chromedriver.exe", chrome_options=chrome_options)
driver.set_window_position(0, 0)
driver.set_window_size(0, 0)

return driver

当我启动我的应用程序时,我得到一个chromedriver.exe控制台(黑色窗口),然后打开一个镀铬窗口,我的所有请求都已完成。

我的问题:在python中是否有办法隐藏控制台窗口?

(你可以看到我也在重新调整chrome窗口的大小,我的偏好是用户不会注意到屏幕上发生任何事情的方式)

感谢 斯万

4 个答案:

答案 0 :(得分:8)

您必须编辑Selenium源代码才能实现此目的。我也是菜鸟,我不完全理解编辑源代码的整体后果,但这是我在Windows 7,Python 2.7上隐藏webdriver控制台窗口所做的工作。

找到并编辑此文件,如下所示: 位于 Python文件夹中的 Lib \ site-packages \ selenium \ webdriver \ common \ _ services.py

通过以这种方式添加创建标志来编辑Start()函数: creationflags = CREATE_NO_WINDOW

编辑后的方法如下:

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=platform.system() != 'Windows',
                                        stdout=self.log_file, stderr=self.log_file, creationflags=CREATE_NO_WINDOW)
    except TypeError:
        raise

您必须添加相关导入:

from win32process import CREATE_NO_WINDOW

这也适用于Chrome webdriver,因为它们导入相同的文件以启动webdriver进程。

答案 1 :(得分:2)

与此相关的问题很多,答案也很多。问题在于,在没有自己的控制台窗口的 Python进程中使用Selenium会导致它在新窗口中启动其驱动程序(包括chromedriver)。

您不必选择直接修改Selenium代码(尽管最终需要完成),而是要为Chrome WebDriver和它使用的Service类创建自己的子类。 Selenium实际上在Service类中调用Popen以启动服务过程,例如chromedriver.exe(如已接受的答案所述):

import errno
import os
import platform
import subprocess
import sys
import time
import warnings

from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common import utils
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from selenium.webdriver.chrome import service, webdriver, remote_connection

class HiddenChromeService(service.Service):

    def start(self):
        try:
            cmd = [self.path]
            cmd.extend(self.command_line_args())

            if platform.system() == 'Windows':
                info = subprocess.STARTUPINFO()
                info.dwFlags = subprocess.STARTF_USESHOWWINDOW
                info.wShowWindow = 0  # SW_HIDE (6 == SW_MINIMIZE)
            else:
                info = None

            self.process = subprocess.Popen(
                cmd, env=self.env,
                close_fds=platform.system() != 'Windows',
                startupinfo=info,
                stdout=self.log_file,
                stderr=self.log_file,
                stdin=subprocess.PIPE)
        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)
                )
            elif err.errno == errno.EACCES:
                raise WebDriverException(
                    "'%s' executable may have wrong permissions. %s" % (
                        os.path.basename(self.path), self.start_error_message)
                )
            else:
                raise
        except Exception as e:
            raise WebDriverException(
                "Executable %s must be in path. %s\n%s" % (
                    os.path.basename(self.path), self.start_error_message,
                    str(e)))
        count = 0
        while True:
            self.assert_process_still_running()
            if self.is_connectable():
                break
            count += 1
            time.sleep(1)
            if count == 30:
                raise WebDriverException("Can't connect to the Service %s" % (
                    self.path,))


class HiddenChromeWebDriver(webdriver.WebDriver):
    def __init__(self, executable_path="chromedriver", port=0,
                options=None, service_args=None,
                desired_capabilities=None, service_log_path=None,
                chrome_options=None, keep_alive=True):
        if chrome_options:
            warnings.warn('use options instead of chrome_options',
                        DeprecationWarning, stacklevel=2)
            options = chrome_options

        if options is None:
            # desired_capabilities stays as passed in
            if desired_capabilities is None:
                desired_capabilities = self.create_options().to_capabilities()
        else:
            if desired_capabilities is None:
                desired_capabilities = options.to_capabilities()
            else:
                desired_capabilities.update(options.to_capabilities())

        self.service = HiddenChromeService(
            executable_path,
            port=port,
            service_args=service_args,
            log_path=service_log_path)
        self.service.start()

        try:
            RemoteWebDriver.__init__(
                self,
                command_executor=remote_connection.ChromeRemoteConnection(
                    remote_server_addr=self.service.service_url,
                    keep_alive=keep_alive),
                desired_capabilities=desired_capabilities)
        except Exception:
            self.quit()
            raise
        self._is_remote = False

为简洁起见,我删除了一些额外的注释和文档字符串goo。然后,您将以与在Selenium中使用官方Chrome相同的方式使用此自定义WebDriver:

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('headless')
headless_chrome = HiddenChromeWebDriver(chrome_options=options)

headless_chrome.get('http://www.example.com/')

headless_chrome.quit()

最后,如果您不适合创建自定义WebDriver,并且您不介意窗口闪烁或消失,那么您也可以在启动后使用win32gui library隐藏窗口:

# hide chromedriver console on Windows
def enumWindowFunc(hwnd, windowList):
    """ win32gui.EnumWindows() callback """
    text = win32gui.GetWindowText(hwnd)
    className = win32gui.GetClassName(hwnd)
    if 'chromedriver' in text.lower() or 'chromedriver' in className.lower():
        win32gui.ShowWindow(hwnd, False)
win32gui.EnumWindows(enumWindowFunc, [])

答案 2 :(得分:0)

启动chrome浏览器时看不到带有给定示例代码的chromedriver控制台。

{{1}}

答案 3 :(得分:0)

我找到了在运行 Chromedriver 时隐藏控制台窗口的解决方案:

CREATE_NO_WINDOW 导入 win32process 时也出现错误。 要正确导入它,请在 Selenium 文件中找到 service.py 文件(如 Josh O'Brien 在此线程下的回复)。然后,而不是像这样导入:

from win32process import CREATE_NO_WINDOW

你应该从子进程中导入它:

from subprocess import CREATE_NO_WINDOW

然后像这样在 service.py 文件代码部分添加 creationflags=CREATE_NO_WINDOW(也像 Josh O'Brien 的回复):

            self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=platform.system() != 'Windows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                        stdin=PIPE, creationflags=CREATE_NO_WINDOW)

它对我来说效果很好,当我使用 Pyinstaller 将其编译为 EXE 文件时也是如此。