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:
parent
ebd3508a03
commit
2b035b4ea1
2
setup.py
2
setup.py
|
@ -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",
|
||||||
],
|
],
|
||||||
|
|
|
@ -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
|
||||||
|
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("--headless=new")
|
||||||
#if self.patcher.version_main < 108:
|
|
||||||
# options.add_argument("--headless=chrome")
|
|
||||||
#elif self.patcher.version_main >= 108:
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
||||||
|
|
Loading…
Reference in New Issue