Skip to content

Commit

Permalink
compatible with selenium 4.10.
Browse files Browse the repository at this point in the history
also removed service_args, service_creationflags, service_log_path from constructor. added find_elements_recursive helper function
  • Loading branch information
UltrafunkAmsterdam committed Jun 12, 2023
1 parent ebd3508 commit 2b035b4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 28 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
version=version,
packages=["undetected_chromedriver"],
install_requires=[
"selenium>=4.0.0",
"selenium>=4.9.0",
"requests",
"websockets",
],
Expand Down
82 changes: 55 additions & 27 deletions undetected_chromedriver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from __future__ import annotations


__version__ = "3.4.7"
__version__ = "3.5.0"

import json
import logging
Expand All @@ -33,7 +33,7 @@
import selenium.webdriver.chrome.service
import selenium.webdriver.chrome.webdriver
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.webdriver

Expand Down Expand Up @@ -109,11 +109,11 @@ def __init__(
browser_executable_path=None,
port=0,
enable_cdp_events=False,
service_args=None,
service_creationflags=None,
# service_args=None,
# service_creationflags=None,
desired_capabilities=None,
advanced_elements=False,
service_log_path=None,
# service_log_path=None,
keep_alive=True,
log_level=0,
headless=False,
Expand Down Expand Up @@ -384,11 +384,15 @@ def __init__(

if headless or options.headless:
#workaround until a better checking is found
options.add_argument("--headless=new")
#if self.patcher.version_main < 108:
# options.add_argument("--headless=chrome")
#elif self.patcher.version_main >= 108:

try:
if self.patcher.version_main < 108:
options.add_argument("--headless=chrome")
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("--start-maximized")
Expand Down Expand Up @@ -441,26 +445,15 @@ def __init__(
)
self.browser_pid = browser.pid

if service_creationflags:
service = selenium.webdriver.common.service.Service(
self.patcher.executable_path, port, service_args, service_log_path
)
for attr_name in ("creationflags", "creation_flags"):
if hasattr(service, attr_name):
setattr(service, attr_name, service_creationflags)
break
else:
service = None

service = selenium.webdriver.chromium.service.ChromiumService(
self.patcher.executable_path
)

super(Chrome, self).__init__(
executable_path=self.patcher.executable_path,
port=port,
service=service,
options=options,
service_args=service_args,
desired_capabilities=desired_capabilities,
service_log_path=service_log_path,
keep_alive=keep_alive,
service=service, # needed or the service will be re-created
)

self.reactor = None
Expand Down Expand Up @@ -716,10 +709,45 @@ def start_session(self, capabilities=None, browser_profile=None):
if not capabilities:
capabilities = self.options.to_capabilities()
super(selenium.webdriver.chrome.webdriver.WebDriver, self).start_session(
capabilities, browser_profile
capabilities
)
# 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):
try:
self.service.process.kill()
Expand Down

0 comments on commit 2b035b4

Please sign in to comment.