compatible with selenium 4.10.

also removed service_args, service_creationflags, service_log_path from constructor. added find_elements_recursive helper function
This commit is contained in:
UltrafunkAmsterdam 2023-06-12 11:30:57 +02:00
parent ebd3508a03
commit 2b035b4ea1
2 changed files with 56 additions and 28 deletions

View File

@ -41,7 +41,7 @@ setup(
version=version, version=version,
packages=["undetected_chromedriver"], packages=["undetected_chromedriver"],
install_requires=[ install_requires=[
"selenium>=4.0.0", "selenium>=4.9.0",
"requests", "requests",
"websockets", "websockets",
], ],

View File

@ -17,7 +17,7 @@ by UltrafunkAmsterdam (https://github.com/ultrafunkamsterdam)
from __future__ import annotations from __future__ import annotations
__version__ = "3.4.7" __version__ = "3.5.0"
import json import json
import logging import logging
@ -33,7 +33,7 @@ from weakref import finalize
import selenium.webdriver.chrome.service import selenium.webdriver.chrome.service
import selenium.webdriver.chrome.webdriver import selenium.webdriver.chrome.webdriver
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
import selenium.webdriver.common.service import selenium.webdriver.chromium.service
import selenium.webdriver.remote.command import selenium.webdriver.remote.command
import selenium.webdriver.remote.webdriver import selenium.webdriver.remote.webdriver
@ -109,11 +109,11 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
browser_executable_path=None, browser_executable_path=None,
port=0, port=0,
enable_cdp_events=False, enable_cdp_events=False,
service_args=None, # service_args=None,
service_creationflags=None, # service_creationflags=None,
desired_capabilities=None, desired_capabilities=None,
advanced_elements=False, advanced_elements=False,
service_log_path=None, # service_log_path=None,
keep_alive=True, keep_alive=True,
log_level=0, log_level=0,
headless=False, headless=False,
@ -384,11 +384,15 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if headless or options.headless: if headless or options.headless:
#workaround until a better checking is found #workaround until a better checking is found
options.add_argument("--headless=new") try:
#if self.patcher.version_main < 108: if self.patcher.version_main < 108:
# options.add_argument("--headless=chrome") options.add_argument("--headless=chrome")
#elif self.patcher.version_main >= 108: elif self.patcher.version_main >= 108:
options.add_argument("--headless=new")
except:
logger.warning("could not detect version_main."
"therefore, we are assuming it is chrome 108 or higher")
options.add_argument("--headless=new")
options.add_argument("--window-size=1920,1080") options.add_argument("--window-size=1920,1080")
options.add_argument("--start-maximized") options.add_argument("--start-maximized")
@ -441,26 +445,15 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
) )
self.browser_pid = browser.pid self.browser_pid = browser.pid
if service_creationflags:
service = selenium.webdriver.common.service.Service( service = selenium.webdriver.chromium.service.ChromiumService(
self.patcher.executable_path, port, service_args, service_log_path self.patcher.executable_path
) )
for attr_name in ("creationflags", "creation_flags"):
if hasattr(service, attr_name):
setattr(service, attr_name, service_creationflags)
break
else:
service = None
super(Chrome, self).__init__( super(Chrome, self).__init__(
executable_path=self.patcher.executable_path, service=service,
port=port,
options=options, options=options,
service_args=service_args,
desired_capabilities=desired_capabilities,
service_log_path=service_log_path,
keep_alive=keep_alive, keep_alive=keep_alive,
service=service, # needed or the service will be re-created
) )
self.reactor = None self.reactor = None
@ -716,10 +709,45 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if not capabilities: if not capabilities:
capabilities = self.options.to_capabilities() capabilities = self.options.to_capabilities()
super(selenium.webdriver.chrome.webdriver.WebDriver, self).start_session( super(selenium.webdriver.chrome.webdriver.WebDriver, self).start_session(
capabilities, browser_profile capabilities
) )
# super(Chrome, self).start_session(capabilities, browser_profile) # super(Chrome, self).start_session(capabilities, browser_profile)
def find_elements_recursive(self, by, value):
"""
find elements in all frames
this is a generator function, which is needed
since if it would return a list of elements, they
will be stale on arrival.
using generator, when the element is returned we are in the correct frame
to use it directly
Args:
by: By
value: str
Returns: Generator[webelement.WebElement]
"""
def search_frame(f=None):
if not f:
# ensure we are on main content frame
self.switch_to.default_content()
else:
self.switch_to.frame(f)
for elem in self.find_elements(by, value):
yield elem
# switch back to main content, otherwise we will get StaleElementReferenceException
self.switch_to.default_content()
# search root frame
for elem in search_frame():
yield elem
# get iframes
frames = self.find_elements('css selector', 'iframe')
# search per frame
for f in frames:
for elem in search_frame(f):
yield elem
def quit(self): def quit(self):
try: try:
self.service.process.kill() self.service.process.kill()