Reputation: 233
I'm using chrome driver in Selenium to open chrome , log into a router, press some buttons ,upload configuration etc. all code is written in Python.
here is the part of the code to obtain the driver:
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
when i fire up my app, i get a chromedriver.exe console (a black window) followed by a chrome window opened and all my requests are done.
My question: is there a way in python to hide the console window ?
(as you can see i'm also re-sizing the chrome window ,my preference would be doing things in a way the user wont notice anything happening on screen)
thanks Sivan
Upvotes: 15
Views: 37603
Reputation: 361
service = Service(ChromeDriverManager().install(), log_level='OFF')
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
chrome_options.add_argument("--disable-gpu") # Desabilita o GPU
browser = webdriver.Chrome(service=service, options=chrome_options)
Upvotes: 0
Reputation: 4480
I needed that too, so I implemented and commited this feature on GitHub as part of selenium4 release. We no longer need to edit the selenium library for this.
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')
# Use `chrome_service.creationflags` for selenium < 4.6
chrome_service.creation_flags = CREATE_NO_WINDOW
driver = webdriver.Chrome(service=chrome_service)
Now, command-prompt window does not open up. This is especially useful when you have a GUI desktop app which is responsible for opening selenium browser.
Also, note that we only need to do this in Windows.
Upvotes: 20
Reputation: 1067
For me, the following solution did NOT work.
service = Service(EdgeChromiumDriverManager().install())
service.creationflags = CREATE_NO_WINDOW
driver = webdriver.Edge(options=self.options, service=service)
However, using selenium version 4.5.0 instead of 4.7.0 works like a charm.
Also see Unable to hide Chromedriver console with CREATE_NO_WINDOW
Upvotes: 2
Reputation: 21
Building from the answer by @Ali Sajjad
If you are using pyinstaller to bundle python code with GUI (like tkinter) and still want to hide the chromedriver console that pops out. Be sure to include the relevant path here...
chrome_service = ChromeService('chromedriver')
chrome_service.creationflags = CREATE_NO_WINDOW
The Service object from selenium take in the path of the chromedriver and thus should be replaced with the following..
chrome_service = ChromeService(get_path('relative/path/to/chromedriver'))
Where get_path is a path connector that helps the scripts to find the files. Example of the resource_path function that works for me...
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)
Now, creating an instance would be:
browser = webdriver.Chrome(service=chrome_service, options=options, executable_path=get_path('relative/path/to/chromedriver.exe'))
This should work with pyinstaller.
Upvotes: 2
Reputation: 31
I found the solution to hide the console window when running Chromedriver:
I also got an error when importing CREATE_NO_WINDOW
from win32process
.
To import it without error find the service.py
file in Selenium files (like in Josh O'Brien's reply under this thread). Then instead of importing like this:
from win32process import CREATE_NO_WINDOW
you should instead import it from subprocess:
from subprocess import CREATE_NO_WINDOW
And then just add creationflags=CREATE_NO_WINDOW
in the service.py file code part like this (also like in Josh O'Brien's reply):
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)
And it works nicely for me, also when I used Pyinstaller to compile it to an EXE file.
Upvotes: 3
Reputation: 471
You will have to edit Selenium Source code to achieve this. I am a noob too, and I dont fully understand the overall consequences of editing source code but here is what I did to achieve hiding the webdriver console window on Windows 7, Python 2.7.
Locate and edit this file as follows: located at Lib\site-packages\selenium\webdriver\common\service.py in your Python folder.
Edit the Start() function by adding the creation flags this way: creationflags=CREATE_NO_WINDOW
The edited method will be as below:
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
You will have to add the relevant imports:
from win32process import CREATE_NO_WINDOW
This should also work for Chrome webdriver as they import the same file to start the webdriver process.
Upvotes: 32
Reputation: 20264
There's a lot of questions relating to this and a lot of various answers. The issue is that using Selenium in a Python process without a console window of its own will cause it to launch its drivers (including the chromedriver
) in a new window.
Rather than modifying the Selenium code directly (although this needs to be done eventually) one option you have is to create your own sub-classes for both the Chrome WebDriver
and the Service
class it uses. The Service
class is where Selenium actually calls Popen
to launch the service process, e.g. chromedriver.exe
(as mentioned in the accepted answer):
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
I removed some of the extra comments and doc string goo for brevity. You would then use this custom WebDriver the same way you'd use the official Chrome
one in Selenium:
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()
Finally, if creating a custom WebDriver is not for you and you don't mind a window flickering and disappearing then you can also use the win32gui library to hide the window after starting up:
# 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, [])
Upvotes: 14
Reputation: 296
While launching chrome browser not seeing chromedriver console with the given sample code.
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)
Upvotes: 2