selenium 在Python中隐藏chromeDriver控制台

oo7oh9g9  于 2022-11-24  发布在  Python
关注(0)|答案(6)|浏览(363)

我在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

当我启动我的应用程序时,我会得到一个chromedriveriderexe控制台(一个黑色窗口),然后打开一个chrome窗口,我所有的请求都完成了。

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

(as你可以看到,我也调整了chrome窗口的大小,我的偏好是以一种用户不会注意到屏幕上发生的任何事情的方式来做事情)
谢谢你,Sivan

hs1ihplo

hs1ihplo1#

你将不得不编辑Selenium源代码来实现这一点。我也是一个菜鸟,我不完全理解编辑源代码的整体后果,但这里是我所做的,以实现隐藏webdriver控制台窗口在Windows 7,Python 2. 7。
按如下所示查找并编辑此文件:位于Python文件夹中的Lib\site-packages\selenium\webdriver\common\service.py
通过以下方式添加创建标志来编辑Start()函数:创建标志=创建_无_窗口
编辑的方法如下:

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进程。

ca1c2owp

ca1c2owp2#

有很多问题与此相关,也有很多不同的答案。问题是,在Python进程中使用Selenium * 而没有 * 自己的控制台窗口,会导致它在一个新窗口中启动它的驱动程序(包括chromedriver)。
除了直接修改Selenium代码(尽管这最终还是需要完成),还有一种选择是为Chrome WebDriver和它使用的Service类创建自己的子类。Service类是Selenium实际调用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

为了简洁起见,我删除了一些额外的注解和doc字符串goo。然后,您可以使用这个自定义的WebDriver,就像在Selenium中使用官方的Chrome一样:

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, [])
dsekswqp

dsekswqp3#

新的简单解决方案!( selenium 4)

我们不再需要为此编辑selenium库。我实现了这个特性,它现在是selenium 4版本的一部分。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService # Similar thing for firefox also!
from subprocess import CREATE_NO_WINDOW # This flag will only be available in windows

# Define your own service object with the `CREATE_NO_WINDOW ` flag
# If chromedriver.exe is not in PATH, then use:
# ChromeService('/path/to/chromedriver')
chrome_service = ChromeService('chromedriver')
chrome_service.creationflags = CREATE_NO_WINDOW

driver = webdriver.Chrome(service=chrome_service)

现在,命令提示符窗口没有打开。当你有一个负责打开selenium浏览器的GUI桌面应用程序时,这特别有用。
另外,请注意,我们只需要在Windows中执行此操作。

lb3vh1jj

lb3vh1jj4#

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

from selenium import webdriver
from selenium.webdriver.chrome.options import Options 
from time import sleep
options = webdriver.ChromeOptions()
prefs = {"download.default_directory":  r"C:\New_Download"}
options.add_experimental_option("prefs", prefs)
print(options.experimental_options)

chromeDriverPath = r'C:\drivers\chromedriver.exe'
driver = webdriver.Chrome(chromeDriverPath,chrome_options=options)
driver.get("http://google.com")
driver.set_window_position(0, 0)
driver.set_window_size(0, 0)
daolsyd0

daolsyd05#

我找到了在运行Chromedriver时隐藏控制台窗口的解决方案:
我在从win32process导入CREATE_NO_WINDOW时也遇到了一个错误。要想导入它而不出错,请在Selenium文件中找到service.py文件(就像Josh奥布莱恩在此线程下的回复)。然后,不要像这样导入:

from win32process import CREATE_NO_WINDOW

您应该改为从子进程导入它:

from subprocess import CREATE_NO_WINDOW

然后在service.py文件的代码部分添加creationflags=CREATE_NO_WINDOW,如下所示(Josh奥布莱恩的回复也是如此):

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文件时也是如此。

gg0vcinb

gg0vcinb6#

selenium 〉4 Pyinstaller溶液

从@Ali Sajjad的答案开始建设
如果你正在使用pyinstaller捆绑python代码和GUI(比如tkinter),并且仍然想隐藏弹出的chromedriver控制台,请确保在这里包含相关路径...

chrome_service = ChromeService('chromedriver')
    chrome_service.creationflags = CREATE_NO_WINDOW

selenium中的Service object占用chromedriver的路径,因此应替换为以下内容。

chrome_service = ChromeService(get_path('relative/path/to/chromedriver'))

其中get_path是一个路径连接器,它帮助脚本查找文件。

def get_path(relative_path):
        """ Get the absolute path to the resource, works for dev and for PyInstaller """
        try:
           # PyInstaller creates a temp folder and stores path in _MEIPASS
           base_path = sys._MEIPASS
        except Exception:
           base_path = os.path.abspath(".")
        return os.path.join(base_path, relative_path)

现在,创建示例的过程如下:

browser = webdriver.Chrome(service=chrome_service, options=options, executable_path=get_path('relative/path/to/chromedriver.exe'))

这应该可以与pyinstaller一起使用。

相关问题