This code is working just fine:
class example:
def __init__(self) -> None:
remote_debug_port=8956
options = webdriver.ChromeOptions()
options.add_argument(f'--remote-debugging-port={remote_debug_port}')
options.add_argument("--start-maximized")
options.add_argument('--no-sandbox')
options.add_argument('--headless')
options.add_argument('--disable-infobars')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome("/usr/bin/chromedriver", options=options)
a = example()
create webdriver inside an Abstract class, then create an child class.
from abc import ABC, abstractmethod
from selenium import webdriver
class ChromeDriverBase(ABC):
def __init__(self, url_source:str,
webdriver_path:str="/usr/bin/chromedriver",
wait_time:int=10,
remote_port:int=2345) -> None:
self.url_source = url_source
self.wait_time = wait_time
self.remote_port = remote_port
self.create_options()
self.driver = webdriver.Chrome(webdriver_path, options=self.options)
def create_options(self):
self.options = webdriver.ChromeOptions()
self.options.add_argument(f'--remote-debugging-port={self.remote_port}')
self.options.add_argument("--start-maximized")
self.options.add_argument('--no-sandbox')
self.options.add_argument('--headless')
self.options.add_argument('--disable-infobars')
self.options.add_argument('--disable-dev-shm-usage')
#abstractmethod
def function1(self):
pass
class ChromeChild(ChromeDriverBase):
def __init__(self, url_source: str, wait_time: int = 10, remote_port: int = 2345) -> None:
super().__init__(url_source=url_source, wait_time=wait_time, remote_port=remote_port)
def function1(self):
# just for illustration
return self.url_source
a = ChromeChild(url_source='www.google.com')
# this trigger this error
selenium.common.exceptions.SessionNotCreatedException: Message: session not
created: This version of ChromeDriver only supports Chrome version 109
Current browser version is 103.0.5060.114 with binary path /usr/bin/google-chrome
I checked the version:
Google Chrome 109.0.5414.119
ChromeDriver 109.0.5414.74
Your output log states:
selenium.common.exceptions.SessionNotCreatedException: Message: session not
created: This version of ChromeDriver only supports Chrome version 109
Current browser version is 103.0.5060.114 with binary path /usr/bin/google-chrome
First, please check your local chrome version from the path /usr/bin/google-chrome and not the local installation. Then,
You have two options:
Use chromedriver for Chrome 103 or
Install Chrome 109
I would recommend you to update your chrome broswer to version 109 unless its a fixed requirement. In that case, downgrade chromedriver version
Related
I'm having troubles to debug why is firefox not working in headless mode. This is how I create the drivers:
def __get_firefox_options(headless=True) -> webdriver.FirefoxOptions:
"""
Get Firefox configuration
"""
options=webdriver.FirefoxOptions()
if headless == True:
options.headless = True
options.add_argument("window-size=1920x1080")
options.add_argument("--start-maximized")
options.add_argument("--disable-gpu")
return options
def __get_firefox_driver(drivers_path, headless) -> webdriver.Firefox:
"""
Return an instance of the geckodriver
"""
driver_path = os.path.join(drivers_path, 'geckodriver.exe')
service = FirefoxService(driver_path)
driver = webdriver.Firefox(
service=service,
options=__get_firefox_options(headless=headless)
)
driver.maximize_window()
return driver
And chrome:
def __get_chrome_options(headless=False) -> webdriver.ChromeOptions:
"""
Get chrome setup to allow self signed certificates
"""
options = webdriver.ChromeOptions()
if headless == True:
options.headless = True
options.add_argument("window-size=1920x1080")
options.add_argument('ignore-certificate-errors')
options.add_argument("--start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-logging"]) # Disable logging
return options
def __get_chrome_driver(drivers_path, headless) -> webdriver.Chrome:
"""
Return an instance of the chromedriver
"""
driver_path = os.path.join(drivers_path, 'chromedriver.exe')
service = ChromeService(driver_path)
return webdriver.Chrome(
service=service,
options=__get_chrome_options(headless)
)
Now I want to find a login element:
from loguru import logger
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
def access_login_page(driver: webdriver.Chrome or webdriver.Firefox) -> None:
"""
Access the login page using the header menu
"""
ELEMENT_ID = 'header-sign-in'
try:
element: WebElement = WebDriverWait(driver, timeout=30).until(
EC.element_to_be_clickable((By.ID, ELEMENT_ID))
)
element.click()
except TimeoutException:
logger.error(f'Element "{ELEMENT_ID}" could not be found')
So this small piece of code works in chrome, chrome headless and firefox, but not in firefox headless.
Before I was having an element not interactable exception, therefore I changed it to element_to_be_clickable, but not it justs is stucked there and ends up with the TimeoutException.
I am not able to debug it because in the non headless mode it works, how can I try to fix this? What can be different in the configuration of firefox when the headless proeperty is used?
If it helps to get an idea, this is how the DOM looks like:
After minimizing the code to write this question I found the issue. The page has a responsive mode where the button I am using gets hidden at a certian screen size.
It seems taht in headless mode firefox takes a different resolution for driver.maximize_window() than running it in my full hd monitor not headless. Thereofre my monitor would return:
{'width': 1920, 'height': 1080}
while in headless mode:
{'width': 1366, 'height': 768}
Therefore I changed the following in the driver creation function:
if headless:
driver.set_window_size(1920, 1080)
else:
driver.maximize_window()
On the other hand I had to add this option driver.maximize_window() because the options options.add_argument("window-size=1920x1080") where not working out of the box for my firefox 96.0.3 (64-bit).
I have a class for Selenium parser:
class DynamicParser(Parser):
"""Selenium Parser with processing JS"""
driver: Chrome = None
def __init__(self, driver_path='./chromedriver', headless=True):
chrome_options = Options()
if headless:
chrome_options.add_argument("--headless")
chrome_options.add_argument("window-size=1920,1080")
# bypass OS security
chrome_options.add_argument('--no-sandbox')
# overcome limited resources
chrome_options.add_argument('--disable-dev-shm-usage')
# don't tell chrome that it is automated
chrome_options.add_experimental_option(
"excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# disable images
prefs = {"profile.managed_default_content_settings.images": 2}
chrome_options.add_experimental_option("prefs", prefs)
# Setting Capabilities
capabilities = DesiredCapabilities.CHROME.copy()
capabilities['acceptSslCerts'] = True
capabilities['acceptInsecureCerts'] = True
self.driver = Chrome(chrome_options=chrome_options,
executable_path=driver_path, desired_capabilities=capabilities)
def goto(self, url: str):
"""Goes to specified URL"""
self.driver.get(url)
def get_seller_name(self) -> str:
"""Returns seller's name"""
offer_actions_tag = self.driver.find_element_by_class_name(
'offer-user__actions')
profile_link_tag = offer_actions_tag.find_element_by_tag_name('a')
return profile_link_tag.text.strip()
Also I have a test script, which creates DynamicParser, goes to some page and calls .get_seller_name().
I noticed that when I run Chromedriver headless, it runs much slower, so i tested it using time python3 test.py.
Output for headless chrome:
python3 test.py 2,98s user 0,94s system 3% cpu 2:04,65 total
Output for non-headless chrome:
python3 test.py 1,48s user 0,33s system 47% cpu 3,790 total
As we can see, headless chrome runs almost 33 times slower!
Chrome version: 83.0.4103.116
Chromedriver version: 83.0.4103.39
I don't really understand what's the problem. When I developed my previous application, headless chrome worked fast enough.
Just found the problem. It was
chrome_options.add_argument('--disable-dev-shm-usage')
I supposed that it should have unlimit chrome resources, but it definitely doesn't work in this case.
When running headless driver you can also use those settings for the performance improvement.
browser_options = webdriver.ChromeOptions()
browser_options.headless = True
image_preferences = {"profile.managed_default_content_settings.images": 2}
browser_options.add_experimental_option("prefs", image_preferences)
I have this code below and it throw the SessionNotCreatedException on the last line.
chrome_options = Options()
LANG = 'fr,fr_FR'
chrome_options.add_experimental_option('prefs', {'intl.accept_languages': LANG})
chrome_options.add_argument("--user-data-dir=chrome-data")
browser = webdriver.Chrome(options=chrome_options)
SessionNotCreatedException: session not created: This version of ChromeDriver only supports Chrome version 80
However, I am already using version 80 ! Downloaded here : https://chromedriver.storage.googleapis.com/index.html?path=80.0.3987.106/
Alternative which worked : SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81
However, the silent log mode doesn't work...
os.environ['WDM_LOG_LEVEL'] = '0'
I got some code together that lets me view the mobile version of Instagram, but whenever I try to put the code into a class and run the class, it fails. I have one Class for writing my methods, and another Class for calling the methods. When I run the second class, the chromedriver will open chrome, but it won't call the instagram URL.
this is the code that works
from selenium import webdriver
mobile_emulation = { "deviceName": "iPhone X" }
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("mobileEmulation",
mobile_emulation)
driver = webdriver.Chrome(executable_path='/Users/~~/chromedriver', chrome_options=chrome_options)
driver.get("https://instagram.com/")
I tried making a class to hold the code like this
from selenium import webdriver
mobile_emulation = {"deviceName": "iPhone X"}
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("mobileEmulation",
mobile_emulation)
driver = webdriver.Chrome(executable_path='/Users/~~/chromedriver',
chrome_options=chrome_options)
class IGFrame:
def __init__(self, driver):
self.driver = driver
def open_ig(self):
self.driver.get("https://instagram.com/")
time.sleep(2)
and then this was the class to call the method
from version1.pages.basic_methods import *
class TestSetUp:
def __init__(self, driver):
self.driver = driver
def test_mobileViewOfIG(self):
methods = IGFrame(self.driver)
methods.open_ig()
What I was aiming for was to have the driver setup and the method to call the URL in the IGFrame class, and then I would call the method from the TestSetUp class. What am I doing wrong and what should I do?
I am running this code with python, selenium, and firefox but still get 'head' version of firefox:
binary = FirefoxBinary('C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe', log_file=sys.stdout)
binary.add_command_line_options('-headless')
self.driver = webdriver.Firefox(firefox_binary=binary)
I also tried some variations of binary:
binary = FirefoxBinary('C:\\Program Files\\Nightly\\firefox.exe', log_file=sys.stdout)
binary.add_command_line_options("--headless")
To invoke Firefox Browser headlessly, you can set the headless property through Options() class as follows:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.headless = True
driver = webdriver.Firefox(options=options, executable_path=r'C:\Utility\BrowserDrivers\geckodriver.exe')
driver.get("http://google.com/")
print ("Headless Firefox Initialized")
driver.quit()
There's another way to accomplish headless mode. If you need to disable or enable the headless mode in Firefox, without changing the code, you can set the environment variable MOZ_HEADLESS to whatever if you want Firefox to run headless, or don't set it at all.
This is very useful when you are using for example continuous integration and you want to run the functional tests in the server but still be able to run the tests in normal mode in your PC.
$ MOZ_HEADLESS=1 python manage.py test # testing example in Django with headless Firefox
or
$ export MOZ_HEADLESS=1 # this way you only have to set it once
$ python manage.py test functional/tests/directory
$ unset MOZ_HEADLESS # if you want to disable headless mode
Steps through YouTube Video
Mozilla Firefox in Headless Mode through Selenium 3.5.2 (Java)
Login into Gmail Account using Headless Chrome through Selenium Java
Outro
How to configure ChromeDriver to initiate Chrome browser in Headless mode through Selenium?
The first answer does't work anymore.
This worked for me:
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium import webdriver
options = FirefoxOptions()
options.add_argument("--headless")
driver = webdriver.Firefox(options=options)
driver.get("http://google.com")
My answer:
set_headless(headless=True) is deprecated.
https://seleniumhq.github.io/selenium/docs/api/py/webdriver_firefox/selenium.webdriver.firefox.options.html
options.headless = True
works for me
Used below code to set driver type based on need of Headless / Head for both Firefox and chrome:
// Can pass browser type
if brower.lower() == 'chrome':
driver = webdriver.Chrome('..\drivers\chromedriver')
elif brower.lower() == 'headless chrome':
ch_Options = Options()
ch_Options.add_argument('--headless')
ch_Options.add_argument("--disable-gpu")
driver = webdriver.Chrome('..\drivers\chromedriver',options=ch_Options)
elif brower.lower() == 'firefox':
driver = webdriver.Firefox(executable_path=r'..\drivers\geckodriver.exe')
elif brower.lower() == 'headless firefox':
ff_option = FFOption()
ff_option.add_argument('--headless')
ff_option.add_argument("--disable-gpu")
driver = webdriver.Firefox(executable_path=r'..\drivers\geckodriver.exe', options=ff_option)
elif brower.lower() == 'ie':
driver = webdriver.Ie('..\drivers\IEDriverServer')
else:
raise Exception('Invalid Browser Type')
To the OP or anyone currently interested, here's the section of code that's worked for me with firefox currently:
opt = webdriver.FirefoxOptions()
opt.add_argument('-headless')
ffox_driver = webdriver.Firefox(executable_path='\path\to\geckodriver', options=opt)
from selenium.webdriver.firefox.options import Options
if __name__ == "__main__":
options = Options()
options.add_argument('-headless')
driver = Firefox(executable_path='geckodriver', firefox_options=options)
wait = WebDriverWait(driver, timeout=10)
driver.get('http://www.google.com')
Tested, works as expected and this is from Official - Headless Mode | Mozilla
Nowadays with this code:
options = Options()
options.headless = True
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install(),options=options)
We have a warning:
DeprecationWarning: executable_path has been deprecated, please pass in a Service object
Changing to this one, works perfectly:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# selenium drivers: https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/
# pip3 install selenium
# pip3 install webdriver-manager
# for custom firefox installation: link firefox to /usr/bin/firefox, example: ln -s /opt/firefox/firefox-bin /usr/bin/firefox
from selenium import webdriver
from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
options = Options()
options.headless = True
service = Service(executable_path=GeckoDriverManager().install())
driver = webdriver.Firefox(service=service, options=options)
driver.get("http://google.com/")
print("Headless Firefox Initialized")
driver.quit()