简体   繁体   中英

How to hide geckodriver console window?

I'm running Selenium 3.141.0 with python 3.6.7 on windows 10

My script runs the Firefox driver in headless, however a console window from geckodriver still pops up.

from selenium import webdriver

options = webdriver.FirefoxOptions()
options.add_argument('-headless')
driver = webdriver.Firefox(executable_path=r'c:\webdrivers\geckodriver.exe', log_path='C:\webdrivers\geckodriver.log', firefox_options=options)
driver.get('http://10.0.0.102/')

element = WebDriverWait(driver, 20).until(
    EC.presence_of_element_located((By.ID, "body-home-tile-pgDevServ"))
)
button = driver.find_element_by_id('body-home-tile-pgDevServ')
button.click()
element = WebDriverWait(driver, 20).until(
    EC.presence_of_element_located((By.ID, "devserv-printQ-Inp"))
)
button = driver.find_element_by_id('devserv-printQ-Inp')
button.click()

I hacked the selenium lib, change the code in, \\AppData\\Roaming\\Python\\Python38\\site-packages\\selenium\\webdriver\\common\\service.py line 72 and below,

the original codes as:

        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,
                                        stdin=PIPE)

and add two more lines, like this

        try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
        CREATE_NO_WINDOW = 0x08000000
        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,
                                        stdin=PIPE)

It works for windows.

I found a way, based on the solution by Anguo Zhao, to solve this without editing the selenium file itself, by monkey-patching it into the imported selenium module:

import functools

from selenium import webdriver

flag = 0x08000000  # No-Window flag
# flag = 0x00000008  # Detached-Process flag, if first doesn't work
webdriver.common.service.subprocess.Popen = functools.partial(
    webdriver.common.service.subprocess.Popen, creationflags=flag)

If you think that this might be executed more than once:

import functools
import subprocess

from selenium import webdriver

flag = 0x08000000  # No-Window flag
webdriver.common.service.subprocess.Popen = functools.partial(
    subprocess.Popen, creationflags=flag)

I couldn't find a place in the selenium module where it would use creationflags by itself, so that shouldn't break anything (as of now).

Natural Language Explanation:

With functools.partial , we create a "prepared" Popen -call that has the creationflags -argument already with it.
Then, we replace the original Popen that selenium tries to call with that prepared one.
Voilà, whenever something in selenium.webdriver.common.service tries to create a Popen -object, it will be the one that has been prepared with the creationflag.

After some messing around it seems like adding options.add_argument('--disable-gpu') fixes it (sometimes).

Running the script from vscode works, running the script with windows task scheduler works. Running from powershell or cmd does not work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM