Skip to content

Commit 8c53566

Browse files
committed
Update CDP Mode
1 parent e456f89 commit 8c53566

File tree

7 files changed

+170
-154
lines changed

7 files changed

+170
-154
lines changed

seleniumbase/core/browser_launcher.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,14 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
938938
driver.solve_captcha = CDPM.solve_captcha
939939
driver.find_element_by_text = CDPM.find_element_by_text
940940
driver._is_using_cdp = True
941+
if (
942+
hasattr(sb_config, "_cdp_proxy")
943+
and sb_config._cdp_proxy
944+
and "@" in sb_config._cdp_proxy
945+
):
946+
time.sleep(0.077)
947+
loop.run_until_complete(page.wait(0.25))
948+
time.sleep(0.022)
941949

942950

943951
def uc_activate_cdp_mode(driver, url=None, **kwargs):
@@ -2746,7 +2754,7 @@ def _set_chrome_options(
27462754
d_f_string = ",".join(included_disabled_features)
27472755
chrome_options.add_argument("--disable-features=%s" % d_f_string)
27482756
chrome_options.add_argument("--enable-unsafe-extension-debugging")
2749-
if proxy_auth:
2757+
if proxy_string:
27502758
chrome_options.add_argument("--test-type")
27512759
if proxy_auth or sb_config._ext_dirs:
27522760
if not is_using_uc(undetectable, browser_name):
@@ -2770,7 +2778,7 @@ def _set_chrome_options(
27702778
chrome_options.add_argument("--disable-popup-blocking")
27712779
# Skip remaining options that trigger anti-bot services
27722780
return chrome_options
2773-
if not proxy_auth:
2781+
if not proxy_string:
27742782
chrome_options.add_argument("--test-type")
27752783
chrome_options.add_argument("--log-level=3")
27762784
chrome_options.add_argument("--no-first-run")
@@ -5812,6 +5820,7 @@ def get_local_driver(
58125820
driver, *args, **kwargs
58135821
)
58145822
)
5823+
driver.activate_cdp_mode = driver.uc_activate_cdp_mode
58155824
driver.uc_open_with_cdp_mode = (
58165825
lambda *args, **kwargs: uc_open_with_cdp_mode(
58175826
driver, *args, **kwargs

seleniumbase/core/sb_cdp.py

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,7 +1823,11 @@ def _on_a_cf_turnstile_page(self, source=None):
18231823
time.sleep(0.2)
18241824
source = self.get_page_source()
18251825
if (
1826-
'data-callback="onCaptchaSuccess"' in source
1826+
(
1827+
'data-callback="onCaptchaSuccess"' in source
1828+
and not 'title="reCAPTCHA"' in source
1829+
and not 'id="recaptcha-token" in source'
1830+
)
18271831
or "/challenge-platform/scripts/" in source
18281832
or 'id="challenge-widget-' in source
18291833
or "challenges.cloudf" in source
@@ -1836,13 +1840,19 @@ def _on_a_g_recaptcha_page(self, source=None):
18361840
if not source or len(source) < 400:
18371841
time.sleep(0.2)
18381842
source = self.get_page_source()
1843+
self.loop.run_until_complete(self.page.wait(0.1))
18391844
if (
1840-
'id="recaptcha-token"' in source
1841-
or 'title="reCAPTCHA"' in source
1845+
(
1846+
'id="recaptcha-token"' in source
1847+
or 'title="reCAPTCHA"' in source
1848+
)
1849+
and self.is_element_visible('iframe[title="reCAPTCHA"]')
18421850
):
1851+
self.loop.run_until_complete(self.page.wait(0.1))
18431852
return True
18441853
elif "/recaptcha/api.js" in source:
18451854
time.sleep(1.6) # Still loading
1855+
self.loop.run_until_complete(self.page.wait(0.1))
18461856
return True
18471857
return False
18481858

@@ -1852,8 +1862,10 @@ def __gui_click_recaptcha(self, use_cdp=False):
18521862
selector = 'iframe[title="reCAPTCHA"]'
18531863
else:
18541864
return
1865+
time.sleep(0.25)
1866+
self.loop.run_until_complete(self.page.wait())
1867+
time.sleep(0.25)
18551868
with suppress(Exception):
1856-
time.sleep(0.08)
18571869
element_rect = self.get_gui_element_rect(selector, timeout=1)
18581870
e_x = element_rect["x"]
18591871
e_y = element_rect["y"]
@@ -1884,7 +1896,9 @@ def gui_click_captcha(self):
18841896

18851897
def __click_captcha(self, use_cdp=False):
18861898
"""Uses PyAutoGUI unless use_cdp == True"""
1887-
self.sleep(0.056)
1899+
self.sleep(0.075)
1900+
self.loop.run_until_complete(self.page.wait())
1901+
self.sleep(0.025)
18881902
source = self.get_page_source()
18891903
if self._on_a_cf_turnstile_page(source):
18901904
pass
@@ -1894,61 +1908,32 @@ def __click_captcha(self, use_cdp=False):
18941908
else:
18951909
return
18961910
selector = None
1897-
if (
1898-
self.is_element_present('[name*="cf-turnstile-"]')
1899-
and self.is_element_present("#challenge-form div > div")
1900-
):
1911+
if self.is_element_present('[class="cf-turnstile"]'):
1912+
selector = '[class="cf-turnstile"]'
1913+
elif self.is_element_present("#challenge-form div > div"):
19011914
selector = "#challenge-form div > div"
1902-
elif (
1903-
self.is_element_present('[name*="cf-turnstile-"]')
1904-
and self.is_element_present(
1905-
'[style="display: grid;"] div div'
1906-
)
1907-
):
1915+
elif self.is_element_present('[style="display: grid;"] div div'):
19081916
selector = '[style="display: grid;"] div div'
1909-
elif (
1910-
self.is_element_present('[name*="cf-turnstile-"]')
1911-
and self.is_element_present("[class*=spacer] + div div")
1912-
):
1917+
elif self.is_element_present("[class*=spacer] + div div"):
19131918
selector = '[class*=spacer] + div div'
1914-
elif (
1915-
self.is_element_present('[name*="cf-turnstile-"]')
1916-
and self.is_element_present(".spacer div:not([class])")
1917-
):
1919+
elif self.is_element_present(".spacer div:not([class])"):
19181920
selector = ".spacer div:not([class])"
1919-
elif (
1920-
self.is_element_present('script[src*="challenges.c"]')
1921-
and self.is_element_present(
1922-
'[data-testid*="challenge-"] div'
1923-
)
1924-
):
1921+
elif self.is_element_present('[data-testid*="challenge-"] div'):
19251922
selector = '[data-testid*="challenge-"] div'
1926-
elif self.is_element_present(
1927-
"div#turnstile-widget div:not([class])"
1928-
):
1923+
elif self.is_element_present("div#turnstile-widget div:not([class])"):
19291924
selector = "div#turnstile-widget div:not([class])"
19301925
elif self.is_element_present("ngx-turnstile div:not([class])"):
19311926
selector = "ngx-turnstile div:not([class])"
19321927
elif self.is_element_present(
19331928
'form div:not([class]):has(input[name*="cf-turn"])'
19341929
):
19351930
selector = 'form div:not([class]):has(input[name*="cf-turn"])'
1936-
elif (
1937-
self.is_element_present('[src*="/turnstile/"]')
1938-
and self.is_element_present("form div:not(:has(*))")
1939-
):
1931+
elif self.is_element_present("form div:not(:has(*))"):
19401932
selector = "form div:not(:has(*))"
1941-
elif (
1942-
self.is_element_present('[src*="/turnstile/"]')
1943-
and self.is_element_present(
1944-
"body > div#check > div:not([class])"
1945-
)
1946-
):
1933+
elif self.is_element_present("body > div#check > div:not([class])"):
19471934
selector = "body > div#check > div:not([class])"
19481935
elif self.is_element_present(".cf-turnstile-wrapper"):
19491936
selector = ".cf-turnstile-wrapper"
1950-
elif self.is_element_present('[class="cf-turnstile"]'):
1951-
selector = '[class="cf-turnstile"]'
19521937
elif self.is_element_present(
19531938
'[id*="turnstile"] div:not([class])'
19541939
):
@@ -2048,7 +2033,7 @@ def __click_captcha(self, use_cdp=False):
20482033
self.loop.run_until_complete(self.page.evaluate(script))
20492034
self.loop.run_until_complete(self.page.wait())
20502035
with suppress(Exception):
2051-
time.sleep(0.08)
2036+
time.sleep(0.05)
20522037
element_rect = self.get_gui_element_rect(selector, timeout=1)
20532038
e_x = element_rect["x"]
20542039
e_y = element_rect["y"]
@@ -2059,15 +2044,17 @@ def __click_captcha(self, use_cdp=False):
20592044
x = e_x + x_offset
20602045
y = e_y + y_offset
20612046
sb_config._saved_cf_x_y = (x, y)
2062-
time.sleep(0.08)
2047+
time.sleep(0.05)
2048+
if hasattr(sb_config, "_cdp_proxy") and sb_config._cdp_proxy:
2049+
time.sleep(0.22) # CAPTCHA may load slower with proxy
20632050
if use_cdp:
20642051
self.sleep(0.03)
20652052
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
20662053
with gui_lock: # Prevent issues with multiple processes
20672054
self.bring_active_window_to_front()
2068-
time.sleep(0.056)
2055+
time.sleep(0.05)
20692056
self.click_with_offset(selector, x_offset, y_offset)
2070-
time.sleep(0.056)
2057+
time.sleep(0.05)
20712058
else:
20722059
self.gui_click_x_y(x, y)
20732060

seleniumbase/fixtures/base_case.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,28 @@ def open(self, url):
227227
if self.__is_cdp_swap_needed():
228228
self.cdp.open(url)
229229
return
230+
elif (
231+
hasattr(self.driver, "_is_using_uc")
232+
and self.driver._is_using_uc
233+
and "@" in self.proxy_string
234+
and (
235+
not hasattr(self.driver, "_is_using_cdp")
236+
or not self.driver._is_using_cdp
237+
)
238+
):
239+
# Auth in UC Mode requires CDP Mode
240+
logging.info("UC Mode requires CDP Mode for auth. Activating now.")
241+
self.activate_cdp_mode(url)
242+
return
243+
elif (
244+
hasattr(self.driver, "_is_using_uc")
245+
and self.driver._is_using_uc
246+
and hasattr(self.driver, "_is_using_cdp")
247+
and self.driver._is_using_cdp
248+
):
249+
self.disconnect()
250+
self.cdp.open(url)
251+
return
230252
self._check_browser()
231253
if self.__needs_minimum_wait():
232254
time.sleep(0.04)
@@ -5005,7 +5027,7 @@ def activate_cdp_mode(self, url=None, **kwargs):
50055027
self.driver.connect()
50065028
current_url = self.get_current_url()
50075029
if not current_url.startswith(("about", "data", "chrome")):
5008-
self.open("about:blank")
5030+
self.driver.get("about:blank")
50095031
self.driver.uc_open_with_cdp_mode(url, **kwargs)
50105032
else:
50115033
self.get_new_driver(undetectable=True)
@@ -5015,6 +5037,13 @@ def activate_cdp_mode(self, url=None, **kwargs):
50155037
self.solve_captcha = self.cdp.solve_captcha
50165038
if hasattr(self.cdp, "find_element_by_text"):
50175039
self.find_element_by_text = self.cdp.find_element_by_text
5040+
if (
5041+
hasattr(sb_config, "_cdp_proxy")
5042+
and sb_config._cdp_proxy
5043+
and "@" in sb_config._cdp_proxy
5044+
):
5045+
with suppress(Exception):
5046+
self.cdp.loop.run_until_complete(self.cdp.page.wait(0.25))
50185047
self.undetectable = True
50195048

50205049
def activate_recorder(self):
@@ -14527,7 +14556,8 @@ def __activate_virtual_display(self):
1452714556
sb_config._virtual_display = self._xvfb_display
1452814557
if "DISPLAY" not in os.environ.keys():
1452914558
print(
14530-
"\nX11 display failed! Will use regular xvfb!"
14559+
"\n X11 display failed! Is Xvfb installed? "
14560+
"\n Try this: `sudo apt install -y xvfb`"
1453114561
)
1453214562
self.__activate_standard_virtual_display()
1453314563
else:
@@ -14540,7 +14570,10 @@ def __activate_virtual_display(self):
1454014570
print("\n" + str(e.msg))
1454114571
else:
1454214572
print(e)
14543-
print("\nX11 display failed! Will use regular xvfb!")
14573+
print(
14574+
"\n X11 display failed! Is Xvfb installed? "
14575+
"\n Try this: `sudo apt install -y xvfb`"
14576+
)
1454414577
self.__activate_standard_virtual_display()
1454514578
return
1454614579
pyautogui_is_installed = False

0 commit comments

Comments
 (0)