Skip to content

Commit 538b5d1

Browse files
authored
Merge pull request #3020 from seleniumbase/update-uc-mode-and-more
Update UC Mode and more
2 parents 9981b5f + fde610f commit 538b5d1

File tree

10 files changed

+182
-72
lines changed

10 files changed

+182
-72
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959
📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/** folder](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
6060

61-
👤 Note that <span translate="no">SeleniumBase</span> <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode / Stealth Mode has its own ReadMe</a>.
61+
👤 Note that <span translate="no">SeleniumBase</span> <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b> (Stealth Mode) has its own ReadMe</a>.
6262

6363
ℹ️ Scripts can be called via <code translate="no"><b>python</b></code>, although some <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover & collect tests automatically).
6464

help_docs/method_summary.md

-2
Original file line numberDiff line numberDiff line change
@@ -1083,8 +1083,6 @@ driver.uc_gui_click_captcha(frame="iframe", retry=False, blind=False)
10831083
driver.uc_gui_handle_captcha(frame="iframe") # (Auto-detects the CAPTCHA)
10841084
# driver.uc_gui_handle_cf(frame="iframe") # PyAutoGUI click CF Turnstile
10851085
# driver.uc_gui_handle_rc(frame="iframe") # PyAutoGUI click G. reCAPTCHA
1086-
1087-
driver.uc_switch_to_frame(frame="iframe") # Stealthy switch_to_frame()
10881086
```
10891087

10901088
--------

help_docs/uc_mode.md

-2
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,6 @@ driver.uc_gui_click_captcha(frame="iframe", retry=False, blind=False)
199199
driver.uc_gui_handle_captcha(frame="iframe")
200200
# driver.uc_gui_handle_cf(frame="iframe")
201201
# driver.uc_gui_handle_rc(frame="iframe")
202-
203-
driver.uc_switch_to_frame(frame, reconnect_time=None)
204202
```
205203

206204
(Note that the <b><code translate="no">reconnect_time</code></b> is used to specify how long the driver should be disconnected from Chrome to prevent detection before reconnecting again.)

mkdocs_build/requirements.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ MarkupSafe==2.1.5
1111
Jinja2==3.1.4
1212
click==8.1.7
1313
ghp-import==2.1.0
14-
watchdog==4.0.1
14+
watchdog==4.0.2
1515
cairocffi==1.7.1
1616
pathspec==0.12.1
17-
Babel==2.15.0
17+
Babel==2.16.0
1818
paginate==0.5.6
19-
lxml==5.2.2
19+
lxml==5.3.0
2020
pyquery==2.0.0
2121
readtime==3.0.0
2222
mkdocs==1.6.0

requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ sniffio==1.3.1
3131
h11==0.14.0
3232
outcome==1.3.0.post0
3333
trio==0.22.2;python_version<"3.8"
34-
trio==0.26.1;python_version>="3.8"
34+
trio==0.26.2;python_version>="3.8"
3535
trio-websocket==0.11.1
3636
wsproto==1.2.0
3737
websocket-client==1.8.0;python_version>="3.8"
@@ -66,7 +66,7 @@ pygments==2.17.2;python_version<"3.8"
6666
pygments==2.18.0;python_version>="3.8"
6767
pyreadline3==3.4.1;platform_system=="Windows"
6868
tabcompleter==1.3.3
69-
pdbp==1.5.3
69+
pdbp==1.5.4
7070
colorama==0.4.6
7171
pyotp==2.9.0
7272
python-xlib==0.33;platform_system=="Linux"

seleniumbase/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.29.8"
2+
__version__ = "4.29.9"

seleniumbase/core/browser_launcher.py

+57-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from selenium import webdriver
1313
from selenium.common.exceptions import ElementClickInterceptedException
1414
from selenium.common.exceptions import InvalidSessionIdException
15+
from selenium.common.exceptions import SessionNotCreatedException
1516
from selenium.webdriver.chrome.service import Service as ChromeService
1617
from selenium.webdriver.common.options import ArgOptions
1718
from selenium.webdriver.common.service import utils as service_utils
@@ -718,7 +719,44 @@ def _uc_gui_click_x_y(driver, x, y, timeframe=0.25, uc_lock=False):
718719

719720

720721
def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
721-
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=True)
722+
gui_lock = fasteners.InterProcessLock(
723+
constants.MultiBrowser.PYAUTOGUILOCK
724+
)
725+
with gui_lock: # Prevent issues with multiple processes
726+
install_pyautogui_if_missing(driver)
727+
import pyautogui
728+
pyautogui = get_configured_pyautogui(pyautogui)
729+
if IS_WINDOWS:
730+
width_ratio = 1.0
731+
window_rect = driver.get_window_rect()
732+
width = window_rect["width"]
733+
height = window_rect["height"]
734+
win_x = window_rect["x"]
735+
win_y = window_rect["y"]
736+
if (
737+
hasattr(sb_config, "_saved_width_ratio")
738+
and sb_config._saved_width_ratio
739+
):
740+
width_ratio = sb_config._saved_width_ratio
741+
else:
742+
scr_width = pyautogui.size().width
743+
driver.maximize_window()
744+
win_width = driver.get_window_size()["width"]
745+
width_ratio = round(float(scr_width) / float(win_width), 2)
746+
width_ratio += 0.01
747+
if width_ratio < 0.45 or width_ratio > 2.55:
748+
width_ratio = 1.01
749+
sb_config._saved_width_ratio = width_ratio
750+
driver.minimize_window()
751+
driver.set_window_rect(win_x, win_y, width, height)
752+
x = x * width_ratio
753+
y = y * width_ratio
754+
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
755+
return
756+
page_actions.switch_to_window(
757+
driver, driver.current_window_handle, 2, uc_lock=False
758+
)
759+
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
722760

723761

724762
def _on_a_cf_turnstile_page(driver):
@@ -804,6 +842,7 @@ def _uc_gui_click_captcha(
804842
width_ratio = round(float(scr_width) / float(win_width), 2) + 0.01
805843
if width_ratio < 0.45 or width_ratio > 2.55:
806844
width_ratio = 1.01
845+
sb_config._saved_width_ratio = width_ratio
807846
driver.minimize_window()
808847
driver.set_window_rect(win_x, win_y, width, height)
809848
if ctype == "cf_t":
@@ -4239,11 +4278,11 @@ def get_local_driver(
42394278
driver.quit()
42404279
except Exception:
42414280
pass
4281+
uc_path = None
4282+
if os.path.exists(LOCAL_UC_DRIVER):
4283+
uc_path = LOCAL_UC_DRIVER
4284+
uc_path = os.path.realpath(uc_path)
42424285
try:
4243-
uc_path = None
4244-
if os.path.exists(LOCAL_UC_DRIVER):
4245-
uc_path = LOCAL_UC_DRIVER
4246-
uc_path = os.path.realpath(uc_path)
42474286
driver = undetected.Chrome(
42484287
options=chrome_options,
42494288
user_data_dir=user_data_dir,
@@ -4260,6 +4299,19 @@ def get_local_driver(
42604299
mac_certificate_error = True
42614300
else:
42624301
raise
4302+
except SessionNotCreatedException:
4303+
time.sleep(0.2)
4304+
driver = undetected.Chrome(
4305+
options=chrome_options,
4306+
user_data_dir=user_data_dir,
4307+
driver_executable_path=uc_path,
4308+
browser_executable_path=b_path,
4309+
enable_cdp_events=cdp_events,
4310+
headless=False, # Xvfb needed!
4311+
version_main=uc_chrome_version,
4312+
use_subprocess=True, # Always!
4313+
)
4314+
uc_activated = True
42634315
if mac_certificate_error:
42644316
cf_lock_path = (
42654317
constants.MultiBrowser.CERT_FIXING_LOCK

seleniumbase/plugins/driver_manager.py

+58-27
Original file line numberDiff line numberDiff line change
@@ -303,28 +303,44 @@ def Driver(
303303
proxy_string = proxy_string[1:-1]
304304
c_a = chromium_arg
305305
if c_a is None and "--chromium-arg" in arg_join:
306-
if "--chromium-arg=" in arg_join:
307-
c_a = arg_join.split("--chromium-arg=")[1].split(" ")[0]
308-
elif "--chromium-arg " in arg_join:
309-
c_a = arg_join.split("--chromium-arg ")[1].split(" ")[0]
310-
if c_a:
311-
if c_a.startswith('"') and c_a.endswith('"'):
312-
c_a = c_a[1:-1]
313-
elif c_a.startswith("'") and c_a.endswith("'"):
314-
c_a = c_a[1:-1]
306+
count = 0
307+
for arg in sys_argv:
308+
if arg.startswith("--chromium-arg="):
309+
c_a = arg.split("--chromium-arg=")[1]
310+
break
311+
elif arg == "--chromium-arg" and len(sys_argv) > count + 1:
312+
c_a = sys_argv[count + 1]
313+
if c_a.startswith("-"):
314+
c_a = None
315+
break
316+
count += 1
315317
chromium_arg = c_a
316318
d_f = disable_features
317319
if d_f is None and "--disable-features" in arg_join:
318-
if "--disable-features=" in arg_join:
319-
d_f = arg_join.split("--disable-features=")[1].split(" ")[0]
320-
elif "--disable-features " in arg_join:
321-
d_f = arg_join.split("--disable-features ")[1].split(" ")[0]
322-
if d_f:
323-
if d_f.startswith('"') and d_f.endswith('"'):
324-
d_f = d_f[1:-1]
325-
elif c_a.startswith("'") and d_f.endswith("'"):
326-
d_f = d_f[1:-1]
320+
count = 0
321+
for arg in sys_argv:
322+
if arg.startswith("--disable-features="):
323+
d_f = arg.split("--disable-features=")[1]
324+
break
325+
elif arg == "--disable-features" and len(sys_argv) > count + 1:
326+
d_f = sys_argv[count + 1]
327+
if d_f.startswith("-"):
328+
d_f = None
329+
break
330+
count += 1
327331
disable_features = d_f
332+
if agent is None and "--agent" in arg_join:
333+
count = 0
334+
for arg in sys_argv:
335+
if arg.startswith("--agent="):
336+
agent = arg.split("--agent=")[1]
337+
break
338+
elif arg == "--agent" and len(sys_argv) > count + 1:
339+
agent = sys_argv[count + 1]
340+
if agent.startswith("-"):
341+
agent = None
342+
break
343+
count += 1
328344
user_agent = agent
329345
recorder_mode = False
330346
if recorder_ext:
@@ -535,15 +551,30 @@ def Driver(
535551
host_resolver_rules = (
536552
arg_join.split("--host_resolver_rules=")[1].split('"')[0]
537553
)
538-
if driver_version is None:
539-
if "--driver-version=" in arg_join:
540-
driver_version = (
541-
arg_join.split("--driver-version=")[1].split(" ")[0]
542-
)
543-
elif "--driver_version=" in arg_join:
544-
driver_version = (
545-
arg_join.split("--driver_version=")[1].split(" ")[0]
546-
)
554+
if driver_version is None and "--driver-version" in arg_join:
555+
count = 0
556+
for arg in sys_argv:
557+
if arg.startswith("--driver-version="):
558+
driver_version = arg.split("--driver-version=")[1]
559+
break
560+
elif arg == "--driver-version" and len(sys_argv) > count + 1:
561+
driver_version = sys_argv[count + 1]
562+
if driver_version.startswith("-"):
563+
driver_version = None
564+
break
565+
count += 1
566+
if driver_version is None and "--driver_version" in arg_join:
567+
count = 0
568+
for arg in sys_argv:
569+
if arg.startswith("--driver_version="):
570+
driver_version = arg.split("--driver_version=")[1]
571+
break
572+
elif arg == "--driver_version" and len(sys_argv) > count + 1:
573+
driver_version = sys_argv[count + 1]
574+
if driver_version.startswith("-"):
575+
driver_version = None
576+
break
577+
count += 1
547578
browser_name = browser
548579

549580
# Launch a web browser

seleniumbase/plugins/sb_manager.py

+58-27
Original file line numberDiff line numberDiff line change
@@ -337,28 +337,44 @@ def SB(
337337
proxy_string = proxy_string[1:-1]
338338
c_a = chromium_arg
339339
if c_a is None and "--chromium-arg" in arg_join:
340-
if "--chromium-arg=" in arg_join:
341-
c_a = arg_join.split("--chromium-arg=")[1].split(" ")[0]
342-
elif "--chromium-arg " in arg_join:
343-
c_a = arg_join.split("--chromium-arg ")[1].split(" ")[0]
344-
if c_a:
345-
if c_a.startswith('"') and c_a.endswith('"'):
346-
c_a = c_a[1:-1]
347-
elif c_a.startswith("'") and c_a.endswith("'"):
348-
c_a = c_a[1:-1]
340+
count = 0
341+
for arg in sys_argv:
342+
if arg.startswith("--chromium-arg="):
343+
c_a = arg.split("--chromium-arg=")[1]
344+
break
345+
elif arg == "--chromium-arg" and len(sys_argv) > count + 1:
346+
c_a = sys_argv[count + 1]
347+
if c_a.startswith("-"):
348+
c_a = None
349+
break
350+
count += 1
349351
chromium_arg = c_a
350352
d_f = disable_features
351353
if d_f is None and "--disable-features" in arg_join:
352-
if "--disable-features=" in arg_join:
353-
d_f = arg_join.split("--disable-features=")[1].split(" ")[0]
354-
elif "--disable-features " in arg_join:
355-
d_f = arg_join.split("--disable-features ")[1].split(" ")[0]
356-
if d_f:
357-
if d_f.startswith('"') and d_f.endswith('"'):
358-
d_f = d_f[1:-1]
359-
elif c_a.startswith("'") and d_f.endswith("'"):
360-
d_f = d_f[1:-1]
354+
count = 0
355+
for arg in sys_argv:
356+
if arg.startswith("--disable-features="):
357+
d_f = arg.split("--disable-features=")[1]
358+
break
359+
elif arg == "--disable-features" and len(sys_argv) > count + 1:
360+
d_f = sys_argv[count + 1]
361+
if d_f.startswith("-"):
362+
d_f = None
363+
break
364+
count += 1
361365
disable_features = d_f
366+
if agent is None and "--agent" in arg_join:
367+
count = 0
368+
for arg in sys_argv:
369+
if arg.startswith("--agent="):
370+
agent = arg.split("--agent=")[1]
371+
break
372+
elif arg == "--agent" and len(sys_argv) > count + 1:
373+
agent = sys_argv[count + 1]
374+
if agent.startswith("-"):
375+
agent = None
376+
break
377+
count += 1
362378
user_agent = agent
363379
recorder_mode = False
364380
if recorder_ext:
@@ -679,15 +695,30 @@ def SB(
679695
host_resolver_rules = (
680696
arg_join.split("--host_resolver_rules=")[1].split('"')[0]
681697
)
682-
if driver_version is None:
683-
if "--driver-version=" in arg_join:
684-
driver_version = (
685-
arg_join.split("--driver-version=")[1].split(" ")[0]
686-
)
687-
elif "--driver_version=" in arg_join:
688-
driver_version = (
689-
arg_join.split("--driver_version=")[1].split(" ")[0]
690-
)
698+
if driver_version is None and "--driver-version" in arg_join:
699+
count = 0
700+
for arg in sys_argv:
701+
if arg.startswith("--driver-version="):
702+
driver_version = arg.split("--driver-version=")[1]
703+
break
704+
elif arg == "--driver-version" and len(sys_argv) > count + 1:
705+
driver_version = sys_argv[count + 1]
706+
if driver_version.startswith("-"):
707+
driver_version = None
708+
break
709+
count += 1
710+
if driver_version is None and "--driver_version" in arg_join:
711+
count = 0
712+
for arg in sys_argv:
713+
if arg.startswith("--driver_version="):
714+
driver_version = arg.split("--driver_version=")[1]
715+
break
716+
elif arg == "--driver_version" and len(sys_argv) > count + 1:
717+
driver_version = sys_argv[count + 1]
718+
if driver_version.startswith("-"):
719+
driver_version = None
720+
break
721+
count += 1
691722
if highlights is not None:
692723
try:
693724
highlights = int(highlights)

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
'h11==0.14.0',
180180
'outcome==1.3.0.post0',
181181
'trio==0.22.2;python_version<"3.8"',
182-
'trio==0.26.1;python_version>="3.8"',
182+
'trio==0.26.2;python_version>="3.8"',
183183
'trio-websocket==0.11.1',
184184
'wsproto==1.2.0',
185185
'websocket-client==1.8.0;python_version>="3.8"',
@@ -214,7 +214,7 @@
214214
'pygments==2.18.0;python_version>="3.8"',
215215
'pyreadline3==3.4.1;platform_system=="Windows"',
216216
"tabcompleter==1.3.3",
217-
"pdbp==1.5.3",
217+
"pdbp==1.5.4",
218218
'colorama==0.4.6',
219219
'pyotp==2.9.0',
220220
'python-xlib==0.33;platform_system=="Linux"',

0 commit comments

Comments
 (0)