seleniumbase 4.24.10__py3-none-any.whl → 4.33.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sbase/__init__.py +1 -0
- sbase/steps.py +7 -0
- seleniumbase/__init__.py +16 -7
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +97 -32
- seleniumbase/common/decorators.py +16 -7
- seleniumbase/config/proxy_list.py +3 -3
- seleniumbase/config/settings.py +4 -0
- seleniumbase/console_scripts/logo_helper.py +47 -8
- seleniumbase/console_scripts/run.py +345 -335
- seleniumbase/console_scripts/sb_behave_gui.py +5 -12
- seleniumbase/console_scripts/sb_caseplans.py +6 -13
- seleniumbase/console_scripts/sb_commander.py +5 -12
- seleniumbase/console_scripts/sb_install.py +62 -54
- seleniumbase/console_scripts/sb_mkchart.py +13 -20
- seleniumbase/console_scripts/sb_mkdir.py +11 -17
- seleniumbase/console_scripts/sb_mkfile.py +69 -43
- seleniumbase/console_scripts/sb_mkpres.py +13 -20
- seleniumbase/console_scripts/sb_mkrec.py +88 -21
- seleniumbase/console_scripts/sb_objectify.py +30 -30
- seleniumbase/console_scripts/sb_print.py +5 -12
- seleniumbase/console_scripts/sb_recorder.py +16 -11
- seleniumbase/core/browser_launcher.py +1658 -221
- seleniumbase/core/detect_b_ver.py +7 -8
- seleniumbase/core/log_helper.py +42 -27
- seleniumbase/core/mysql.py +1 -4
- seleniumbase/core/proxy_helper.py +35 -30
- seleniumbase/core/recorder_helper.py +24 -5
- seleniumbase/core/sb_cdp.py +1951 -0
- seleniumbase/core/sb_driver.py +162 -8
- seleniumbase/core/settings_parser.py +6 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/extensions/recorder.zip +0 -0
- seleniumbase/fixtures/base_case.py +1234 -632
- seleniumbase/fixtures/constants.py +10 -1
- seleniumbase/fixtures/js_utils.py +171 -144
- seleniumbase/fixtures/page_actions.py +177 -13
- seleniumbase/fixtures/page_utils.py +25 -53
- seleniumbase/fixtures/shared_utils.py +97 -11
- seleniumbase/js_code/active_css_js.py +1 -1
- seleniumbase/js_code/recorder_js.py +1 -1
- seleniumbase/plugins/base_plugin.py +2 -3
- seleniumbase/plugins/driver_manager.py +340 -65
- seleniumbase/plugins/pytest_plugin.py +276 -47
- seleniumbase/plugins/sb_manager.py +412 -99
- seleniumbase/plugins/selenium_plugin.py +122 -17
- seleniumbase/translate/translator.py +0 -7
- seleniumbase/undetected/__init__.py +59 -52
- seleniumbase/undetected/cdp.py +0 -1
- seleniumbase/undetected/cdp_driver/__init__.py +1 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
- seleniumbase/undetected/cdp_driver/browser.py +829 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
- seleniumbase/undetected/cdp_driver/config.py +334 -0
- seleniumbase/undetected/cdp_driver/connection.py +639 -0
- seleniumbase/undetected/cdp_driver/element.py +1168 -0
- seleniumbase/undetected/cdp_driver/tab.py +1323 -0
- seleniumbase/undetected/dprocess.py +4 -7
- seleniumbase/undetected/options.py +6 -8
- seleniumbase/undetected/patcher.py +11 -13
- seleniumbase/undetected/reactor.py +0 -1
- seleniumbase/undetected/webelement.py +16 -3
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +68 -70
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
- sbase/ReadMe.txt +0 -2
- seleniumbase/ReadMe.md +0 -25
- seleniumbase/common/ReadMe.md +0 -71
- seleniumbase/console_scripts/ReadMe.md +0 -731
- seleniumbase/drivers/ReadMe.md +0 -27
- seleniumbase/extensions/ReadMe.md +0 -12
- seleniumbase/masterqa/ReadMe.md +0 -61
- seleniumbase/resources/ReadMe.md +0 -31
- seleniumbase/resources/favicon.ico +0 -0
- seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
- seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.24.10.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
@@ -9,8 +9,11 @@ import time
|
|
9
9
|
import types
|
10
10
|
import urllib3
|
11
11
|
import warnings
|
12
|
+
from contextlib import suppress
|
12
13
|
from selenium import webdriver
|
13
14
|
from selenium.common.exceptions import ElementClickInterceptedException
|
15
|
+
from selenium.common.exceptions import InvalidSessionIdException
|
16
|
+
from selenium.common.exceptions import SessionNotCreatedException
|
14
17
|
from selenium.webdriver.chrome.service import Service as ChromeService
|
15
18
|
from selenium.webdriver.common.options import ArgOptions
|
16
19
|
from selenium.webdriver.common.service import utils as service_utils
|
@@ -26,7 +29,10 @@ from seleniumbase.core import detect_b_ver
|
|
26
29
|
from seleniumbase.core import download_helper
|
27
30
|
from seleniumbase.core import proxy_helper
|
28
31
|
from seleniumbase.core import sb_driver
|
32
|
+
from seleniumbase.core import sb_cdp
|
29
33
|
from seleniumbase.fixtures import constants
|
34
|
+
from seleniumbase.fixtures import js_utils
|
35
|
+
from seleniumbase.fixtures import page_actions
|
30
36
|
from seleniumbase.fixtures import shared_utils
|
31
37
|
|
32
38
|
urllib3.disable_warnings()
|
@@ -91,19 +97,12 @@ def log_d(message):
|
|
91
97
|
print(message)
|
92
98
|
|
93
99
|
|
94
|
-
def make_executable(file_path):
|
95
|
-
# Set permissions to: "If you can read it, you can execute it."
|
96
|
-
mode = os.stat(file_path).st_mode
|
97
|
-
mode |= (mode & 0o444) >> 2 # copy R bits to X
|
98
|
-
os.chmod(file_path, mode)
|
99
|
-
|
100
|
-
|
101
100
|
def make_driver_executable_if_not(driver_path):
|
102
101
|
# Verify driver has executable permissions. If not, add them.
|
103
102
|
permissions = oct(os.stat(driver_path)[0])[-3:]
|
104
103
|
if "4" in permissions or "6" in permissions:
|
105
104
|
# We want at least a '5' or '7' to make sure it's executable
|
106
|
-
make_executable(driver_path)
|
105
|
+
shared_utils.make_executable(driver_path)
|
107
106
|
|
108
107
|
|
109
108
|
def extend_driver(driver):
|
@@ -129,9 +128,13 @@ def extend_driver(driver):
|
|
129
128
|
page.assert_element_not_visible = DM.assert_element_not_visible
|
130
129
|
page.assert_text = DM.assert_text
|
131
130
|
page.assert_exact_text = DM.assert_exact_text
|
131
|
+
page.assert_non_empty_text = DM.assert_non_empty_text
|
132
|
+
page.assert_text_not_visible = DM.assert_text_not_visible
|
132
133
|
page.wait_for_element = DM.wait_for_element
|
133
134
|
page.wait_for_text = DM.wait_for_text
|
134
135
|
page.wait_for_exact_text = DM.wait_for_exact_text
|
136
|
+
page.wait_for_non_empty_text = DM.wait_for_non_empty_text
|
137
|
+
page.wait_for_text_not_visible = DM.wait_for_text_not_visible
|
135
138
|
page.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
|
136
139
|
page.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
|
137
140
|
page.is_element_present = DM.is_element_present
|
@@ -139,12 +142,22 @@ def extend_driver(driver):
|
|
139
142
|
page.is_text_visible = DM.is_text_visible
|
140
143
|
page.is_exact_text_visible = DM.is_exact_text_visible
|
141
144
|
page.is_attribute_present = DM.is_attribute_present
|
145
|
+
page.is_non_empty_text_visible = DM.is_non_empty_text_visible
|
142
146
|
page.get_text = DM.get_text
|
143
147
|
page.find_element = DM.find_element
|
144
148
|
page.find_elements = DM.find_elements
|
145
149
|
page.locator = DM.locator
|
150
|
+
page.get_current_url = DM.get_current_url
|
146
151
|
page.get_page_source = DM.get_page_source
|
147
152
|
page.get_title = DM.get_title
|
153
|
+
page.get_page_title = DM.get_title
|
154
|
+
page.switch_to_default_window = DM.switch_to_default_window
|
155
|
+
page.switch_to_newest_window = DM.switch_to_newest_window
|
156
|
+
page.open_new_window = DM.open_new_window
|
157
|
+
page.open_new_tab = DM.open_new_tab
|
158
|
+
page.switch_to_window = DM.switch_to_window
|
159
|
+
page.switch_to_tab = DM.switch_to_tab
|
160
|
+
page.switch_to_frame = DM.switch_to_frame
|
148
161
|
driver.page = page
|
149
162
|
js = types.SimpleNamespace()
|
150
163
|
js.js_click = DM.js_click
|
@@ -168,12 +181,16 @@ def extend_driver(driver):
|
|
168
181
|
driver.assert_element_not_visible = DM.assert_element_not_visible
|
169
182
|
driver.assert_text = DM.assert_text
|
170
183
|
driver.assert_exact_text = DM.assert_exact_text
|
184
|
+
driver.assert_non_empty_text = DM.assert_non_empty_text
|
185
|
+
driver.assert_text_not_visible = DM.assert_text_not_visible
|
171
186
|
driver.wait_for_element = DM.wait_for_element
|
172
187
|
driver.wait_for_element_visible = DM.wait_for_element_visible
|
173
188
|
driver.wait_for_element_present = DM.wait_for_element_present
|
174
189
|
driver.wait_for_selector = DM.wait_for_selector
|
175
190
|
driver.wait_for_text = DM.wait_for_text
|
176
191
|
driver.wait_for_exact_text = DM.wait_for_exact_text
|
192
|
+
driver.wait_for_non_empty_text = DM.wait_for_non_empty_text
|
193
|
+
driver.wait_for_text_not_visible = DM.wait_for_text_not_visible
|
177
194
|
driver.wait_for_and_accept_alert = DM.wait_for_and_accept_alert
|
178
195
|
driver.wait_for_and_dismiss_alert = DM.wait_for_and_dismiss_alert
|
179
196
|
driver.is_element_present = DM.is_element_present
|
@@ -181,20 +198,38 @@ def extend_driver(driver):
|
|
181
198
|
driver.is_text_visible = DM.is_text_visible
|
182
199
|
driver.is_exact_text_visible = DM.is_exact_text_visible
|
183
200
|
driver.is_attribute_present = DM.is_attribute_present
|
184
|
-
driver.
|
201
|
+
driver.is_non_empty_text_visible = DM.is_non_empty_text_visible
|
202
|
+
driver.is_valid_url = DM.is_valid_url
|
203
|
+
driver.is_alert_present = DM.is_alert_present
|
204
|
+
driver.is_online = DM.is_online
|
205
|
+
driver.is_connected = DM.is_connected
|
206
|
+
driver.is_uc_mode_active = DM.is_uc_mode_active
|
207
|
+
driver.is_cdp_mode_active = DM.is_cdp_mode_active
|
185
208
|
driver.js_click = DM.js_click
|
209
|
+
driver.get_text = DM.get_text
|
186
210
|
driver.get_active_element_css = DM.get_active_element_css
|
187
211
|
driver.get_locale_code = DM.get_locale_code
|
212
|
+
driver.get_screen_rect = DM.get_screen_rect
|
188
213
|
driver.get_origin = DM.get_origin
|
189
214
|
driver.get_user_agent = DM.get_user_agent
|
215
|
+
driver.get_cookie_string = DM.get_cookie_string
|
190
216
|
driver.highlight = DM.highlight
|
191
217
|
driver.highlight_click = DM.highlight_click
|
192
218
|
driver.highlight_if_visible = DM.highlight_if_visible
|
193
219
|
driver.sleep = time.sleep
|
194
220
|
driver.get_attribute = DM.get_attribute
|
221
|
+
driver.get_current_url = DM.get_current_url
|
195
222
|
driver.get_page_source = DM.get_page_source
|
196
223
|
driver.get_title = DM.get_title
|
224
|
+
driver.get_page_title = DM.get_title
|
225
|
+
driver.switch_to_default_window = DM.switch_to_default_window
|
226
|
+
driver.switch_to_newest_window = DM.switch_to_newest_window
|
227
|
+
driver.open_new_window = DM.open_new_window
|
228
|
+
driver.open_new_tab = DM.open_new_tab
|
229
|
+
driver.switch_to_window = DM.switch_to_window
|
230
|
+
driver.switch_to_tab = DM.switch_to_tab
|
197
231
|
driver.switch_to_frame = DM.switch_to_frame
|
232
|
+
driver.reset_window_size = DM.reset_window_size
|
198
233
|
if hasattr(driver, "proxy"):
|
199
234
|
driver.set_wire_proxy = DM.set_wire_proxy
|
200
235
|
return driver
|
@@ -249,7 +284,7 @@ def chromedriver_on_path():
|
|
249
284
|
def get_uc_driver_version(full=False):
|
250
285
|
uc_driver_version = None
|
251
286
|
if os.path.exists(LOCAL_UC_DRIVER):
|
252
|
-
|
287
|
+
with suppress(Exception):
|
253
288
|
output = subprocess.check_output(
|
254
289
|
'"%s" --version' % LOCAL_UC_DRIVER, shell=True
|
255
290
|
)
|
@@ -264,8 +299,6 @@ def get_uc_driver_version(full=False):
|
|
264
299
|
uc_driver_version = full_version
|
265
300
|
else:
|
266
301
|
uc_driver_version = output
|
267
|
-
except Exception:
|
268
|
-
pass
|
269
302
|
return uc_driver_version
|
270
303
|
|
271
304
|
|
@@ -312,17 +345,19 @@ def find_edgedriver_version_to_use(use_version, driver_version):
|
|
312
345
|
return use_version
|
313
346
|
|
314
347
|
|
315
|
-
def
|
348
|
+
def has_captcha(text):
|
316
349
|
if (
|
317
350
|
"<title>403 Forbidden</title>" in text
|
318
351
|
or "Permission Denied</title>" in text
|
319
352
|
or 'id="challenge-error-text"' in text
|
320
353
|
or "<title>Just a moment..." in text
|
321
354
|
or 'action="/?__cf_chl_f_tk' in text
|
355
|
+
or 'id="challenge-widget-' in text
|
322
356
|
or 'src="chromedriver.js"' in text
|
323
357
|
or 'class="g-recaptcha"' in text
|
324
358
|
or 'content="Pixelscan"' in text
|
325
359
|
or 'id="challenge-form"' in text
|
360
|
+
or "/challenge-platform" in text
|
326
361
|
or "window._cf_chl_opt" in text
|
327
362
|
or "/recaptcha/api.js" in text
|
328
363
|
or "/turnstile/" in text
|
@@ -331,6 +366,11 @@ def has_cf(text):
|
|
331
366
|
return False
|
332
367
|
|
333
368
|
|
369
|
+
def __is_cdp_swap_needed(driver):
|
370
|
+
"""If the driver is disconnected, use a CDP method when available."""
|
371
|
+
return shared_utils.is_cdp_swap_needed(driver)
|
372
|
+
|
373
|
+
|
334
374
|
def uc_special_open_if_cf(
|
335
375
|
driver,
|
336
376
|
url,
|
@@ -342,32 +382,32 @@ def uc_special_open_if_cf(
|
|
342
382
|
):
|
343
383
|
if url.startswith("http:") or url.startswith("https:"):
|
344
384
|
special = False
|
345
|
-
|
385
|
+
with suppress(Exception):
|
346
386
|
req_get = requests_get(url, proxy_string)
|
347
387
|
status_str = str(req_get.status_code)
|
348
388
|
if (
|
349
389
|
status_str.startswith("3")
|
350
390
|
or status_str.startswith("4")
|
351
391
|
or status_str.startswith("5")
|
352
|
-
or
|
392
|
+
or has_captcha(req_get.text)
|
353
393
|
):
|
354
394
|
special = True
|
355
395
|
if status_str == "403" or status_str == "429":
|
356
396
|
time.sleep(0.06) # Forbidden / Blocked! (Wait first!)
|
357
|
-
except Exception:
|
358
|
-
pass
|
359
397
|
if special:
|
360
398
|
time.sleep(0.05)
|
361
399
|
with driver:
|
362
400
|
driver.execute_script('window.open("%s","_blank");' % url)
|
363
401
|
driver.close()
|
364
402
|
if mobile_emulator:
|
365
|
-
|
403
|
+
page_actions.switch_to_window(
|
404
|
+
driver, driver.window_handles[-1], 2
|
405
|
+
)
|
366
406
|
uc_metrics = {}
|
367
407
|
if (
|
368
408
|
isinstance(device_width, int)
|
369
409
|
and isinstance(device_height, int)
|
370
|
-
and isinstance(device_pixel_ratio, int)
|
410
|
+
and isinstance(device_pixel_ratio, (int, float))
|
371
411
|
):
|
372
412
|
uc_metrics["width"] = device_width
|
373
413
|
uc_metrics["height"] = device_height
|
@@ -384,15 +424,15 @@ def uc_special_open_if_cf(
|
|
384
424
|
"mobile": True
|
385
425
|
}
|
386
426
|
)
|
387
|
-
|
427
|
+
with suppress(Exception):
|
388
428
|
driver.execute_cdp_cmd(
|
389
429
|
'Emulation.setDeviceMetricsOverride',
|
390
430
|
set_device_metrics_override
|
391
431
|
)
|
392
|
-
except Exception:
|
393
|
-
pass
|
394
432
|
if not mobile_emulator:
|
395
|
-
|
433
|
+
page_actions.switch_to_window(
|
434
|
+
driver, driver.window_handles[-1], 2
|
435
|
+
)
|
396
436
|
else:
|
397
437
|
driver.default_get(url) # The original one
|
398
438
|
else:
|
@@ -401,30 +441,31 @@ def uc_special_open_if_cf(
|
|
401
441
|
|
402
442
|
|
403
443
|
def uc_open(driver, url):
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
444
|
+
url = shared_utils.fix_url_as_needed(url)
|
445
|
+
if __is_cdp_swap_needed(driver):
|
446
|
+
driver.cdp.get(url)
|
447
|
+
time.sleep(0.3)
|
448
|
+
return
|
408
449
|
if (url.startswith("http:") or url.startswith("https:")):
|
409
|
-
time.sleep(0.05)
|
410
450
|
with driver:
|
411
|
-
|
451
|
+
script = 'window.location.href = "%s";' % url
|
452
|
+
js_utils.call_me_later(driver, script, 5)
|
412
453
|
else:
|
413
454
|
driver.default_get(url) # The original one
|
414
455
|
return None
|
415
456
|
|
416
457
|
|
417
458
|
def uc_open_with_tab(driver, url):
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
459
|
+
url = shared_utils.fix_url_as_needed(url)
|
460
|
+
if __is_cdp_swap_needed(driver):
|
461
|
+
driver.cdp.get(url)
|
462
|
+
time.sleep(0.3)
|
463
|
+
return
|
422
464
|
if (url.startswith("http:") or url.startswith("https:")):
|
423
|
-
time.sleep(0.05)
|
424
465
|
with driver:
|
425
466
|
driver.execute_script('window.open("%s","_blank");' % url)
|
426
467
|
driver.close()
|
427
|
-
|
468
|
+
page_actions.switch_to_window(driver, driver.window_handles[-1], 2)
|
428
469
|
else:
|
429
470
|
driver.default_get(url) # The original one
|
430
471
|
return None
|
@@ -432,17 +473,314 @@ def uc_open_with_tab(driver, url):
|
|
432
473
|
|
433
474
|
def uc_open_with_reconnect(driver, url, reconnect_time=None):
|
434
475
|
"""Open a url, disconnect chromedriver, wait, and reconnect."""
|
476
|
+
url = shared_utils.fix_url_as_needed(url)
|
477
|
+
if __is_cdp_swap_needed(driver):
|
478
|
+
driver.cdp.get(url)
|
479
|
+
time.sleep(0.3)
|
480
|
+
return
|
435
481
|
if not reconnect_time:
|
436
482
|
reconnect_time = constants.UC.RECONNECT_TIME
|
437
|
-
if url.startswith("//"):
|
438
|
-
url = "https:" + url
|
439
|
-
elif ":" not in url:
|
440
|
-
url = "https://" + url
|
441
483
|
if (url.startswith("http:") or url.startswith("https:")):
|
442
|
-
|
484
|
+
script = 'window.open("%s","_blank");' % url
|
485
|
+
driver.execute_script(script)
|
486
|
+
time.sleep(0.05)
|
487
|
+
driver.close()
|
488
|
+
if reconnect_time == "disconnect":
|
489
|
+
driver.disconnect()
|
490
|
+
time.sleep(0.008)
|
491
|
+
else:
|
492
|
+
driver.reconnect(reconnect_time)
|
493
|
+
time.sleep(0.004)
|
494
|
+
try:
|
495
|
+
page_actions.switch_to_window(
|
496
|
+
driver, driver.window_handles[-1], 2
|
497
|
+
)
|
498
|
+
except InvalidSessionIdException:
|
499
|
+
time.sleep(0.05)
|
500
|
+
page_actions.switch_to_window(
|
501
|
+
driver, driver.window_handles[-1], 2
|
502
|
+
)
|
503
|
+
else:
|
504
|
+
driver.default_get(url) # The original one
|
505
|
+
return None
|
506
|
+
|
507
|
+
|
508
|
+
def uc_open_with_cdp_mode(driver, url=None):
|
509
|
+
import asyncio
|
510
|
+
from seleniumbase.undetected.cdp_driver import cdp_util
|
511
|
+
|
512
|
+
current_url = None
|
513
|
+
try:
|
514
|
+
current_url = driver.current_url
|
515
|
+
except Exception:
|
516
|
+
driver.connect()
|
517
|
+
current_url = driver.current_url
|
518
|
+
url_protocol = current_url.split(":")[0]
|
519
|
+
if url_protocol not in ["about", "data", "chrome"]:
|
520
|
+
script = 'window.open("data:,","_blank");'
|
521
|
+
js_utils.call_me_later(driver, script, 3)
|
522
|
+
time.sleep(0.012)
|
523
|
+
driver.close()
|
524
|
+
driver.disconnect()
|
525
|
+
|
526
|
+
cdp_details = driver._get_cdp_details()
|
527
|
+
cdp_host = cdp_details[1].split("://")[1].split(":")[0]
|
528
|
+
cdp_port = int(cdp_details[1].split("://")[1].split(":")[1].split("/")[0])
|
529
|
+
|
530
|
+
url = shared_utils.fix_url_as_needed(url)
|
531
|
+
url_protocol = url.split(":")[0]
|
532
|
+
safe_url = True
|
533
|
+
if url_protocol not in ["about", "data", "chrome"]:
|
534
|
+
safe_url = False
|
535
|
+
|
536
|
+
headless = False
|
537
|
+
headed = None
|
538
|
+
xvfb = None
|
539
|
+
if hasattr(sb_config, "headless"):
|
540
|
+
headless = sb_config.headless
|
541
|
+
if hasattr(sb_config, "headed"):
|
542
|
+
headed = sb_config.headed
|
543
|
+
if hasattr(sb_config, "xvfb"):
|
544
|
+
xvfb = sb_config.xvfb
|
545
|
+
|
546
|
+
loop = asyncio.new_event_loop()
|
547
|
+
asyncio.set_event_loop(loop)
|
548
|
+
driver.cdp_base = loop.run_until_complete(
|
549
|
+
cdp_util.start(
|
550
|
+
host=cdp_host,
|
551
|
+
port=cdp_port,
|
552
|
+
headless=headless,
|
553
|
+
headed=headed,
|
554
|
+
xvfb=xvfb,
|
555
|
+
)
|
556
|
+
)
|
557
|
+
loop.run_until_complete(driver.cdp_base.wait(0))
|
558
|
+
|
559
|
+
gui_lock = fasteners.InterProcessLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
560
|
+
|
561
|
+
if (
|
562
|
+
"chrome-extension://" in str(driver.cdp_base.main_tab)
|
563
|
+
and len(driver.cdp_base.tabs) >= 2
|
564
|
+
):
|
565
|
+
with suppress(Exception):
|
566
|
+
loop.run_until_complete(driver.cdp_base.main_tab.close())
|
567
|
+
|
568
|
+
for tab in driver.cdp_base.tabs[-1::-1]:
|
569
|
+
if "chrome-extension://" not in str(tab):
|
570
|
+
with gui_lock:
|
571
|
+
with suppress(Exception):
|
572
|
+
shared_utils.make_writable(
|
573
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
574
|
+
)
|
575
|
+
loop.run_until_complete(tab.activate())
|
576
|
+
break
|
577
|
+
|
578
|
+
page_tab = None
|
579
|
+
if "chrome-extension://" not in str(driver.cdp_base.tabs[-1]):
|
580
|
+
page_tab = driver.cdp_base.tabs[-1]
|
581
|
+
else:
|
582
|
+
for tab in driver.cdp_base.tabs:
|
583
|
+
if "chrome-extension://" not in str(tab):
|
584
|
+
page_tab = tab
|
585
|
+
break
|
586
|
+
if page_tab:
|
587
|
+
loop.run_until_complete(page_tab.aopen())
|
588
|
+
with gui_lock:
|
589
|
+
with suppress(Exception):
|
590
|
+
shared_utils.make_writable(
|
591
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
592
|
+
)
|
593
|
+
loop.run_until_complete(page_tab.activate())
|
594
|
+
|
595
|
+
loop.run_until_complete(driver.cdp_base.update_targets())
|
596
|
+
page = loop.run_until_complete(driver.cdp_base.get(url))
|
597
|
+
with gui_lock:
|
598
|
+
with suppress(Exception):
|
599
|
+
shared_utils.make_writable(constants.MultiBrowser.PYAUTOGUILOCK)
|
600
|
+
loop.run_until_complete(page.activate())
|
601
|
+
loop.run_until_complete(page.wait())
|
602
|
+
if not safe_url:
|
603
|
+
time.sleep(constants.UC.CDP_MODE_OPEN_WAIT)
|
604
|
+
if IS_WINDOWS:
|
605
|
+
time.sleep(constants.UC.EXTRA_WINDOWS_WAIT)
|
606
|
+
else:
|
607
|
+
time.sleep(0.012)
|
608
|
+
cdp = types.SimpleNamespace()
|
609
|
+
CDPM = sb_cdp.CDPMethods(loop, page, driver)
|
610
|
+
cdp.get = CDPM.get
|
611
|
+
cdp.open = CDPM.open
|
612
|
+
cdp.reload = CDPM.reload
|
613
|
+
cdp.refresh = CDPM.refresh
|
614
|
+
cdp.add_handler = CDPM.add_handler
|
615
|
+
cdp.get_event_loop = CDPM.get_event_loop
|
616
|
+
cdp.find_element = CDPM.find_element
|
617
|
+
cdp.find = CDPM.find_element
|
618
|
+
cdp.locator = CDPM.find_element
|
619
|
+
cdp.find_element_by_text = CDPM.find_element_by_text
|
620
|
+
cdp.find_all = CDPM.find_all
|
621
|
+
cdp.find_elements_by_text = CDPM.find_elements_by_text
|
622
|
+
cdp.select = CDPM.select
|
623
|
+
cdp.select_all = CDPM.select_all
|
624
|
+
cdp.find_elements = CDPM.find_elements
|
625
|
+
cdp.find_visible_elements = CDPM.find_visible_elements
|
626
|
+
cdp.click_nth_element = CDPM.click_nth_element
|
627
|
+
cdp.click_nth_visible_element = CDPM.click_nth_visible_element
|
628
|
+
cdp.click_link = CDPM.click_link
|
629
|
+
cdp.go_back = CDPM.go_back
|
630
|
+
cdp.go_forward = CDPM.go_forward
|
631
|
+
cdp.get_navigation_history = CDPM.get_navigation_history
|
632
|
+
cdp.tile_windows = CDPM.tile_windows
|
633
|
+
cdp.get_all_cookies = CDPM.get_all_cookies
|
634
|
+
cdp.set_all_cookies = CDPM.set_all_cookies
|
635
|
+
cdp.save_cookies = CDPM.save_cookies
|
636
|
+
cdp.load_cookies = CDPM.load_cookies
|
637
|
+
cdp.clear_cookies = CDPM.clear_cookies
|
638
|
+
cdp.sleep = CDPM.sleep
|
639
|
+
cdp.bring_active_window_to_front = CDPM.bring_active_window_to_front
|
640
|
+
cdp.bring_to_front = CDPM.bring_active_window_to_front
|
641
|
+
cdp.get_active_element = CDPM.get_active_element
|
642
|
+
cdp.get_active_element_css = CDPM.get_active_element_css
|
643
|
+
cdp.click = CDPM.click
|
644
|
+
cdp.click_active_element = CDPM.click_active_element
|
645
|
+
cdp.click_if_visible = CDPM.click_if_visible
|
646
|
+
cdp.click_visible_elements = CDPM.click_visible_elements
|
647
|
+
cdp.mouse_click = CDPM.mouse_click
|
648
|
+
cdp.remove_element = CDPM.remove_element
|
649
|
+
cdp.remove_from_dom = CDPM.remove_from_dom
|
650
|
+
cdp.remove_elements = CDPM.remove_elements
|
651
|
+
cdp.send_keys = CDPM.send_keys
|
652
|
+
cdp.press_keys = CDPM.press_keys
|
653
|
+
cdp.type = CDPM.type
|
654
|
+
cdp.set_value = CDPM.set_value
|
655
|
+
cdp.evaluate = CDPM.evaluate
|
656
|
+
cdp.js_dumps = CDPM.js_dumps
|
657
|
+
cdp.maximize = CDPM.maximize
|
658
|
+
cdp.minimize = CDPM.minimize
|
659
|
+
cdp.medimize = CDPM.medimize
|
660
|
+
cdp.set_window_rect = CDPM.set_window_rect
|
661
|
+
cdp.reset_window_size = CDPM.reset_window_size
|
662
|
+
cdp.set_locale = CDPM.set_locale
|
663
|
+
cdp.set_attributes = CDPM.set_attributes
|
664
|
+
cdp.gui_press_key = CDPM.gui_press_key
|
665
|
+
cdp.gui_press_keys = CDPM.gui_press_keys
|
666
|
+
cdp.gui_write = CDPM.gui_write
|
667
|
+
cdp.gui_click_x_y = CDPM.gui_click_x_y
|
668
|
+
cdp.gui_click_element = CDPM.gui_click_element
|
669
|
+
cdp.gui_drag_drop_points = CDPM.gui_drag_drop_points
|
670
|
+
cdp.gui_drag_and_drop = CDPM.gui_drag_and_drop
|
671
|
+
cdp.gui_hover_x_y = CDPM.gui_hover_x_y
|
672
|
+
cdp.gui_hover_element = CDPM.gui_hover_element
|
673
|
+
cdp.gui_hover_and_click = CDPM.gui_hover_and_click
|
674
|
+
cdp.internalize_links = CDPM.internalize_links
|
675
|
+
cdp.get_window = CDPM.get_window
|
676
|
+
cdp.get_element_attributes = CDPM.get_element_attributes
|
677
|
+
cdp.get_element_attribute = CDPM.get_element_attribute
|
678
|
+
cdp.get_attribute = CDPM.get_attribute
|
679
|
+
cdp.get_element_html = CDPM.get_element_html
|
680
|
+
cdp.get_element_rect = CDPM.get_element_rect
|
681
|
+
cdp.get_element_size = CDPM.get_element_size
|
682
|
+
cdp.get_element_position = CDPM.get_element_position
|
683
|
+
cdp.get_gui_element_rect = CDPM.get_gui_element_rect
|
684
|
+
cdp.get_gui_element_center = CDPM.get_gui_element_center
|
685
|
+
cdp.get_page_source = CDPM.get_page_source
|
686
|
+
cdp.get_user_agent = CDPM.get_user_agent
|
687
|
+
cdp.get_cookie_string = CDPM.get_cookie_string
|
688
|
+
cdp.get_locale_code = CDPM.get_locale_code
|
689
|
+
cdp.get_text = CDPM.get_text
|
690
|
+
cdp.get_title = CDPM.get_title
|
691
|
+
cdp.get_page_title = CDPM.get_title
|
692
|
+
cdp.get_current_url = CDPM.get_current_url
|
693
|
+
cdp.get_origin = CDPM.get_origin
|
694
|
+
cdp.get_nested_element = CDPM.get_nested_element
|
695
|
+
cdp.get_document = CDPM.get_document
|
696
|
+
cdp.get_flattened_document = CDPM.get_flattened_document
|
697
|
+
cdp.get_screen_rect = CDPM.get_screen_rect
|
698
|
+
cdp.get_window_rect = CDPM.get_window_rect
|
699
|
+
cdp.get_window_size = CDPM.get_window_size
|
700
|
+
cdp.nested_click = CDPM.nested_click
|
701
|
+
cdp.select_option_by_text = CDPM.select_option_by_text
|
702
|
+
cdp.flash = CDPM.flash
|
703
|
+
cdp.highlight = CDPM.highlight
|
704
|
+
cdp.focus = CDPM.focus
|
705
|
+
cdp.highlight_overlay = CDPM.highlight_overlay
|
706
|
+
cdp.get_window_position = CDPM.get_window_position
|
707
|
+
cdp.check_if_unchecked = CDPM.check_if_unchecked
|
708
|
+
cdp.uncheck_if_checked = CDPM.uncheck_if_checked
|
709
|
+
cdp.select_if_unselected = CDPM.select_if_unselected
|
710
|
+
cdp.unselect_if_selected = CDPM.unselect_if_selected
|
711
|
+
cdp.is_checked = CDPM.is_checked
|
712
|
+
cdp.is_selected = CDPM.is_selected
|
713
|
+
cdp.is_element_present = CDPM.is_element_present
|
714
|
+
cdp.is_element_visible = CDPM.is_element_visible
|
715
|
+
cdp.wait_for_element_visible = CDPM.wait_for_element_visible
|
716
|
+
cdp.assert_element = CDPM.assert_element
|
717
|
+
cdp.assert_element_visible = CDPM.assert_element_visible
|
718
|
+
cdp.assert_element_present = CDPM.assert_element_present
|
719
|
+
cdp.assert_element_absent = CDPM.assert_element_absent
|
720
|
+
cdp.assert_element_not_visible = CDPM.assert_element_not_visible
|
721
|
+
cdp.assert_element_attribute = CDPM.assert_element_attribute
|
722
|
+
cdp.assert_title = CDPM.assert_title
|
723
|
+
cdp.assert_title_contains = CDPM.assert_title_contains
|
724
|
+
cdp.assert_url = CDPM.assert_url
|
725
|
+
cdp.assert_url_contains = CDPM.assert_url_contains
|
726
|
+
cdp.assert_text = CDPM.assert_text
|
727
|
+
cdp.assert_exact_text = CDPM.assert_exact_text
|
728
|
+
cdp.assert_true = CDPM.assert_true
|
729
|
+
cdp.assert_false = CDPM.assert_false
|
730
|
+
cdp.assert_equal = CDPM.assert_equal
|
731
|
+
cdp.assert_not_equal = CDPM.assert_not_equal
|
732
|
+
cdp.assert_in = CDPM.assert_in
|
733
|
+
cdp.assert_not_in = CDPM.assert_not_in
|
734
|
+
cdp.scroll_into_view = CDPM.scroll_into_view
|
735
|
+
cdp.scroll_to_y = CDPM.scroll_to_y
|
736
|
+
cdp.scroll_to_top = CDPM.scroll_to_top
|
737
|
+
cdp.scroll_to_bottom = CDPM.scroll_to_bottom
|
738
|
+
cdp.scroll_up = CDPM.scroll_up
|
739
|
+
cdp.scroll_down = CDPM.scroll_down
|
740
|
+
cdp.save_screenshot = CDPM.save_screenshot
|
741
|
+
cdp.page = page # async world
|
742
|
+
cdp.driver = driver.cdp_base # async world
|
743
|
+
cdp.tab = cdp.page # shortcut (original)
|
744
|
+
cdp.browser = driver.cdp_base # shortcut (original)
|
745
|
+
cdp.util = cdp_util # shortcut (original)
|
746
|
+
core_items = types.SimpleNamespace()
|
747
|
+
core_items.browser = cdp.browser
|
748
|
+
core_items.tab = cdp.tab
|
749
|
+
core_items.util = cdp.util
|
750
|
+
cdp.core = core_items
|
751
|
+
cdp.loop = cdp.get_event_loop()
|
752
|
+
driver.cdp = cdp
|
753
|
+
driver._is_using_cdp = True
|
754
|
+
|
755
|
+
|
756
|
+
def uc_activate_cdp_mode(driver, url=None):
|
757
|
+
uc_open_with_cdp_mode(driver, url=url)
|
758
|
+
|
759
|
+
|
760
|
+
def uc_open_with_disconnect(driver, url, timeout=None):
|
761
|
+
"""Open a url and disconnect chromedriver.
|
762
|
+
Then waits for the duration of the timeout.
|
763
|
+
Note: You can't perform Selenium actions again
|
764
|
+
until after you've called driver.connect()."""
|
765
|
+
url = shared_utils.fix_url_as_needed(url)
|
766
|
+
if __is_cdp_swap_needed(driver):
|
767
|
+
driver.cdp.get(url)
|
768
|
+
time.sleep(0.3)
|
769
|
+
return
|
770
|
+
if not driver.is_connected():
|
771
|
+
driver.connect()
|
772
|
+
if (url.startswith("http:") or url.startswith("https:")):
|
773
|
+
script = 'window.open("%s","_blank");' % url
|
774
|
+
driver.execute_script(script)
|
775
|
+
time.sleep(0.05)
|
443
776
|
driver.close()
|
444
|
-
driver.
|
445
|
-
|
777
|
+
driver.disconnect()
|
778
|
+
min_timeout = 0.008
|
779
|
+
if timeout and not str(timeout).replace(".", "", 1).isdigit():
|
780
|
+
timeout = min_timeout
|
781
|
+
if not timeout or timeout < min_timeout:
|
782
|
+
timeout = min_timeout
|
783
|
+
time.sleep(timeout)
|
446
784
|
else:
|
447
785
|
driver.default_get(url) # The original one
|
448
786
|
return None
|
@@ -455,19 +793,25 @@ def uc_click(
|
|
455
793
|
timeout=settings.SMALL_TIMEOUT,
|
456
794
|
reconnect_time=None,
|
457
795
|
):
|
458
|
-
|
796
|
+
if __is_cdp_swap_needed(driver):
|
797
|
+
driver.cdp.click(selector)
|
798
|
+
return
|
799
|
+
with suppress(Exception):
|
459
800
|
rct = float(by) # Add shortcut: driver.uc_click(selector, RCT)
|
460
801
|
if not reconnect_time:
|
461
802
|
reconnect_time = rct
|
462
803
|
by = "css selector"
|
463
|
-
except Exception:
|
464
|
-
pass
|
465
804
|
element = driver.wait_for_selector(selector, by=by, timeout=timeout)
|
466
|
-
|
805
|
+
tag_name = element.tag_name
|
806
|
+
if not tag_name == "span" and not tag_name == "input": # Must be "visible"
|
467
807
|
element = driver.wait_for_element(selector, by=by, timeout=timeout)
|
468
808
|
try:
|
469
809
|
element.uc_click(
|
470
|
-
driver,
|
810
|
+
driver,
|
811
|
+
selector,
|
812
|
+
by=by,
|
813
|
+
reconnect_time=reconnect_time,
|
814
|
+
tag_name=tag_name,
|
471
815
|
)
|
472
816
|
except ElementClickInterceptedException:
|
473
817
|
time.sleep(0.16)
|
@@ -478,7 +822,801 @@ def uc_click(
|
|
478
822
|
driver.reconnect(reconnect_time)
|
479
823
|
|
480
824
|
|
481
|
-
def
|
825
|
+
def verify_pyautogui_has_a_headed_browser(driver):
|
826
|
+
"""PyAutoGUI requires a headed browser so that it can
|
827
|
+
focus on the correct element when performing actions."""
|
828
|
+
if hasattr(driver, "_is_hidden") and driver._is_hidden:
|
829
|
+
raise Exception(
|
830
|
+
"PyAutoGUI can't be used in headless mode!"
|
831
|
+
)
|
832
|
+
|
833
|
+
|
834
|
+
def __install_pyautogui_if_missing():
|
835
|
+
try:
|
836
|
+
import pyautogui
|
837
|
+
with suppress(Exception):
|
838
|
+
use_pyautogui_ver = constants.PyAutoGUI.VER
|
839
|
+
if pyautogui.__version__ != use_pyautogui_ver:
|
840
|
+
del pyautogui
|
841
|
+
shared_utils.pip_install(
|
842
|
+
"pyautogui", version=use_pyautogui_ver
|
843
|
+
)
|
844
|
+
import pyautogui
|
845
|
+
except Exception:
|
846
|
+
print("\nPyAutoGUI required! Installing now...")
|
847
|
+
shared_utils.pip_install(
|
848
|
+
"pyautogui", version=constants.PyAutoGUI.VER
|
849
|
+
)
|
850
|
+
try:
|
851
|
+
import pyautogui
|
852
|
+
except Exception:
|
853
|
+
if (
|
854
|
+
IS_LINUX
|
855
|
+
and hasattr(sb_config, "xvfb")
|
856
|
+
and hasattr(sb_config, "headed")
|
857
|
+
and hasattr(sb_config, "headless")
|
858
|
+
and hasattr(sb_config, "headless2")
|
859
|
+
and (not sb_config.headed or sb_config.xvfb)
|
860
|
+
and not (sb_config.headless or sb_config.headless2)
|
861
|
+
):
|
862
|
+
from sbvirtualdisplay import Display
|
863
|
+
xvfb_width = 1366
|
864
|
+
xvfb_height = 768
|
865
|
+
if (
|
866
|
+
hasattr(sb_config, "_xvfb_width")
|
867
|
+
and sb_config._xvfb_width
|
868
|
+
and isinstance(sb_config._xvfb_width, int)
|
869
|
+
and hasattr(sb_config, "_xvfb_height")
|
870
|
+
and sb_config._xvfb_height
|
871
|
+
and isinstance(sb_config._xvfb_height, int)
|
872
|
+
):
|
873
|
+
xvfb_width = sb_config._xvfb_width
|
874
|
+
xvfb_height = sb_config._xvfb_height
|
875
|
+
if xvfb_width < 1024:
|
876
|
+
xvfb_width = 1024
|
877
|
+
sb_config._xvfb_width = xvfb_width
|
878
|
+
if xvfb_height < 768:
|
879
|
+
xvfb_height = 768
|
880
|
+
sb_config._xvfb_height = xvfb_height
|
881
|
+
with suppress(Exception):
|
882
|
+
_xvfb_display = Display(
|
883
|
+
visible=True,
|
884
|
+
size=(xvfb_width, xvfb_height),
|
885
|
+
backend="xvfb",
|
886
|
+
use_xauth=True,
|
887
|
+
)
|
888
|
+
_xvfb_display.start()
|
889
|
+
sb_config._virtual_display = _xvfb_display
|
890
|
+
sb_config.headless_active = True
|
891
|
+
|
892
|
+
|
893
|
+
def install_pyautogui_if_missing(driver):
|
894
|
+
verify_pyautogui_has_a_headed_browser(driver)
|
895
|
+
pip_find_lock = fasteners.InterProcessLock(
|
896
|
+
constants.PipInstall.FINDLOCK
|
897
|
+
)
|
898
|
+
try:
|
899
|
+
with pip_find_lock:
|
900
|
+
pass
|
901
|
+
except Exception:
|
902
|
+
# Since missing permissions, skip the locks
|
903
|
+
__install_pyautogui_if_missing()
|
904
|
+
return
|
905
|
+
with pip_find_lock: # Prevent issues with multiple processes
|
906
|
+
with suppress(Exception):
|
907
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
908
|
+
__install_pyautogui_if_missing()
|
909
|
+
|
910
|
+
|
911
|
+
def get_configured_pyautogui(pyautogui_copy):
|
912
|
+
if (
|
913
|
+
IS_LINUX
|
914
|
+
and hasattr(pyautogui_copy, "_pyautogui_x11")
|
915
|
+
and "DISPLAY" in os.environ.keys()
|
916
|
+
):
|
917
|
+
if (
|
918
|
+
hasattr(sb_config, "_pyautogui_x11_display")
|
919
|
+
and sb_config._pyautogui_x11_display
|
920
|
+
and hasattr(pyautogui_copy._pyautogui_x11, "_display")
|
921
|
+
and (
|
922
|
+
sb_config._pyautogui_x11_display
|
923
|
+
== pyautogui_copy._pyautogui_x11._display
|
924
|
+
)
|
925
|
+
):
|
926
|
+
pass
|
927
|
+
else:
|
928
|
+
import Xlib.display
|
929
|
+
pyautogui_copy._pyautogui_x11._display = (
|
930
|
+
Xlib.display.Display(os.environ['DISPLAY'])
|
931
|
+
)
|
932
|
+
sb_config._pyautogui_x11_display = (
|
933
|
+
pyautogui_copy._pyautogui_x11._display
|
934
|
+
)
|
935
|
+
return pyautogui_copy
|
936
|
+
|
937
|
+
|
938
|
+
def uc_gui_press_key(driver, key):
|
939
|
+
install_pyautogui_if_missing(driver)
|
940
|
+
import pyautogui
|
941
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
942
|
+
gui_lock = fasteners.InterProcessLock(
|
943
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
944
|
+
)
|
945
|
+
with gui_lock:
|
946
|
+
pyautogui.press(key)
|
947
|
+
|
948
|
+
|
949
|
+
def uc_gui_press_keys(driver, keys):
|
950
|
+
install_pyautogui_if_missing(driver)
|
951
|
+
import pyautogui
|
952
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
953
|
+
gui_lock = fasteners.InterProcessLock(
|
954
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
955
|
+
)
|
956
|
+
with gui_lock:
|
957
|
+
for key in keys:
|
958
|
+
pyautogui.press(key)
|
959
|
+
|
960
|
+
|
961
|
+
def uc_gui_write(driver, text):
|
962
|
+
install_pyautogui_if_missing(driver)
|
963
|
+
import pyautogui
|
964
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
965
|
+
gui_lock = fasteners.InterProcessLock(
|
966
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
967
|
+
)
|
968
|
+
with gui_lock:
|
969
|
+
pyautogui.write(text)
|
970
|
+
|
971
|
+
|
972
|
+
def get_gui_element_position(driver, selector):
|
973
|
+
if __is_cdp_swap_needed(driver):
|
974
|
+
element_rect = driver.cdp.get_gui_element_rect(selector)
|
975
|
+
return (element_rect["x"], element_rect["y"])
|
976
|
+
element = driver.wait_for_element_present(selector, timeout=3)
|
977
|
+
element_rect = element.rect
|
978
|
+
window_rect = driver.get_window_rect()
|
979
|
+
window_bottom_y = window_rect["y"] + window_rect["height"]
|
980
|
+
viewport_height = driver.execute_script("return window.innerHeight;")
|
981
|
+
viewport_x = window_rect["x"] + element_rect["x"]
|
982
|
+
viewport_y = window_bottom_y - viewport_height + element_rect["y"]
|
983
|
+
y_scroll_offset = driver.execute_script("return window.pageYOffset;")
|
984
|
+
viewport_y = viewport_y - y_scroll_offset
|
985
|
+
return (viewport_x, viewport_y)
|
986
|
+
|
987
|
+
|
988
|
+
def _uc_gui_click_x_y(driver, x, y, timeframe=0.25, uc_lock=False):
|
989
|
+
install_pyautogui_if_missing(driver)
|
990
|
+
import pyautogui
|
991
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
992
|
+
screen_width, screen_height = pyautogui.size()
|
993
|
+
if x < 0 or y < 0 or x > screen_width or y > screen_height:
|
994
|
+
raise Exception(
|
995
|
+
"PyAutoGUI cannot click on point (%s, %s)"
|
996
|
+
" outside screen. (Width: %s, Height: %s)"
|
997
|
+
% (x, y, screen_width, screen_height)
|
998
|
+
)
|
999
|
+
if uc_lock:
|
1000
|
+
gui_lock = fasteners.InterProcessLock(
|
1001
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
1002
|
+
)
|
1003
|
+
with gui_lock: # Prevent issues with multiple processes
|
1004
|
+
pyautogui.moveTo(x, y, timeframe, pyautogui.easeOutQuad)
|
1005
|
+
if timeframe >= 0.25:
|
1006
|
+
time.sleep(0.056) # Wait if moving at human-speed
|
1007
|
+
if "--debug" in sys.argv:
|
1008
|
+
print(" <DEBUG> pyautogui.click(%s, %s)" % (x, y))
|
1009
|
+
pyautogui.click(x=x, y=y)
|
1010
|
+
else:
|
1011
|
+
# Called from a method where the gui_lock is already active
|
1012
|
+
pyautogui.moveTo(x, y, timeframe, pyautogui.easeOutQuad)
|
1013
|
+
if timeframe >= 0.25:
|
1014
|
+
time.sleep(0.056) # Wait if moving at human-speed
|
1015
|
+
if "--debug" in sys.argv:
|
1016
|
+
print(" <DEBUG> pyautogui.click(%s, %s)" % (x, y))
|
1017
|
+
pyautogui.click(x=x, y=y)
|
1018
|
+
|
1019
|
+
|
1020
|
+
def uc_gui_click_x_y(driver, x, y, timeframe=0.25):
|
1021
|
+
gui_lock = fasteners.InterProcessLock(
|
1022
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
1023
|
+
)
|
1024
|
+
with gui_lock: # Prevent issues with multiple processes
|
1025
|
+
install_pyautogui_if_missing(driver)
|
1026
|
+
import pyautogui
|
1027
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
1028
|
+
connected = True
|
1029
|
+
width_ratio = 1.0
|
1030
|
+
if IS_WINDOWS:
|
1031
|
+
connected = driver.is_connected()
|
1032
|
+
if (
|
1033
|
+
not connected
|
1034
|
+
and (
|
1035
|
+
not hasattr(sb_config, "_saved_width_ratio")
|
1036
|
+
or not sb_config._saved_width_ratio
|
1037
|
+
)
|
1038
|
+
and not __is_cdp_swap_needed(driver)
|
1039
|
+
):
|
1040
|
+
driver.reconnect(0.1)
|
1041
|
+
if IS_WINDOWS and not __is_cdp_swap_needed(driver):
|
1042
|
+
window_rect = driver.get_window_rect()
|
1043
|
+
width = window_rect["width"]
|
1044
|
+
height = window_rect["height"]
|
1045
|
+
win_x = window_rect["x"]
|
1046
|
+
win_y = window_rect["y"]
|
1047
|
+
scr_width = pyautogui.size().width
|
1048
|
+
driver.maximize_window()
|
1049
|
+
win_width = driver.get_window_size()["width"]
|
1050
|
+
width_ratio = round(float(scr_width) / float(win_width), 2) + 0.01
|
1051
|
+
if width_ratio < 0.45 or width_ratio > 2.55:
|
1052
|
+
width_ratio = 1.01
|
1053
|
+
sb_config._saved_width_ratio = width_ratio
|
1054
|
+
driver.minimize_window()
|
1055
|
+
driver.set_window_rect(win_x, win_y, width, height)
|
1056
|
+
elif IS_WINDOWS and __is_cdp_swap_needed(driver):
|
1057
|
+
window_rect = driver.cdp.get_window_rect()
|
1058
|
+
width = window_rect["width"]
|
1059
|
+
height = window_rect["height"]
|
1060
|
+
win_x = window_rect["x"]
|
1061
|
+
win_y = window_rect["y"]
|
1062
|
+
scr_width = pyautogui.size().width
|
1063
|
+
driver.cdp.maximize()
|
1064
|
+
win_width = driver.cdp.get_window_size()["width"]
|
1065
|
+
width_ratio = round(float(scr_width) / float(win_width), 2) + 0.01
|
1066
|
+
if width_ratio < 0.45 or width_ratio > 2.55:
|
1067
|
+
width_ratio = 1.01
|
1068
|
+
sb_config._saved_width_ratio = width_ratio
|
1069
|
+
driver.cdp.minimize()
|
1070
|
+
driver.cdp.set_window_rect(win_x, win_y, width, height)
|
1071
|
+
if IS_WINDOWS:
|
1072
|
+
x = x * width_ratio
|
1073
|
+
y = y * width_ratio
|
1074
|
+
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
|
1075
|
+
return
|
1076
|
+
with suppress(Exception):
|
1077
|
+
page_actions.switch_to_window(
|
1078
|
+
driver, driver.current_window_handle, 2, uc_lock=False
|
1079
|
+
)
|
1080
|
+
_uc_gui_click_x_y(driver, x, y, timeframe=timeframe, uc_lock=False)
|
1081
|
+
|
1082
|
+
|
1083
|
+
def _on_a_cf_turnstile_page(driver):
|
1084
|
+
source = driver.get_page_source()
|
1085
|
+
if (
|
1086
|
+
'data-callback="onCaptchaSuccess"' in source
|
1087
|
+
or "/challenge-platform/scripts/" in source
|
1088
|
+
or 'id="challenge-widget-' in source
|
1089
|
+
or "cf-turnstile-" in source
|
1090
|
+
):
|
1091
|
+
return True
|
1092
|
+
return False
|
1093
|
+
|
1094
|
+
|
1095
|
+
def _on_a_g_recaptcha_page(driver):
|
1096
|
+
source = driver.get_page_source()
|
1097
|
+
if (
|
1098
|
+
'id="recaptcha-token"' in source
|
1099
|
+
or 'title="reCAPTCHA"' in source
|
1100
|
+
):
|
1101
|
+
return True
|
1102
|
+
return False
|
1103
|
+
|
1104
|
+
|
1105
|
+
def _uc_gui_click_captcha(
|
1106
|
+
driver,
|
1107
|
+
frame="iframe",
|
1108
|
+
retry=False,
|
1109
|
+
blind=False,
|
1110
|
+
ctype=None,
|
1111
|
+
):
|
1112
|
+
cdp_mode_on_at_start = __is_cdp_swap_needed(driver)
|
1113
|
+
_on_a_captcha_page = None
|
1114
|
+
if ctype == "cf_t":
|
1115
|
+
if not _on_a_cf_turnstile_page(driver):
|
1116
|
+
return
|
1117
|
+
else:
|
1118
|
+
_on_a_captcha_page = _on_a_cf_turnstile_page
|
1119
|
+
elif ctype == "g_rc":
|
1120
|
+
if not _on_a_g_recaptcha_page(driver):
|
1121
|
+
return
|
1122
|
+
else:
|
1123
|
+
_on_a_captcha_page = _on_a_g_recaptcha_page
|
1124
|
+
else:
|
1125
|
+
if _on_a_g_recaptcha_page(driver):
|
1126
|
+
ctype = "g_rc"
|
1127
|
+
_on_a_captcha_page = _on_a_g_recaptcha_page
|
1128
|
+
elif _on_a_cf_turnstile_page(driver):
|
1129
|
+
ctype = "cf_t"
|
1130
|
+
_on_a_captcha_page = _on_a_cf_turnstile_page
|
1131
|
+
else:
|
1132
|
+
return
|
1133
|
+
install_pyautogui_if_missing(driver)
|
1134
|
+
import pyautogui
|
1135
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
1136
|
+
i_x = None
|
1137
|
+
i_y = None
|
1138
|
+
x = None
|
1139
|
+
y = None
|
1140
|
+
visible_iframe = True
|
1141
|
+
gui_lock = fasteners.InterProcessLock(
|
1142
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
1143
|
+
)
|
1144
|
+
with gui_lock: # Prevent issues with multiple processes
|
1145
|
+
needs_switch = False
|
1146
|
+
width_ratio = 1.0
|
1147
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
1148
|
+
if is_in_frame and driver.is_element_present("#challenge-stage"):
|
1149
|
+
driver.switch_to.parent_frame()
|
1150
|
+
needs_switch = True
|
1151
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
1152
|
+
if not is_in_frame:
|
1153
|
+
# Make sure the window is on top
|
1154
|
+
if __is_cdp_swap_needed(driver):
|
1155
|
+
driver.cdp.bring_active_window_to_front()
|
1156
|
+
else:
|
1157
|
+
page_actions.switch_to_window(
|
1158
|
+
driver, driver.current_window_handle, 2, uc_lock=False
|
1159
|
+
)
|
1160
|
+
if IS_WINDOWS and not __is_cdp_swap_needed(driver):
|
1161
|
+
window_rect = driver.get_window_rect()
|
1162
|
+
width = window_rect["width"]
|
1163
|
+
height = window_rect["height"]
|
1164
|
+
win_x = window_rect["x"]
|
1165
|
+
win_y = window_rect["y"]
|
1166
|
+
scr_width = pyautogui.size().width
|
1167
|
+
driver.maximize_window()
|
1168
|
+
win_width = driver.get_window_size()["width"]
|
1169
|
+
width_ratio = round(float(scr_width) / float(win_width), 2) + 0.01
|
1170
|
+
if width_ratio < 0.45 or width_ratio > 2.55:
|
1171
|
+
width_ratio = 1.01
|
1172
|
+
sb_config._saved_width_ratio = width_ratio
|
1173
|
+
driver.minimize_window()
|
1174
|
+
driver.set_window_rect(win_x, win_y, width, height)
|
1175
|
+
elif IS_WINDOWS and __is_cdp_swap_needed(driver):
|
1176
|
+
window_rect = driver.cdp.get_window_rect()
|
1177
|
+
width = window_rect["width"]
|
1178
|
+
height = window_rect["height"]
|
1179
|
+
win_x = window_rect["x"]
|
1180
|
+
win_y = window_rect["y"]
|
1181
|
+
scr_width = pyautogui.size().width
|
1182
|
+
driver.cdp.maximize()
|
1183
|
+
win_width = driver.cdp.get_window_size()["width"]
|
1184
|
+
width_ratio = round(float(scr_width) / float(win_width), 2) + 0.01
|
1185
|
+
if width_ratio < 0.45 or width_ratio > 2.55:
|
1186
|
+
width_ratio = 1.01
|
1187
|
+
sb_config._saved_width_ratio = width_ratio
|
1188
|
+
driver.cdp.minimize()
|
1189
|
+
driver.cdp.set_window_rect(win_x, win_y, width, height)
|
1190
|
+
if ctype == "cf_t":
|
1191
|
+
if (
|
1192
|
+
driver.is_element_present(".cf-turnstile-wrapper iframe")
|
1193
|
+
or driver.is_element_present(
|
1194
|
+
'[data-callback="onCaptchaSuccess"] iframe'
|
1195
|
+
)
|
1196
|
+
):
|
1197
|
+
pass
|
1198
|
+
else:
|
1199
|
+
visible_iframe = False
|
1200
|
+
if (
|
1201
|
+
frame != "iframe"
|
1202
|
+
and driver.is_element_present(
|
1203
|
+
"%s .cf-turnstile-wrapper" % frame
|
1204
|
+
)
|
1205
|
+
):
|
1206
|
+
frame = "%s .cf-turnstile-wrapper" % frame
|
1207
|
+
elif (
|
1208
|
+
frame != "iframe"
|
1209
|
+
and driver.is_element_present(
|
1210
|
+
'%s [name*="cf-turnstile"]' % frame
|
1211
|
+
)
|
1212
|
+
and driver.is_element_present("%s div" % frame)
|
1213
|
+
):
|
1214
|
+
frame = "%s div" % frame
|
1215
|
+
elif (
|
1216
|
+
driver.is_element_present('[name*="cf-turnstile-"]')
|
1217
|
+
and driver.is_element_present("#challenge-form div > div")
|
1218
|
+
):
|
1219
|
+
frame = "#challenge-form div > div"
|
1220
|
+
elif (
|
1221
|
+
driver.is_element_present('[name*="cf-turnstile-"]')
|
1222
|
+
and driver.is_element_present("[class*=spacer] + div div")
|
1223
|
+
):
|
1224
|
+
frame = '[class*=spacer] + div div'
|
1225
|
+
elif (
|
1226
|
+
driver.is_element_present('[name*="cf-turnstile-"]')
|
1227
|
+
and driver.is_element_present("div.spacer div")
|
1228
|
+
):
|
1229
|
+
frame = "div.spacer div"
|
1230
|
+
elif (
|
1231
|
+
driver.is_element_present('script[src*="challenges.c"]')
|
1232
|
+
and driver.is_element_present(
|
1233
|
+
'[data-testid*="challenge-"] div'
|
1234
|
+
)
|
1235
|
+
):
|
1236
|
+
frame = '[data-testid*="challenge-"] div'
|
1237
|
+
elif driver.is_element_present(
|
1238
|
+
'form div:not([class]):has(input[name*="cf-turn"])'
|
1239
|
+
):
|
1240
|
+
frame = 'form div:not([class]):has(input[name*="cf-turn"])'
|
1241
|
+
elif (
|
1242
|
+
driver.is_element_present('[src*="/turnstile/"]')
|
1243
|
+
and driver.is_element_present("form div:not(:has(*))")
|
1244
|
+
):
|
1245
|
+
frame = "form div:not(:has(*))"
|
1246
|
+
elif driver.is_element_present(".cf-turnstile-wrapper"):
|
1247
|
+
frame = ".cf-turnstile-wrapper"
|
1248
|
+
elif driver.is_element_present(
|
1249
|
+
'[data-callback="onCaptchaSuccess"]'
|
1250
|
+
):
|
1251
|
+
frame = '[data-callback="onCaptchaSuccess"]'
|
1252
|
+
else:
|
1253
|
+
return
|
1254
|
+
if (
|
1255
|
+
driver.is_element_present("form")
|
1256
|
+
and (
|
1257
|
+
driver.is_element_present('form[class*="center"]')
|
1258
|
+
or driver.is_element_present('form[class*="right"]')
|
1259
|
+
or driver.is_element_present('form div[class*="center"]')
|
1260
|
+
or driver.is_element_present('form div[class*="right"]')
|
1261
|
+
)
|
1262
|
+
):
|
1263
|
+
script = (
|
1264
|
+
"""var $elements = document.querySelectorAll(
|
1265
|
+
'form[class], form div[class]');
|
1266
|
+
var index = 0, length = $elements.length;
|
1267
|
+
for(; index < length; index++){
|
1268
|
+
the_class = $elements[index].getAttribute('class');
|
1269
|
+
new_class = the_class.replaceAll('center', 'left');
|
1270
|
+
new_class = new_class.replaceAll('right', 'left');
|
1271
|
+
$elements[index].setAttribute('class', new_class);}"""
|
1272
|
+
)
|
1273
|
+
if __is_cdp_swap_needed(driver):
|
1274
|
+
driver.cdp.evaluate(script)
|
1275
|
+
else:
|
1276
|
+
driver.execute_script(script)
|
1277
|
+
if not is_in_frame or needs_switch:
|
1278
|
+
# Currently not in frame (or nested frame outside CF one)
|
1279
|
+
try:
|
1280
|
+
i_x, i_y = get_gui_element_position(driver, frame)
|
1281
|
+
if visible_iframe:
|
1282
|
+
driver.switch_to_frame(frame)
|
1283
|
+
except Exception:
|
1284
|
+
if visible_iframe:
|
1285
|
+
if driver.is_element_present("iframe"):
|
1286
|
+
i_x, i_y = get_gui_element_position(driver, "iframe")
|
1287
|
+
if driver.is_connected():
|
1288
|
+
driver.switch_to_frame("iframe")
|
1289
|
+
else:
|
1290
|
+
return
|
1291
|
+
if not i_x or not i_y:
|
1292
|
+
return
|
1293
|
+
try:
|
1294
|
+
if ctype == "g_rc" and not driver.is_connected():
|
1295
|
+
x = (i_x + 29) * width_ratio
|
1296
|
+
y = (i_y + 35) * width_ratio
|
1297
|
+
elif visible_iframe:
|
1298
|
+
selector = "span"
|
1299
|
+
if ctype == "g_rc":
|
1300
|
+
selector = "span.recaptcha-checkbox"
|
1301
|
+
if not driver.is_connected():
|
1302
|
+
selector = "iframe"
|
1303
|
+
element = driver.wait_for_element_present(
|
1304
|
+
selector, timeout=2.5
|
1305
|
+
)
|
1306
|
+
x = i_x + element.rect["x"] + (element.rect["width"] / 2.0)
|
1307
|
+
x += 0.5
|
1308
|
+
y = i_y + element.rect["y"] + (element.rect["height"] / 2.0)
|
1309
|
+
y += 0.5
|
1310
|
+
else:
|
1311
|
+
x = (i_x + 32) * width_ratio
|
1312
|
+
y = (i_y + 32) * width_ratio
|
1313
|
+
if driver.is_connected():
|
1314
|
+
driver.switch_to.default_content()
|
1315
|
+
except Exception:
|
1316
|
+
if driver.is_connected():
|
1317
|
+
try:
|
1318
|
+
driver.switch_to.default_content()
|
1319
|
+
except Exception:
|
1320
|
+
return
|
1321
|
+
if x and y:
|
1322
|
+
sb_config._saved_cf_x_y = (x, y)
|
1323
|
+
if not __is_cdp_swap_needed(driver):
|
1324
|
+
if driver.is_element_present(".footer .clearfix .ray-id"):
|
1325
|
+
driver.uc_open_with_disconnect(
|
1326
|
+
driver.get_current_url(), 3.8
|
1327
|
+
)
|
1328
|
+
else:
|
1329
|
+
driver.disconnect()
|
1330
|
+
with suppress(Exception):
|
1331
|
+
_uc_gui_click_x_y(driver, x, y, timeframe=0.32)
|
1332
|
+
if __is_cdp_swap_needed(driver):
|
1333
|
+
time.sleep(float(constants.UC.RECONNECT_TIME) / 2.0)
|
1334
|
+
return
|
1335
|
+
reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.6
|
1336
|
+
if IS_LINUX:
|
1337
|
+
reconnect_time = constants.UC.RECONNECT_TIME + 0.2
|
1338
|
+
if not x or not y:
|
1339
|
+
reconnect_time = 1 # Make it quick (it already failed)
|
1340
|
+
driver.reconnect(reconnect_time)
|
1341
|
+
caught = False
|
1342
|
+
if (
|
1343
|
+
driver.is_element_present(".footer .clearfix .ray-id")
|
1344
|
+
and not driver.is_element_visible("#challenge-success-text")
|
1345
|
+
):
|
1346
|
+
blind = True
|
1347
|
+
caught = True
|
1348
|
+
if blind:
|
1349
|
+
retry = True
|
1350
|
+
if retry and x and y and (caught or _on_a_captcha_page(driver)):
|
1351
|
+
with gui_lock: # Prevent issues with multiple processes
|
1352
|
+
# Make sure the window is on top
|
1353
|
+
if __is_cdp_swap_needed(driver):
|
1354
|
+
driver.cdp.bring_active_window_to_front()
|
1355
|
+
else:
|
1356
|
+
page_actions.switch_to_window(
|
1357
|
+
driver, driver.current_window_handle, 2, uc_lock=False
|
1358
|
+
)
|
1359
|
+
if driver.is_element_present("iframe"):
|
1360
|
+
try:
|
1361
|
+
driver.switch_to_frame(frame)
|
1362
|
+
except Exception:
|
1363
|
+
try:
|
1364
|
+
driver.switch_to_frame("iframe")
|
1365
|
+
except Exception:
|
1366
|
+
return
|
1367
|
+
checkbox_success = None
|
1368
|
+
if ctype == "cf_t":
|
1369
|
+
checkbox_success = "#success-icon"
|
1370
|
+
elif ctype == "g_rc":
|
1371
|
+
checkbox_success = "span.recaptcha-checkbox-checked"
|
1372
|
+
else:
|
1373
|
+
return # If this line is reached, ctype wasn't set
|
1374
|
+
if driver.is_element_visible("#success-icon"):
|
1375
|
+
driver.switch_to.parent_frame(checkbox_success)
|
1376
|
+
return
|
1377
|
+
if blind:
|
1378
|
+
driver.uc_open_with_disconnect(driver.get_current_url(), 3.8)
|
1379
|
+
if __is_cdp_swap_needed(driver) and _on_a_captcha_page(driver):
|
1380
|
+
_uc_gui_click_x_y(driver, x, y, timeframe=0.32)
|
1381
|
+
else:
|
1382
|
+
time.sleep(0.1)
|
1383
|
+
else:
|
1384
|
+
driver.uc_open_with_reconnect(driver.get_current_url(), 3.8)
|
1385
|
+
if _on_a_captcha_page(driver):
|
1386
|
+
driver.disconnect()
|
1387
|
+
_uc_gui_click_x_y(driver, x, y, timeframe=0.32)
|
1388
|
+
if not cdp_mode_on_at_start:
|
1389
|
+
driver.reconnect(reconnect_time)
|
1390
|
+
|
1391
|
+
|
1392
|
+
def uc_gui_click_captcha(driver, frame="iframe", retry=False, blind=False):
|
1393
|
+
_uc_gui_click_captcha(
|
1394
|
+
driver,
|
1395
|
+
frame=frame,
|
1396
|
+
retry=retry,
|
1397
|
+
blind=blind,
|
1398
|
+
ctype=None,
|
1399
|
+
)
|
1400
|
+
|
1401
|
+
|
1402
|
+
def uc_gui_click_rc(driver, frame="iframe", retry=False, blind=False):
|
1403
|
+
_uc_gui_click_captcha(
|
1404
|
+
driver,
|
1405
|
+
frame=frame,
|
1406
|
+
retry=retry,
|
1407
|
+
blind=blind,
|
1408
|
+
ctype="g_rc",
|
1409
|
+
)
|
1410
|
+
|
1411
|
+
|
1412
|
+
def uc_gui_click_cf(driver, frame="iframe", retry=False, blind=False):
|
1413
|
+
_uc_gui_click_captcha(
|
1414
|
+
driver,
|
1415
|
+
frame=frame,
|
1416
|
+
retry=retry,
|
1417
|
+
blind=blind,
|
1418
|
+
ctype="cf_t",
|
1419
|
+
)
|
1420
|
+
|
1421
|
+
|
1422
|
+
def _uc_gui_handle_captcha_(driver, frame="iframe", ctype=None):
|
1423
|
+
if ctype == "cf_t":
|
1424
|
+
if not _on_a_cf_turnstile_page(driver):
|
1425
|
+
return
|
1426
|
+
elif ctype == "g_rc":
|
1427
|
+
if not _on_a_g_recaptcha_page(driver):
|
1428
|
+
return
|
1429
|
+
else:
|
1430
|
+
if _on_a_g_recaptcha_page(driver):
|
1431
|
+
ctype = "g_rc"
|
1432
|
+
elif _on_a_cf_turnstile_page(driver):
|
1433
|
+
ctype = "cf_t"
|
1434
|
+
else:
|
1435
|
+
return
|
1436
|
+
if not driver.is_connected() and not __is_cdp_swap_needed(driver):
|
1437
|
+
driver.connect()
|
1438
|
+
time.sleep(2)
|
1439
|
+
install_pyautogui_if_missing(driver)
|
1440
|
+
import pyautogui
|
1441
|
+
pyautogui = get_configured_pyautogui(pyautogui)
|
1442
|
+
visible_iframe = True
|
1443
|
+
gui_lock = fasteners.InterProcessLock(
|
1444
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
1445
|
+
)
|
1446
|
+
with gui_lock: # Prevent issues with multiple processes
|
1447
|
+
needs_switch = False
|
1448
|
+
if not __is_cdp_swap_needed(driver):
|
1449
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
1450
|
+
else:
|
1451
|
+
is_in_frame = False
|
1452
|
+
selector = "#challenge-stage"
|
1453
|
+
if ctype == "g_rc":
|
1454
|
+
selector = "#recaptcha-token"
|
1455
|
+
if is_in_frame and driver.is_element_present(selector):
|
1456
|
+
driver.switch_to.parent_frame()
|
1457
|
+
needs_switch = True
|
1458
|
+
is_in_frame = js_utils.is_in_frame(driver)
|
1459
|
+
if not is_in_frame and not __is_cdp_swap_needed(driver):
|
1460
|
+
# Make sure the window is on top
|
1461
|
+
page_actions.switch_to_window(
|
1462
|
+
driver, driver.current_window_handle, 2, uc_lock=False
|
1463
|
+
)
|
1464
|
+
if IS_WINDOWS and hasattr(pyautogui, "getActiveWindowTitle"):
|
1465
|
+
py_a_g_title = pyautogui.getActiveWindowTitle() or ""
|
1466
|
+
window_title = driver.get_title()
|
1467
|
+
if not py_a_g_title.startswith(window_title):
|
1468
|
+
window_rect = driver.get_window_rect()
|
1469
|
+
width = window_rect["width"]
|
1470
|
+
height = window_rect["height"]
|
1471
|
+
win_x = window_rect["x"]
|
1472
|
+
win_y = window_rect["y"]
|
1473
|
+
driver.minimize_window()
|
1474
|
+
driver.set_window_rect(win_x, win_y, width, height)
|
1475
|
+
time.sleep(0.33)
|
1476
|
+
tab_up_first = False
|
1477
|
+
special_form = False
|
1478
|
+
if ctype == "cf_t":
|
1479
|
+
if (
|
1480
|
+
driver.is_element_present(".cf-turnstile-wrapper iframe")
|
1481
|
+
or driver.is_element_present(
|
1482
|
+
'[data-callback="onCaptchaSuccess"] iframe'
|
1483
|
+
)
|
1484
|
+
):
|
1485
|
+
pass
|
1486
|
+
else:
|
1487
|
+
visible_iframe = False
|
1488
|
+
if driver.is_element_present(".cf-turnstile-wrapper"):
|
1489
|
+
frame = ".cf-turnstile-wrapper"
|
1490
|
+
elif driver.is_element_present(
|
1491
|
+
'[data-callback="onCaptchaSuccess"]'
|
1492
|
+
):
|
1493
|
+
frame = '[data-callback="onCaptchaSuccess"]'
|
1494
|
+
elif (
|
1495
|
+
driver.is_element_present('[name*="cf-turnstile-"]')
|
1496
|
+
and driver.is_element_present("div.spacer div")
|
1497
|
+
):
|
1498
|
+
frame = "div.spacer div"
|
1499
|
+
elif (
|
1500
|
+
driver.is_element_present('script[src*="challenges.c"]')
|
1501
|
+
and driver.is_element_present(
|
1502
|
+
'[data-testid*="challenge-"] div'
|
1503
|
+
)
|
1504
|
+
):
|
1505
|
+
frame = '[data-testid*="challenge-"] div'
|
1506
|
+
elif driver.is_element_present(
|
1507
|
+
'form div:not([class]):has(input[name*="cf-turn"])'
|
1508
|
+
):
|
1509
|
+
frame = 'form div:not([class]):has(input[name*="cf-turn"])'
|
1510
|
+
tab_up_first = True
|
1511
|
+
special_form = True
|
1512
|
+
elif (
|
1513
|
+
driver.is_element_present('[src*="/turnstile/"]')
|
1514
|
+
and driver.is_element_present("form div:not(:has(*))")
|
1515
|
+
):
|
1516
|
+
frame = "form div:not(:has(*))"
|
1517
|
+
tab_up_first = True
|
1518
|
+
else:
|
1519
|
+
return
|
1520
|
+
else:
|
1521
|
+
if (
|
1522
|
+
driver.is_element_present('iframe[title="reCAPTCHA"]')
|
1523
|
+
and frame == "iframe"
|
1524
|
+
):
|
1525
|
+
frame = 'iframe[title="reCAPTCHA"]'
|
1526
|
+
if not __is_cdp_swap_needed(driver):
|
1527
|
+
if not is_in_frame or needs_switch:
|
1528
|
+
# Currently not in frame (or nested frame outside CF one)
|
1529
|
+
try:
|
1530
|
+
if visible_iframe or ctype == "g_rc":
|
1531
|
+
driver.switch_to_frame(frame)
|
1532
|
+
except Exception:
|
1533
|
+
if visible_iframe or ctype == "g_rc":
|
1534
|
+
if driver.is_element_present("iframe"):
|
1535
|
+
driver.switch_to_frame("iframe")
|
1536
|
+
else:
|
1537
|
+
return
|
1538
|
+
try:
|
1539
|
+
selector = "div.cf-turnstile"
|
1540
|
+
if ctype == "g_rc":
|
1541
|
+
selector = "span#recaptcha-anchor"
|
1542
|
+
found_checkbox = False
|
1543
|
+
if tab_up_first:
|
1544
|
+
for i in range(10):
|
1545
|
+
pyautogui.hotkey("shift", "tab")
|
1546
|
+
time.sleep(0.027)
|
1547
|
+
if ctype == "g_rc":
|
1548
|
+
if js_utils.get_active_element_css(driver) == "body":
|
1549
|
+
break
|
1550
|
+
tab_count = 0
|
1551
|
+
for i in range(34):
|
1552
|
+
pyautogui.press("\t")
|
1553
|
+
tab_count += 1
|
1554
|
+
time.sleep(0.027)
|
1555
|
+
active_element_css = js_utils.get_active_element_css(driver)
|
1556
|
+
if (
|
1557
|
+
active_element_css.startswith(selector)
|
1558
|
+
or active_element_css.endswith(" > div" * 2)
|
1559
|
+
or (special_form and active_element_css.endswith(" div"))
|
1560
|
+
or (ctype == "g_rc" and "frame[name" in active_element_css)
|
1561
|
+
):
|
1562
|
+
found_checkbox = True
|
1563
|
+
sb_config._saved_cf_tab_count = tab_count
|
1564
|
+
break
|
1565
|
+
time.sleep(0.02)
|
1566
|
+
if not found_checkbox:
|
1567
|
+
return
|
1568
|
+
except Exception:
|
1569
|
+
try:
|
1570
|
+
driver.switch_to.default_content()
|
1571
|
+
except Exception:
|
1572
|
+
return
|
1573
|
+
if (
|
1574
|
+
(
|
1575
|
+
driver.is_element_present(".footer .clearfix .ray-id")
|
1576
|
+
or driver.is_element_present("script[data-cf-beacon]")
|
1577
|
+
)
|
1578
|
+
and hasattr(sb_config, "_saved_cf_tab_count")
|
1579
|
+
and sb_config._saved_cf_tab_count
|
1580
|
+
and not __is_cdp_swap_needed(driver)
|
1581
|
+
):
|
1582
|
+
driver.uc_open_with_disconnect(driver.current_url, 3.8)
|
1583
|
+
with suppress(Exception):
|
1584
|
+
for i in range(sb_config._saved_cf_tab_count):
|
1585
|
+
pyautogui.press("\t")
|
1586
|
+
time.sleep(0.027)
|
1587
|
+
pyautogui.press(" ")
|
1588
|
+
else:
|
1589
|
+
driver.disconnect()
|
1590
|
+
pyautogui.press(" ")
|
1591
|
+
reconnect_time = (float(constants.UC.RECONNECT_TIME) / 2.0) + 0.6
|
1592
|
+
if IS_LINUX:
|
1593
|
+
reconnect_time = constants.UC.RECONNECT_TIME + 0.2
|
1594
|
+
driver.reconnect(reconnect_time)
|
1595
|
+
|
1596
|
+
|
1597
|
+
def _uc_gui_handle_captcha(driver, frame="iframe", ctype=None):
|
1598
|
+
_uc_gui_handle_captcha_(driver, frame=frame, ctype=ctype)
|
1599
|
+
if (
|
1600
|
+
driver.is_element_present(".footer .clearfix .ray-id")
|
1601
|
+
and not driver.is_element_visible("#challenge-success-text")
|
1602
|
+
):
|
1603
|
+
driver.uc_open_with_reconnect(driver.current_url, 3.8)
|
1604
|
+
_uc_gui_handle_captcha_(driver, frame=frame, ctype=ctype)
|
1605
|
+
|
1606
|
+
|
1607
|
+
def uc_gui_handle_captcha(driver, frame="iframe"):
|
1608
|
+
_uc_gui_handle_captcha(driver, frame=frame, ctype=None)
|
1609
|
+
|
1610
|
+
|
1611
|
+
def uc_gui_handle_cf(driver, frame="iframe"):
|
1612
|
+
_uc_gui_handle_captcha(driver, frame=frame, ctype="cf_t")
|
1613
|
+
|
1614
|
+
|
1615
|
+
def uc_gui_handle_rc(driver, frame="iframe"):
|
1616
|
+
_uc_gui_handle_captcha(driver, frame=frame, ctype="g_rc")
|
1617
|
+
|
1618
|
+
|
1619
|
+
def uc_switch_to_frame(driver, frame="iframe", reconnect_time=None):
|
482
1620
|
from selenium.webdriver.remote.webelement import WebElement
|
483
1621
|
if isinstance(frame, WebElement):
|
484
1622
|
if not reconnect_time:
|
@@ -654,22 +1792,34 @@ def _add_chrome_proxy_extension(
|
|
654
1792
|
):
|
655
1793
|
# Single-threaded
|
656
1794
|
if zip_it:
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
1795
|
+
proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
|
1796
|
+
with proxy_zip_lock:
|
1797
|
+
proxy_helper.create_proxy_ext(
|
1798
|
+
proxy_string, proxy_user, proxy_pass, bypass_list
|
1799
|
+
)
|
1800
|
+
proxy_zip = proxy_helper.PROXY_ZIP_PATH
|
1801
|
+
chrome_options.add_extension(proxy_zip)
|
662
1802
|
else:
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
1803
|
+
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
1804
|
+
with proxy_dir_lock:
|
1805
|
+
proxy_helper.create_proxy_ext(
|
1806
|
+
proxy_string,
|
1807
|
+
proxy_user,
|
1808
|
+
proxy_pass,
|
1809
|
+
bypass_list,
|
1810
|
+
zip_it=False,
|
1811
|
+
)
|
1812
|
+
proxy_dir_path = proxy_helper.PROXY_DIR_PATH
|
1813
|
+
chrome_options = add_chrome_ext_dir(
|
1814
|
+
chrome_options, proxy_dir_path
|
1815
|
+
)
|
668
1816
|
else:
|
669
1817
|
# Multi-threaded
|
670
1818
|
if zip_it:
|
671
1819
|
proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
|
672
1820
|
with proxy_zip_lock:
|
1821
|
+
with suppress(Exception):
|
1822
|
+
shared_utils.make_writable(PROXY_ZIP_LOCK)
|
673
1823
|
if multi_proxy:
|
674
1824
|
_set_proxy_filenames()
|
675
1825
|
if not os.path.exists(proxy_helper.PROXY_ZIP_PATH):
|
@@ -681,6 +1831,8 @@ def _add_chrome_proxy_extension(
|
|
681
1831
|
else:
|
682
1832
|
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
683
1833
|
with proxy_dir_lock:
|
1834
|
+
with suppress(Exception):
|
1835
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
684
1836
|
if multi_proxy:
|
685
1837
|
_set_proxy_filenames()
|
686
1838
|
if not os.path.exists(proxy_helper.PROXY_DIR_PATH):
|
@@ -689,7 +1841,7 @@ def _add_chrome_proxy_extension(
|
|
689
1841
|
proxy_user,
|
690
1842
|
proxy_pass,
|
691
1843
|
bypass_list,
|
692
|
-
False,
|
1844
|
+
zip_it=False,
|
693
1845
|
)
|
694
1846
|
chrome_options = add_chrome_ext_dir(
|
695
1847
|
chrome_options, proxy_helper.PROXY_DIR_PATH
|
@@ -706,6 +1858,8 @@ def is_using_uc(undetectable, browser_name):
|
|
706
1858
|
def _unzip_to_new_folder(zip_file, folder):
|
707
1859
|
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
708
1860
|
with proxy_dir_lock:
|
1861
|
+
with suppress(Exception):
|
1862
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
709
1863
|
if not os.path.exists(folder):
|
710
1864
|
import zipfile
|
711
1865
|
zip_ref = zipfile.ZipFile(zip_file, "r")
|
@@ -765,6 +1919,7 @@ def _set_chrome_options(
|
|
765
1919
|
multi_proxy,
|
766
1920
|
user_agent,
|
767
1921
|
recorder_ext,
|
1922
|
+
disable_cookies,
|
768
1923
|
disable_js,
|
769
1924
|
disable_csp,
|
770
1925
|
enable_ws,
|
@@ -776,6 +1931,7 @@ def _set_chrome_options(
|
|
776
1931
|
log_cdp_events,
|
777
1932
|
no_sandbox,
|
778
1933
|
disable_gpu,
|
1934
|
+
headless1,
|
779
1935
|
headless2,
|
780
1936
|
incognito,
|
781
1937
|
guest_mode,
|
@@ -812,11 +1968,12 @@ def _set_chrome_options(
|
|
812
1968
|
chrome_options = webdriver.edge.options.Options()
|
813
1969
|
prefs = {}
|
814
1970
|
prefs["download.default_directory"] = downloads_path
|
815
|
-
prefs["local_discovery.notifications_enabled"] = False
|
816
|
-
prefs["credentials_enable_service"] = False
|
817
|
-
prefs["download.prompt_for_download"] = False
|
818
1971
|
prefs["download.directory_upgrade"] = True
|
819
|
-
prefs["
|
1972
|
+
prefs["download.prompt_for_download"] = False
|
1973
|
+
prefs["credentials_enable_service"] = False
|
1974
|
+
prefs["local_discovery.notifications_enabled"] = False
|
1975
|
+
prefs["safebrowsing.enabled"] = False # Prevent PW "data breach" pop-ups
|
1976
|
+
prefs["safebrowsing.disable_download_protection"] = True
|
820
1977
|
prefs["omnibox-max-zero-suggest-matches"] = 0
|
821
1978
|
prefs["omnibox-use-existing-autocomplete-client"] = 0
|
822
1979
|
prefs["omnibox-trending-zero-prefix-suggestions-on-ntp"] = 0
|
@@ -827,12 +1984,12 @@ def _set_chrome_options(
|
|
827
1984
|
prefs["omnibox-zero-suggest-prefetching-on-srp"] = 0
|
828
1985
|
prefs["omnibox-zero-suggest-prefetching-on-web"] = 0
|
829
1986
|
prefs["omnibox-zero-suggest-in-memory-caching"] = 0
|
830
|
-
prefs["default_content_setting_values.notifications"] = 0
|
831
1987
|
prefs["content_settings.exceptions.automatic_downloads.*.setting"] = 1
|
832
|
-
prefs["
|
1988
|
+
prefs["default_content_setting_values.notifications"] = 0
|
833
1989
|
prefs["default_content_settings.popups"] = 0
|
834
1990
|
prefs["managed_default_content_settings.popups"] = 0
|
835
1991
|
prefs["profile.password_manager_enabled"] = False
|
1992
|
+
prefs["profile.password_manager_leak_detection"] = False
|
836
1993
|
prefs["profile.default_content_setting_values.notifications"] = 2
|
837
1994
|
prefs["profile.default_content_settings.popups"] = 0
|
838
1995
|
prefs["profile.managed_default_content_settings.popups"] = 0
|
@@ -841,6 +1998,8 @@ def _set_chrome_options(
|
|
841
1998
|
prefs["intl.accept_languages"] = locale_code
|
842
1999
|
if block_images:
|
843
2000
|
prefs["profile.managed_default_content_settings.images"] = 2
|
2001
|
+
if disable_cookies:
|
2002
|
+
prefs["profile.default_content_setting_values.cookies"] = 2
|
844
2003
|
if disable_js:
|
845
2004
|
prefs["profile.managed_default_content_settings.javascript"] = 2
|
846
2005
|
if do_not_track:
|
@@ -878,7 +2037,7 @@ def _set_chrome_options(
|
|
878
2037
|
if (
|
879
2038
|
isinstance(device_width, int)
|
880
2039
|
and isinstance(device_height, int)
|
881
|
-
and isinstance(device_pixel_ratio, int)
|
2040
|
+
and isinstance(device_pixel_ratio, (int, float))
|
882
2041
|
):
|
883
2042
|
device_metrics["width"] = device_width
|
884
2043
|
device_metrics["height"] = device_height
|
@@ -893,18 +2052,49 @@ def _set_chrome_options(
|
|
893
2052
|
chrome_options.add_experimental_option(
|
894
2053
|
"mobileEmulation", emulator_settings
|
895
2054
|
)
|
2055
|
+
# Handle Window Position
|
2056
|
+
if (headless or headless2) and IS_WINDOWS:
|
2057
|
+
# https://stackoverflow.com/a/78999088/7058266
|
2058
|
+
chrome_options.add_argument("--window-position=-2400,-2400")
|
2059
|
+
else:
|
2060
|
+
if (
|
2061
|
+
hasattr(settings, "WINDOW_START_X")
|
2062
|
+
and isinstance(settings.WINDOW_START_X, int)
|
2063
|
+
and hasattr(settings, "WINDOW_START_Y")
|
2064
|
+
and isinstance(settings.WINDOW_START_Y, int)
|
2065
|
+
):
|
2066
|
+
chrome_options.add_argument(
|
2067
|
+
"--window-position=%s,%s" % (
|
2068
|
+
settings.WINDOW_START_X, settings.WINDOW_START_Y
|
2069
|
+
)
|
2070
|
+
)
|
2071
|
+
# Handle Window Size
|
896
2072
|
if headless or headless2:
|
897
|
-
|
898
|
-
"
|
899
|
-
|
2073
|
+
if (
|
2074
|
+
hasattr(settings, "HEADLESS_START_WIDTH")
|
2075
|
+
and isinstance(settings.HEADLESS_START_WIDTH, int)
|
2076
|
+
and hasattr(settings, "HEADLESS_START_HEIGHT")
|
2077
|
+
and isinstance(settings.HEADLESS_START_HEIGHT, int)
|
2078
|
+
):
|
2079
|
+
chrome_options.add_argument(
|
2080
|
+
"--window-size=%s,%s" % (
|
2081
|
+
settings.HEADLESS_START_WIDTH,
|
2082
|
+
settings.HEADLESS_START_HEIGHT,
|
2083
|
+
)
|
900
2084
|
)
|
901
|
-
)
|
902
2085
|
else:
|
903
|
-
|
904
|
-
"
|
905
|
-
|
2086
|
+
if (
|
2087
|
+
hasattr(settings, "CHROME_START_WIDTH")
|
2088
|
+
and isinstance(settings.CHROME_START_WIDTH, int)
|
2089
|
+
and hasattr(settings, "CHROME_START_HEIGHT")
|
2090
|
+
and isinstance(settings.CHROME_START_HEIGHT, int)
|
2091
|
+
):
|
2092
|
+
chrome_options.add_argument(
|
2093
|
+
"--window-size=%s,%s" % (
|
2094
|
+
settings.CHROME_START_WIDTH,
|
2095
|
+
settings.CHROME_START_HEIGHT,
|
2096
|
+
)
|
906
2097
|
)
|
907
|
-
)
|
908
2098
|
if (
|
909
2099
|
not proxy_auth
|
910
2100
|
and not disable_csp
|
@@ -963,7 +2153,10 @@ def _set_chrome_options(
|
|
963
2153
|
pass # Processed After Version Check
|
964
2154
|
elif headless:
|
965
2155
|
if not undetectable:
|
966
|
-
|
2156
|
+
if headless1:
|
2157
|
+
chrome_options.add_argument("--headless=old")
|
2158
|
+
else:
|
2159
|
+
chrome_options.add_argument("--headless")
|
967
2160
|
if undetectable and servername and servername != "localhost":
|
968
2161
|
# The Grid Node will need Chrome 109 or newer
|
969
2162
|
chrome_options.add_argument("--headless=new")
|
@@ -1045,7 +2238,10 @@ def _set_chrome_options(
|
|
1045
2238
|
chrome_options.add_argument("--ignore-certificate-errors")
|
1046
2239
|
if not enable_ws:
|
1047
2240
|
chrome_options.add_argument("--disable-web-security")
|
1048
|
-
if
|
2241
|
+
if (
|
2242
|
+
IS_LINUX
|
2243
|
+
or (IS_MAC and not is_using_uc(undetectable, browser_name))
|
2244
|
+
):
|
1049
2245
|
chrome_options.add_argument("--no-sandbox")
|
1050
2246
|
if remote_debug:
|
1051
2247
|
# To access the Debugger, go to: chrome://inspect/#devices
|
@@ -1077,10 +2273,18 @@ def _set_chrome_options(
|
|
1077
2273
|
binary_loc = detect_b_ver.get_binary_location(br_app, True)
|
1078
2274
|
if os.path.exists(binary_loc):
|
1079
2275
|
binary_location = binary_loc
|
2276
|
+
elif os.path.exists("/usr/bin/google-chrome-stable"):
|
2277
|
+
binary_location = "/usr/bin/google-chrome-stable"
|
2278
|
+
elif os.path.exists("/usr/bin/google-chrome"):
|
2279
|
+
binary_location = "/usr/bin/google-chrome"
|
1080
2280
|
extra_disabled_features = []
|
1081
2281
|
if chromium_arg:
|
1082
|
-
# Can be a comma-separated list of Chromium args
|
1083
|
-
chromium_arg_list =
|
2282
|
+
# Can be a comma-separated list of Chromium args or a list
|
2283
|
+
chromium_arg_list = None
|
2284
|
+
if isinstance(chromium_arg, (list, tuple)):
|
2285
|
+
chromium_arg_list = chromium_arg
|
2286
|
+
else:
|
2287
|
+
chromium_arg_list = chromium_arg.split(",")
|
1084
2288
|
for chromium_arg_item in chromium_arg_list:
|
1085
2289
|
chromium_arg_item = chromium_arg_item.strip()
|
1086
2290
|
if not chromium_arg_item.startswith("--"):
|
@@ -1089,13 +2293,11 @@ def _set_chrome_options(
|
|
1089
2293
|
else:
|
1090
2294
|
chromium_arg_item = "--" + chromium_arg_item
|
1091
2295
|
if "remote-debugging-port=" in chromium_arg_item:
|
1092
|
-
|
2296
|
+
with suppress(Exception):
|
1093
2297
|
# Extra processing for UC Mode
|
1094
2298
|
chrome_options._remote_debugging_port = int(
|
1095
2299
|
chromium_arg_item.split("remote-debugging-port=")[1]
|
1096
2300
|
)
|
1097
|
-
except Exception:
|
1098
|
-
pass
|
1099
2301
|
if "set-binary" in chromium_arg_item and not binary_location:
|
1100
2302
|
br_app = "google-chrome"
|
1101
2303
|
binary_loc = detect_b_ver.get_binary_location(
|
@@ -1114,6 +2316,8 @@ def _set_chrome_options(
|
|
1114
2316
|
chrome_options.add_argument("--auto-open-devtools-for-tabs")
|
1115
2317
|
if user_agent:
|
1116
2318
|
chrome_options.add_argument("--user-agent=%s" % user_agent)
|
2319
|
+
chrome_options.add_argument("--safebrowsing-disable-download-protection")
|
2320
|
+
chrome_options.add_argument("--disable-search-engine-choice-screen")
|
1117
2321
|
chrome_options.add_argument("--disable-browser-side-navigation")
|
1118
2322
|
chrome_options.add_argument("--disable-save-password-bubble")
|
1119
2323
|
chrome_options.add_argument("--disable-single-click-autofill")
|
@@ -1134,30 +2338,31 @@ def _set_chrome_options(
|
|
1134
2338
|
chrome_options.add_argument("--ash-no-nudges")
|
1135
2339
|
chrome_options.add_argument("--no-crash-upload")
|
1136
2340
|
chrome_options.add_argument("--deny-permission-prompts")
|
2341
|
+
chrome_options.add_argument(
|
2342
|
+
'--simulate-outdated-no-au="Tue, 31 Dec 2099 23:59:59 GMT"'
|
2343
|
+
)
|
2344
|
+
chrome_options.add_argument("--disable-ipc-flooding-protection")
|
2345
|
+
chrome_options.add_argument("--disable-password-generation")
|
2346
|
+
chrome_options.add_argument("--disable-domain-reliability")
|
2347
|
+
chrome_options.add_argument("--disable-breakpad")
|
1137
2348
|
included_disabled_features = []
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
included_disabled_features
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
included_disabled_features.append("DownloadBubbleV2")
|
1156
|
-
for item in extra_disabled_features:
|
1157
|
-
if item not in included_disabled_features:
|
1158
|
-
included_disabled_features.append(item)
|
1159
|
-
d_f_string = ",".join(included_disabled_features)
|
1160
|
-
chrome_options.add_argument("--disable-features=%s" % d_f_string)
|
2349
|
+
included_disabled_features.append("OptimizationHints")
|
2350
|
+
included_disabled_features.append("OptimizationHintsFetching")
|
2351
|
+
included_disabled_features.append("Translate")
|
2352
|
+
included_disabled_features.append("OptimizationTargetPrediction")
|
2353
|
+
included_disabled_features.append("OptimizationGuideModelDownloading")
|
2354
|
+
included_disabled_features.append("DownloadBubble")
|
2355
|
+
included_disabled_features.append("DownloadBubbleV2")
|
2356
|
+
included_disabled_features.append("InsecureDownloadWarnings")
|
2357
|
+
included_disabled_features.append("InterestFeedContentSuggestions")
|
2358
|
+
included_disabled_features.append("PrivacySandboxSettings4")
|
2359
|
+
included_disabled_features.append("SidePanelPinning")
|
2360
|
+
included_disabled_features.append("UserAgentClientHint")
|
2361
|
+
for item in extra_disabled_features:
|
2362
|
+
if item not in included_disabled_features:
|
2363
|
+
included_disabled_features.append(item)
|
2364
|
+
d_f_string = ",".join(included_disabled_features)
|
2365
|
+
chrome_options.add_argument("--disable-features=%s" % d_f_string)
|
1161
2366
|
if (
|
1162
2367
|
is_using_uc(undetectable, browser_name)
|
1163
2368
|
and (
|
@@ -1165,8 +2370,14 @@ def _set_chrome_options(
|
|
1165
2370
|
or IS_LINUX # switches to Xvfb (non-headless)
|
1166
2371
|
)
|
1167
2372
|
):
|
2373
|
+
chrome_options.add_argument("--no-pings")
|
2374
|
+
chrome_options.add_argument("--homepage=chrome://version/")
|
2375
|
+
chrome_options.add_argument("--animation-duration-scale=0")
|
2376
|
+
chrome_options.add_argument("--wm-window-animations-disabled")
|
2377
|
+
chrome_options.add_argument("--enable-privacy-sandbox-ads-apis")
|
2378
|
+
chrome_options.add_argument("--disable-background-timer-throttling")
|
2379
|
+
# Prevent new tabs opened by Selenium from being blocked:
|
1168
2380
|
chrome_options.add_argument("--disable-popup-blocking")
|
1169
|
-
chrome_options.add_argument("--homepage=chrome://new-tab-page/")
|
1170
2381
|
# Skip remaining options that trigger anti-bot services
|
1171
2382
|
return chrome_options
|
1172
2383
|
chrome_options.add_argument("--test-type")
|
@@ -1193,10 +2404,12 @@ def _set_firefox_options(
|
|
1193
2404
|
proxy_bypass_list,
|
1194
2405
|
proxy_pac_url,
|
1195
2406
|
user_agent,
|
2407
|
+
disable_cookies,
|
1196
2408
|
disable_js,
|
1197
2409
|
disable_csp,
|
1198
2410
|
firefox_arg,
|
1199
2411
|
firefox_pref,
|
2412
|
+
external_pdf,
|
1200
2413
|
):
|
1201
2414
|
blank_p = "about:blank"
|
1202
2415
|
options = webdriver.FirefoxOptions()
|
@@ -1208,7 +2421,6 @@ def _set_firefox_options(
|
|
1208
2421
|
options.set_preference("browser.newtab.url", blank_p)
|
1209
2422
|
options.set_preference("trailhead.firstrun.branches", "nofirstrun-empty")
|
1210
2423
|
options.set_preference("browser.aboutwelcome.enabled", False)
|
1211
|
-
options.set_preference("pdfjs.disabled", True)
|
1212
2424
|
options.set_preference("app.update.auto", False)
|
1213
2425
|
options.set_preference("app.update.enabled", False)
|
1214
2426
|
options.set_preference("browser.formfill.enable", False)
|
@@ -1216,8 +2428,6 @@ def _set_firefox_options(
|
|
1216
2428
|
options.set_preference("dom.webnotifications.enabled", False)
|
1217
2429
|
options.set_preference("dom.disable_beforeunload", True)
|
1218
2430
|
options.set_preference("browser.contentblocking.database.enabled", True)
|
1219
|
-
options.set_preference("extensions.allowPrivateBrowsingByDefault", True)
|
1220
|
-
options.set_preference("extensions.PrivateBrowsing.notification", False)
|
1221
2431
|
options.set_preference("extensions.systemAddon.update.enabled", False)
|
1222
2432
|
options.set_preference("extensions.update.autoUpdateDefault", False)
|
1223
2433
|
options.set_preference("extensions.update.enabled", False)
|
@@ -1266,6 +2476,8 @@ def _set_firefox_options(
|
|
1266
2476
|
"security.mixed_content.block_active_content", False
|
1267
2477
|
)
|
1268
2478
|
options.set_preference("security.warn_submit_insecure", False)
|
2479
|
+
if disable_cookies:
|
2480
|
+
options.set_preference("network.cookie.cookieBehavior", 2)
|
1269
2481
|
if disable_js:
|
1270
2482
|
options.set_preference("javascript.enabled", False)
|
1271
2483
|
if settings.DISABLE_CSP_ON_FIREFOX or disable_csp:
|
@@ -1293,22 +2505,27 @@ def _set_firefox_options(
|
|
1293
2505
|
options.set_preference(
|
1294
2506
|
"browser.helperApps.neverAsk.saveToDisk",
|
1295
2507
|
(
|
1296
|
-
"application/pdf,
|
1297
|
-
"text/csv,
|
1298
|
-
"text/octet-stream,
|
1299
|
-
"application/"
|
1300
|
-
"
|
2508
|
+
"application/pdf,application/zip,application/octet-stream,"
|
2509
|
+
"text/csv,text/xml,application/xml,text/plain,application/json,"
|
2510
|
+
"text/octet-stream,application/x-gzip,application/x-tar,"
|
2511
|
+
"application/java-archive,text/x-java-source,java,"
|
2512
|
+
"application/javascript,video/jpeg,audio/x-aac,image/svg+xml,"
|
2513
|
+
"application/x-font-woff,application/x-7z-compressed,"
|
2514
|
+
"application/mp4,video/mp4,audio/mp4,video/x-msvideo,"
|
2515
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
1301
2516
|
),
|
1302
2517
|
)
|
2518
|
+
if external_pdf:
|
2519
|
+
options.set_preference("pdfjs.disabled", True)
|
2520
|
+
else:
|
2521
|
+
options.set_preference("pdfjs.disabled", False)
|
1303
2522
|
if firefox_arg:
|
1304
2523
|
# Can be a comma-separated list of Firefox args
|
1305
2524
|
firefox_arg_list = firefox_arg.split(",")
|
1306
2525
|
for firefox_arg_item in firefox_arg_list:
|
1307
2526
|
firefox_arg_item = firefox_arg_item.strip()
|
1308
|
-
if not firefox_arg_item.startswith("
|
1309
|
-
if firefox_arg_item.
|
1310
|
-
firefox_arg_item = "-" + firefox_arg_item
|
1311
|
-
else:
|
2527
|
+
if not firefox_arg_item.startswith("-"):
|
2528
|
+
if firefox_arg_item.count(os.sep) == 0:
|
1312
2529
|
firefox_arg_item = "--" + firefox_arg_item
|
1313
2530
|
if len(firefox_arg_item) >= 3:
|
1314
2531
|
options.add_argument(firefox_arg_item)
|
@@ -1340,7 +2557,7 @@ def _set_firefox_options(
|
|
1340
2557
|
f_pref_value = False
|
1341
2558
|
elif f_pref_value.isdigit():
|
1342
2559
|
f_pref_value = int(f_pref_value)
|
1343
|
-
elif f_pref_value.
|
2560
|
+
elif f_pref_value.replace(".", "", 1).isdigit():
|
1344
2561
|
f_pref_value = float(f_pref_value)
|
1345
2562
|
else:
|
1346
2563
|
pass # keep as string
|
@@ -1365,6 +2582,7 @@ def get_driver(
|
|
1365
2582
|
cap_file=None,
|
1366
2583
|
cap_string=None,
|
1367
2584
|
recorder_ext=False,
|
2585
|
+
disable_cookies=False,
|
1368
2586
|
disable_js=False,
|
1369
2587
|
disable_csp=False,
|
1370
2588
|
enable_ws=False,
|
@@ -1376,6 +2594,7 @@ def get_driver(
|
|
1376
2594
|
log_cdp_events=False,
|
1377
2595
|
no_sandbox=False,
|
1378
2596
|
disable_gpu=False,
|
2597
|
+
headless1=False,
|
1379
2598
|
headless2=False,
|
1380
2599
|
incognito=False,
|
1381
2600
|
guest_mode=False,
|
@@ -1524,6 +2743,7 @@ def get_driver(
|
|
1524
2743
|
headless
|
1525
2744
|
and (
|
1526
2745
|
proxy_auth
|
2746
|
+
or disable_cookies
|
1527
2747
|
or disable_js
|
1528
2748
|
or ad_block_on
|
1529
2749
|
or disable_csp
|
@@ -1578,6 +2798,7 @@ def get_driver(
|
|
1578
2798
|
cap_file,
|
1579
2799
|
cap_string,
|
1580
2800
|
recorder_ext,
|
2801
|
+
disable_cookies,
|
1581
2802
|
disable_js,
|
1582
2803
|
disable_csp,
|
1583
2804
|
enable_ws,
|
@@ -1589,6 +2810,7 @@ def get_driver(
|
|
1589
2810
|
log_cdp_events,
|
1590
2811
|
no_sandbox,
|
1591
2812
|
disable_gpu,
|
2813
|
+
headless1,
|
1592
2814
|
headless2,
|
1593
2815
|
incognito,
|
1594
2816
|
guest_mode,
|
@@ -1634,6 +2856,7 @@ def get_driver(
|
|
1634
2856
|
multi_proxy,
|
1635
2857
|
user_agent,
|
1636
2858
|
recorder_ext,
|
2859
|
+
disable_cookies,
|
1637
2860
|
disable_js,
|
1638
2861
|
disable_csp,
|
1639
2862
|
enable_ws,
|
@@ -1645,6 +2868,7 @@ def get_driver(
|
|
1645
2868
|
log_cdp_events,
|
1646
2869
|
no_sandbox,
|
1647
2870
|
disable_gpu,
|
2871
|
+
headless1,
|
1648
2872
|
headless2,
|
1649
2873
|
incognito,
|
1650
2874
|
guest_mode,
|
@@ -1694,6 +2918,7 @@ def get_remote_driver(
|
|
1694
2918
|
cap_file,
|
1695
2919
|
cap_string,
|
1696
2920
|
recorder_ext,
|
2921
|
+
disable_cookies,
|
1697
2922
|
disable_js,
|
1698
2923
|
disable_csp,
|
1699
2924
|
enable_ws,
|
@@ -1705,6 +2930,7 @@ def get_remote_driver(
|
|
1705
2930
|
log_cdp_events,
|
1706
2931
|
no_sandbox,
|
1707
2932
|
disable_gpu,
|
2933
|
+
headless1,
|
1708
2934
|
headless2,
|
1709
2935
|
incognito,
|
1710
2936
|
guest_mode,
|
@@ -1739,14 +2965,28 @@ def get_remote_driver(
|
|
1739
2965
|
pip_find_lock = fasteners.InterProcessLock(
|
1740
2966
|
constants.PipInstall.FINDLOCK
|
1741
2967
|
)
|
1742
|
-
with pip_find_lock:
|
2968
|
+
with pip_find_lock: # Prevent issues with multiple processes
|
2969
|
+
with suppress(Exception):
|
2970
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
1743
2971
|
try:
|
1744
2972
|
from seleniumwire import webdriver
|
2973
|
+
import blinker
|
2974
|
+
with suppress(Exception):
|
2975
|
+
use_blinker_ver = constants.SeleniumWire.BLINKER_VER
|
2976
|
+
if blinker.__version__ != use_blinker_ver:
|
2977
|
+
shared_utils.pip_install(
|
2978
|
+
"blinker", version=use_blinker_ver
|
2979
|
+
)
|
2980
|
+
del blinker
|
1745
2981
|
except Exception:
|
2982
|
+
shared_utils.pip_install(
|
2983
|
+
"blinker", version=constants.SeleniumWire.BLINKER_VER
|
2984
|
+
)
|
1746
2985
|
shared_utils.pip_install(
|
1747
2986
|
"selenium-wire", version=constants.SeleniumWire.VER
|
1748
2987
|
)
|
1749
2988
|
from seleniumwire import webdriver
|
2989
|
+
warnings.simplefilter("ignore", category=DeprecationWarning)
|
1750
2990
|
else:
|
1751
2991
|
from selenium import webdriver
|
1752
2992
|
|
@@ -1817,6 +3057,7 @@ def get_remote_driver(
|
|
1817
3057
|
multi_proxy,
|
1818
3058
|
user_agent,
|
1819
3059
|
recorder_ext,
|
3060
|
+
disable_cookies,
|
1820
3061
|
disable_js,
|
1821
3062
|
disable_csp,
|
1822
3063
|
enable_ws,
|
@@ -1828,6 +3069,7 @@ def get_remote_driver(
|
|
1828
3069
|
log_cdp_events,
|
1829
3070
|
no_sandbox,
|
1830
3071
|
disable_gpu,
|
3072
|
+
headless1,
|
1831
3073
|
headless2,
|
1832
3074
|
incognito,
|
1833
3075
|
guest_mode,
|
@@ -1911,10 +3153,12 @@ def get_remote_driver(
|
|
1911
3153
|
proxy_bypass_list,
|
1912
3154
|
proxy_pac_url,
|
1913
3155
|
user_agent,
|
3156
|
+
disable_cookies,
|
1914
3157
|
disable_js,
|
1915
3158
|
disable_csp,
|
1916
3159
|
firefox_arg,
|
1917
3160
|
firefox_pref,
|
3161
|
+
external_pdf,
|
1918
3162
|
)
|
1919
3163
|
capabilities = webdriver.FirefoxOptions().to_capabilities()
|
1920
3164
|
capabilities["marionette"] = True
|
@@ -1989,6 +3233,7 @@ def get_remote_driver(
|
|
1989
3233
|
multi_proxy,
|
1990
3234
|
user_agent,
|
1991
3235
|
recorder_ext,
|
3236
|
+
disable_cookies,
|
1992
3237
|
disable_js,
|
1993
3238
|
disable_csp,
|
1994
3239
|
enable_ws,
|
@@ -2000,6 +3245,7 @@ def get_remote_driver(
|
|
2000
3245
|
log_cdp_events,
|
2001
3246
|
no_sandbox,
|
2002
3247
|
disable_gpu,
|
3248
|
+
headless1,
|
2003
3249
|
headless2,
|
2004
3250
|
incognito,
|
2005
3251
|
guest_mode,
|
@@ -2108,6 +3354,7 @@ def get_local_driver(
|
|
2108
3354
|
multi_proxy,
|
2109
3355
|
user_agent,
|
2110
3356
|
recorder_ext,
|
3357
|
+
disable_cookies,
|
2111
3358
|
disable_js,
|
2112
3359
|
disable_csp,
|
2113
3360
|
enable_ws,
|
@@ -2119,6 +3366,7 @@ def get_local_driver(
|
|
2119
3366
|
log_cdp_events,
|
2120
3367
|
no_sandbox,
|
2121
3368
|
disable_gpu,
|
3369
|
+
headless1,
|
2122
3370
|
headless2,
|
2123
3371
|
incognito,
|
2124
3372
|
guest_mode,
|
@@ -2153,17 +3401,31 @@ def get_local_driver(
|
|
2153
3401
|
downloads_path = DOWNLOADS_FOLDER
|
2154
3402
|
b_path = binary_location
|
2155
3403
|
if use_wire:
|
2156
|
-
|
2157
|
-
constants.
|
3404
|
+
pip_find_lock = fasteners.InterProcessLock(
|
3405
|
+
constants.PipInstall.FINDLOCK
|
2158
3406
|
)
|
2159
|
-
with
|
3407
|
+
with pip_find_lock: # Prevent issues with multiple processes
|
3408
|
+
with suppress(Exception):
|
3409
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
2160
3410
|
try:
|
2161
3411
|
from seleniumwire import webdriver
|
3412
|
+
import blinker
|
3413
|
+
with suppress(Exception):
|
3414
|
+
use_blinker_ver = constants.SeleniumWire.BLINKER_VER
|
3415
|
+
if blinker.__version__ != use_blinker_ver:
|
3416
|
+
shared_utils.pip_install(
|
3417
|
+
"blinker", version=use_blinker_ver
|
3418
|
+
)
|
3419
|
+
del blinker
|
2162
3420
|
except Exception:
|
3421
|
+
shared_utils.pip_install(
|
3422
|
+
"blinker", version=constants.SeleniumWire.BLINKER_VER
|
3423
|
+
)
|
2163
3424
|
shared_utils.pip_install(
|
2164
3425
|
"selenium-wire", version=constants.SeleniumWire.VER
|
2165
3426
|
)
|
2166
3427
|
from seleniumwire import webdriver
|
3428
|
+
warnings.simplefilter("ignore", category=DeprecationWarning)
|
2167
3429
|
else:
|
2168
3430
|
from selenium import webdriver
|
2169
3431
|
|
@@ -2176,10 +3438,12 @@ def get_local_driver(
|
|
2176
3438
|
proxy_bypass_list,
|
2177
3439
|
proxy_pac_url,
|
2178
3440
|
user_agent,
|
3441
|
+
disable_cookies,
|
2179
3442
|
disable_js,
|
2180
3443
|
disable_csp,
|
2181
3444
|
firefox_arg,
|
2182
3445
|
firefox_pref,
|
3446
|
+
external_pdf,
|
2183
3447
|
)
|
2184
3448
|
if LOCAL_GECKODRIVER and os.path.exists(LOCAL_GECKODRIVER):
|
2185
3449
|
try:
|
@@ -2206,6 +3470,10 @@ def get_local_driver(
|
|
2206
3470
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2207
3471
|
)
|
2208
3472
|
with geckodriver_fixing_lock:
|
3473
|
+
with suppress(Exception):
|
3474
|
+
shared_utils.make_writable(
|
3475
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3476
|
+
)
|
2209
3477
|
if not geckodriver_on_path():
|
2210
3478
|
sys_args = sys.argv # Save a copy of sys args
|
2211
3479
|
log_d(
|
@@ -2232,11 +3500,13 @@ def get_local_driver(
|
|
2232
3500
|
or "Process unexpectedly closed" in str(e)
|
2233
3501
|
or "Failed to read marionette port" in str(e)
|
2234
3502
|
or "A connection attempt failed" in str(e)
|
3503
|
+
or "Expected browser binary" in str(e)
|
2235
3504
|
or hasattr(e, "msg") and (
|
2236
3505
|
"geckodriver unexpectedly exited" in e.msg
|
2237
3506
|
or "Process unexpectedly closed" in e.msg
|
2238
3507
|
or "Failed to read marionette port" in e.msg
|
2239
3508
|
or "A connection attempt failed" in e.msg
|
3509
|
+
or "Expected browser binary" in e.msg
|
2240
3510
|
)
|
2241
3511
|
):
|
2242
3512
|
time.sleep(0.1)
|
@@ -2272,11 +3542,13 @@ def get_local_driver(
|
|
2272
3542
|
or "Process unexpectedly closed" in str(e)
|
2273
3543
|
or "Failed to read marionette port" in str(e)
|
2274
3544
|
or "A connection attempt failed" in str(e)
|
3545
|
+
or "Expected browser binary" in str(e)
|
2275
3546
|
or hasattr(e, "msg") and (
|
2276
3547
|
"geckodriver unexpectedly exited" in e.msg
|
2277
3548
|
or "Process unexpectedly closed" in e.msg
|
2278
3549
|
or "Failed to read marionette port" in e.msg
|
2279
3550
|
or "A connection attempt failed" in e.msg
|
3551
|
+
or "Expected browser binary" in e.msg
|
2280
3552
|
)
|
2281
3553
|
):
|
2282
3554
|
time.sleep(0.1)
|
@@ -2367,11 +3639,12 @@ def get_local_driver(
|
|
2367
3639
|
elif browser_name == constants.Browser.EDGE:
|
2368
3640
|
prefs = {
|
2369
3641
|
"download.default_directory": downloads_path,
|
2370
|
-
"local_discovery.notifications_enabled": False,
|
2371
|
-
"credentials_enable_service": False,
|
2372
|
-
"download.prompt_for_download": False,
|
2373
3642
|
"download.directory_upgrade": True,
|
2374
|
-
"
|
3643
|
+
"download.prompt_for_download": False,
|
3644
|
+
"credentials_enable_service": False,
|
3645
|
+
"local_discovery.notifications_enabled": False,
|
3646
|
+
"safebrowsing.disable_download_protection": True,
|
3647
|
+
"safebrowsing.enabled": False, # Prevent PW "data breach" pop-ups
|
2375
3648
|
"omnibox-max-zero-suggest-matches": 0,
|
2376
3649
|
"omnibox-use-existing-autocomplete-client": 0,
|
2377
3650
|
"omnibox-trending-zero-prefix-suggestions-on-ntp": 0,
|
@@ -2382,12 +3655,12 @@ def get_local_driver(
|
|
2382
3655
|
"omnibox-zero-suggest-prefetching-on-srp": 0,
|
2383
3656
|
"omnibox-zero-suggest-prefetching-on-web": 0,
|
2384
3657
|
"omnibox-zero-suggest-in-memory-caching": 0,
|
2385
|
-
"
|
3658
|
+
"content_settings.exceptions.automatic_downloads.*.setting": 1,
|
2386
3659
|
"default_content_setting_values.notifications": 0,
|
2387
3660
|
"default_content_settings.popups": 0,
|
2388
3661
|
"managed_default_content_settings.popups": 0,
|
2389
|
-
"content_settings.exceptions.automatic_downloads.*.setting": 1,
|
2390
3662
|
"profile.password_manager_enabled": False,
|
3663
|
+
"profile.password_manager_leak_detection": False,
|
2391
3664
|
"profile.default_content_setting_values.notifications": 2,
|
2392
3665
|
"profile.default_content_settings.popups": 0,
|
2393
3666
|
"profile.managed_default_content_settings.popups": 0,
|
@@ -2440,7 +3713,7 @@ def get_local_driver(
|
|
2440
3713
|
edge_driver_version = None
|
2441
3714
|
edgedriver_upgrade_needed = False
|
2442
3715
|
if os.path.exists(LOCAL_EDGEDRIVER):
|
2443
|
-
|
3716
|
+
with suppress(Exception):
|
2444
3717
|
output = subprocess.check_output(
|
2445
3718
|
'"%s" --version' % LOCAL_EDGEDRIVER, shell=True
|
2446
3719
|
)
|
@@ -2466,8 +3739,6 @@ def get_local_driver(
|
|
2466
3739
|
edge_driver_version = output
|
2467
3740
|
if driver_version == "keep":
|
2468
3741
|
driver_version = edge_driver_version
|
2469
|
-
except Exception:
|
2470
|
-
pass
|
2471
3742
|
use_version = find_edgedriver_version_to_use(
|
2472
3743
|
use_version, driver_version
|
2473
3744
|
)
|
@@ -2505,6 +3776,10 @@ def get_local_driver(
|
|
2505
3776
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2506
3777
|
)
|
2507
3778
|
with edgedriver_fixing_lock:
|
3779
|
+
with suppress(Exception):
|
3780
|
+
shared_utils.make_writable(
|
3781
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3782
|
+
)
|
2508
3783
|
msg = "Microsoft Edge Driver not found."
|
2509
3784
|
if edgedriver_upgrade_needed:
|
2510
3785
|
msg = "Microsoft Edge Driver update needed."
|
@@ -2530,6 +3805,8 @@ def get_local_driver(
|
|
2530
3805
|
prefs["intl.accept_languages"] = locale_code
|
2531
3806
|
if block_images:
|
2532
3807
|
prefs["profile.managed_default_content_settings.images"] = 2
|
3808
|
+
if disable_cookies:
|
3809
|
+
prefs["profile.default_content_setting_values.cookies"] = 2
|
2533
3810
|
if disable_js:
|
2534
3811
|
prefs["profile.managed_default_content_settings.javascript"] = 2
|
2535
3812
|
if do_not_track:
|
@@ -2571,7 +3848,7 @@ def get_local_driver(
|
|
2571
3848
|
edge_options.add_argument("--headless=new")
|
2572
3849
|
elif headless and undetectable:
|
2573
3850
|
# (For later: UC Mode doesn't support Edge now)
|
2574
|
-
|
3851
|
+
with suppress(Exception):
|
2575
3852
|
if int(use_version) >= 109:
|
2576
3853
|
edge_options.add_argument("--headless=new")
|
2577
3854
|
elif (
|
@@ -2581,18 +3858,22 @@ def get_local_driver(
|
|
2581
3858
|
edge_options.add_argument("--headless=chrome")
|
2582
3859
|
else:
|
2583
3860
|
pass # Will need Xvfb on Linux
|
2584
|
-
except Exception:
|
2585
|
-
pass
|
2586
3861
|
elif headless:
|
2587
|
-
if
|
2588
|
-
|
3862
|
+
if (
|
3863
|
+
"--headless" not in edge_options.arguments
|
3864
|
+
and "--headless=old" not in edge_options.arguments
|
3865
|
+
):
|
3866
|
+
if headless1:
|
3867
|
+
edge_options.add_argument("--headless=old")
|
3868
|
+
else:
|
3869
|
+
edge_options.add_argument("--headless")
|
2589
3870
|
if mobile_emulator and not is_using_uc(undetectable, browser_name):
|
2590
3871
|
emulator_settings = {}
|
2591
3872
|
device_metrics = {}
|
2592
3873
|
if (
|
2593
3874
|
isinstance(device_width, int)
|
2594
3875
|
and isinstance(device_height, int)
|
2595
|
-
and isinstance(device_pixel_ratio, int)
|
3876
|
+
and isinstance(device_pixel_ratio, (int, float))
|
2596
3877
|
):
|
2597
3878
|
device_metrics["width"] = device_width
|
2598
3879
|
device_metrics["height"] = device_height
|
@@ -2607,20 +3888,49 @@ def get_local_driver(
|
|
2607
3888
|
edge_options.add_experimental_option(
|
2608
3889
|
"mobileEmulation", emulator_settings
|
2609
3890
|
)
|
3891
|
+
# Handle Window Position
|
3892
|
+
if (headless or headless2) and IS_WINDOWS:
|
3893
|
+
# https://stackoverflow.com/a/78999088/7058266
|
3894
|
+
edge_options.add_argument("--window-position=-2400,-2400")
|
3895
|
+
else:
|
3896
|
+
if (
|
3897
|
+
hasattr(settings, "WINDOW_START_X")
|
3898
|
+
and isinstance(settings.WINDOW_START_X, int)
|
3899
|
+
and hasattr(settings, "WINDOW_START_Y")
|
3900
|
+
and isinstance(settings.WINDOW_START_Y, int)
|
3901
|
+
):
|
3902
|
+
edge_options.add_argument(
|
3903
|
+
"--window-position=%s,%s" % (
|
3904
|
+
settings.WINDOW_START_X, settings.WINDOW_START_Y
|
3905
|
+
)
|
3906
|
+
)
|
3907
|
+
# Handle Window Size
|
2610
3908
|
if headless or headless2:
|
2611
|
-
|
2612
|
-
"
|
2613
|
-
|
2614
|
-
|
3909
|
+
if (
|
3910
|
+
hasattr(settings, "HEADLESS_START_WIDTH")
|
3911
|
+
and isinstance(settings.HEADLESS_START_WIDTH, int)
|
3912
|
+
and hasattr(settings, "HEADLESS_START_HEIGHT")
|
3913
|
+
and isinstance(settings.HEADLESS_START_HEIGHT, int)
|
3914
|
+
):
|
3915
|
+
edge_options.add_argument(
|
3916
|
+
"--window-size=%s,%s" % (
|
3917
|
+
settings.HEADLESS_START_WIDTH,
|
3918
|
+
settings.HEADLESS_START_HEIGHT,
|
3919
|
+
)
|
2615
3920
|
)
|
2616
|
-
)
|
2617
3921
|
else:
|
2618
|
-
|
2619
|
-
"
|
2620
|
-
|
2621
|
-
|
3922
|
+
if (
|
3923
|
+
hasattr(settings, "CHROME_START_WIDTH")
|
3924
|
+
and isinstance(settings.CHROME_START_WIDTH, int)
|
3925
|
+
and hasattr(settings, "CHROME_START_HEIGHT")
|
3926
|
+
and isinstance(settings.CHROME_START_HEIGHT, int)
|
3927
|
+
):
|
3928
|
+
edge_options.add_argument(
|
3929
|
+
"--window-size=%s,%s" % (
|
3930
|
+
settings.CHROME_START_WIDTH,
|
3931
|
+
settings.CHROME_START_HEIGHT,
|
3932
|
+
)
|
2622
3933
|
)
|
2623
|
-
)
|
2624
3934
|
if user_data_dir and not is_using_uc(undetectable, browser_name):
|
2625
3935
|
abs_path = os.path.abspath(user_data_dir)
|
2626
3936
|
edge_options.add_argument("--user-data-dir=%s" % abs_path)
|
@@ -2641,6 +3951,8 @@ def get_local_driver(
|
|
2641
3951
|
edge_options.add_argument(
|
2642
3952
|
"--disable-autofill-keyboard-accessory-view[8]"
|
2643
3953
|
)
|
3954
|
+
edge_options.add_argument("--safebrowsing-disable-download-protection")
|
3955
|
+
edge_options.add_argument("--disable-search-engine-choice-screen")
|
2644
3956
|
edge_options.add_argument("--disable-browser-side-navigation")
|
2645
3957
|
edge_options.add_argument("--disable-translate")
|
2646
3958
|
if not enable_ws:
|
@@ -2724,7 +4036,10 @@ def get_local_driver(
|
|
2724
4036
|
edge_options.add_argument("--allow-running-insecure-content")
|
2725
4037
|
if user_agent:
|
2726
4038
|
edge_options.add_argument("--user-agent=%s" % user_agent)
|
2727
|
-
if
|
4039
|
+
if (
|
4040
|
+
IS_LINUX
|
4041
|
+
or (IS_MAC and not is_using_uc(undetectable, browser_name))
|
4042
|
+
):
|
2728
4043
|
edge_options.add_argument("--no-sandbox")
|
2729
4044
|
if remote_debug:
|
2730
4045
|
# To access the Debugger, go to: edge://inspect/#devices
|
@@ -2749,7 +4064,11 @@ def get_local_driver(
|
|
2749
4064
|
set_binary = False
|
2750
4065
|
if chromium_arg:
|
2751
4066
|
# Can be a comma-separated list of Chromium args
|
2752
|
-
chromium_arg_list =
|
4067
|
+
chromium_arg_list = None
|
4068
|
+
if isinstance(chromium_arg, (list, tuple)):
|
4069
|
+
chromium_arg_list = chromium_arg
|
4070
|
+
else:
|
4071
|
+
chromium_arg_list = chromium_arg.split(",")
|
2753
4072
|
for chromium_arg_item in chromium_arg_list:
|
2754
4073
|
chromium_arg_item = chromium_arg_item.strip()
|
2755
4074
|
if not chromium_arg_item.startswith("--"):
|
@@ -2766,26 +4085,29 @@ def get_local_driver(
|
|
2766
4085
|
edge_options.add_argument(chromium_arg_item)
|
2767
4086
|
if disable_features:
|
2768
4087
|
extra_disabled_features.extend(disable_features.split(","))
|
4088
|
+
edge_options.add_argument(
|
4089
|
+
'--simulate-outdated-no-au="Tue, 31 Dec 2099 23:59:59 GMT"'
|
4090
|
+
)
|
4091
|
+
edge_options.add_argument("--disable-ipc-flooding-protection")
|
4092
|
+
edge_options.add_argument("--disable-password-generation")
|
4093
|
+
edge_options.add_argument("--disable-domain-reliability")
|
4094
|
+
edge_options.add_argument("--disable-breakpad")
|
2769
4095
|
included_disabled_features = []
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
included_disabled_features
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
if item not in included_disabled_features:
|
2786
|
-
included_disabled_features.append(item)
|
2787
|
-
d_f_string = ",".join(included_disabled_features)
|
2788
|
-
edge_options.add_argument("--disable-features=%s" % d_f_string)
|
4096
|
+
included_disabled_features.append("OptimizationHints")
|
4097
|
+
included_disabled_features.append("OptimizationHintsFetching")
|
4098
|
+
included_disabled_features.append("Translate")
|
4099
|
+
included_disabled_features.append("OptimizationTargetPrediction")
|
4100
|
+
included_disabled_features.append("OptimizationGuideModelDownloading")
|
4101
|
+
included_disabled_features.append("InsecureDownloadWarnings")
|
4102
|
+
included_disabled_features.append("InterestFeedContentSuggestions")
|
4103
|
+
included_disabled_features.append("PrivacySandboxSettings4")
|
4104
|
+
included_disabled_features.append("SidePanelPinning")
|
4105
|
+
included_disabled_features.append("UserAgentClientHint")
|
4106
|
+
for item in extra_disabled_features:
|
4107
|
+
if item not in included_disabled_features:
|
4108
|
+
included_disabled_features.append(item)
|
4109
|
+
d_f_string = ",".join(included_disabled_features)
|
4110
|
+
edge_options.add_argument("--disable-features=%s" % d_f_string)
|
2789
4111
|
if (set_binary or IS_LINUX) and not binary_location:
|
2790
4112
|
br_app = "edge"
|
2791
4113
|
binary_loc = detect_b_ver.get_binary_location(br_app)
|
@@ -2840,19 +4162,19 @@ def get_local_driver(
|
|
2840
4162
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
2841
4163
|
)
|
2842
4164
|
with edgedriver_fixing_lock:
|
2843
|
-
|
4165
|
+
with suppress(Exception):
|
4166
|
+
shared_utils.make_writable(
|
4167
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4168
|
+
)
|
4169
|
+
with suppress(Exception):
|
2844
4170
|
if not _was_driver_repaired():
|
2845
4171
|
_repair_edgedriver(edge_version)
|
2846
4172
|
_mark_driver_repaired()
|
2847
|
-
except Exception:
|
2848
|
-
pass
|
2849
4173
|
else:
|
2850
|
-
|
4174
|
+
with suppress(Exception):
|
2851
4175
|
if not _was_driver_repaired():
|
2852
4176
|
_repair_edgedriver(edge_version)
|
2853
4177
|
_mark_driver_repaired()
|
2854
|
-
except Exception:
|
2855
|
-
pass
|
2856
4178
|
driver = Edge(service=service, options=edge_options)
|
2857
4179
|
return extend_driver(driver)
|
2858
4180
|
elif browser_name == constants.Browser.SAFARI:
|
@@ -2898,6 +4220,7 @@ def get_local_driver(
|
|
2898
4220
|
multi_proxy,
|
2899
4221
|
user_agent,
|
2900
4222
|
recorder_ext,
|
4223
|
+
disable_cookies,
|
2901
4224
|
disable_js,
|
2902
4225
|
disable_csp,
|
2903
4226
|
enable_ws,
|
@@ -2909,6 +4232,7 @@ def get_local_driver(
|
|
2909
4232
|
log_cdp_events,
|
2910
4233
|
no_sandbox,
|
2911
4234
|
disable_gpu,
|
4235
|
+
headless1,
|
2912
4236
|
headless2,
|
2913
4237
|
incognito,
|
2914
4238
|
guest_mode,
|
@@ -3004,7 +4328,7 @@ def get_local_driver(
|
|
3004
4328
|
ch_driver_version = None
|
3005
4329
|
path_chromedriver = chromedriver_on_path()
|
3006
4330
|
if os.path.exists(LOCAL_CHROMEDRIVER):
|
3007
|
-
|
4331
|
+
with suppress(Exception):
|
3008
4332
|
output = subprocess.check_output(
|
3009
4333
|
'"%s" --version' % LOCAL_CHROMEDRIVER, shell=True
|
3010
4334
|
)
|
@@ -3018,8 +4342,6 @@ def get_local_driver(
|
|
3018
4342
|
ch_driver_version = output
|
3019
4343
|
if driver_version == "keep":
|
3020
4344
|
driver_version = ch_driver_version
|
3021
|
-
except Exception:
|
3022
|
-
pass
|
3023
4345
|
elif path_chromedriver:
|
3024
4346
|
try:
|
3025
4347
|
make_driver_executable_if_not(path_chromedriver)
|
@@ -3028,7 +4350,7 @@ def get_local_driver(
|
|
3028
4350
|
"\nWarning: Could not make chromedriver"
|
3029
4351
|
" executable: %s" % e
|
3030
4352
|
)
|
3031
|
-
|
4353
|
+
with suppress(Exception):
|
3032
4354
|
output = subprocess.check_output(
|
3033
4355
|
'"%s" --version' % path_chromedriver, shell=True
|
3034
4356
|
)
|
@@ -3042,8 +4364,6 @@ def get_local_driver(
|
|
3042
4364
|
ch_driver_version = output
|
3043
4365
|
if driver_version == "keep":
|
3044
4366
|
use_version = ch_driver_version
|
3045
|
-
except Exception:
|
3046
|
-
pass
|
3047
4367
|
disable_build_check = True
|
3048
4368
|
uc_driver_version = None
|
3049
4369
|
if is_using_uc(undetectable, browser_name):
|
@@ -3085,8 +4405,14 @@ def get_local_driver(
|
|
3085
4405
|
except Exception:
|
3086
4406
|
pass # Will need Xvfb on Linux
|
3087
4407
|
elif headless:
|
3088
|
-
if
|
3089
|
-
|
4408
|
+
if (
|
4409
|
+
"--headless" not in chrome_options.arguments
|
4410
|
+
and "--headless=old" not in chrome_options.arguments
|
4411
|
+
):
|
4412
|
+
if headless1:
|
4413
|
+
chrome_options.add_argument("--headless=old")
|
4414
|
+
else:
|
4415
|
+
chrome_options.add_argument("--headless")
|
3090
4416
|
if LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER):
|
3091
4417
|
try:
|
3092
4418
|
make_driver_executable_if_not(LOCAL_CHROMEDRIVER)
|
@@ -3222,6 +4548,10 @@ def get_local_driver(
|
|
3222
4548
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3223
4549
|
)
|
3224
4550
|
with chromedriver_fixing_lock:
|
4551
|
+
with suppress(Exception):
|
4552
|
+
shared_utils.make_writable(
|
4553
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4554
|
+
)
|
3225
4555
|
msg = "chromedriver update needed. Getting it now:"
|
3226
4556
|
if not path_chromedriver:
|
3227
4557
|
msg = "chromedriver not found. Getting it now:"
|
@@ -3236,7 +4566,7 @@ def get_local_driver(
|
|
3236
4566
|
if IS_ARM_MAC and use_uc:
|
3237
4567
|
intel_for_uc = True # Use Intel driver for UC Mode
|
3238
4568
|
if os.path.exists(LOCAL_CHROMEDRIVER):
|
3239
|
-
|
4569
|
+
with suppress(Exception):
|
3240
4570
|
output = subprocess.check_output(
|
3241
4571
|
'"%s" --version' % LOCAL_CHROMEDRIVER,
|
3242
4572
|
shell=True,
|
@@ -3249,8 +4579,6 @@ def get_local_driver(
|
|
3249
4579
|
output = full_ch_driver_version.split(".")[0]
|
3250
4580
|
if int(output) >= 2:
|
3251
4581
|
ch_driver_version = output
|
3252
|
-
except Exception:
|
3253
|
-
pass
|
3254
4582
|
if (
|
3255
4583
|
(
|
3256
4584
|
not use_uc
|
@@ -3315,15 +4643,23 @@ def get_local_driver(
|
|
3315
4643
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3316
4644
|
)
|
3317
4645
|
with uc_lock: # Avoid multithreaded issues
|
4646
|
+
with suppress(Exception):
|
4647
|
+
shared_utils.make_writable(
|
4648
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4649
|
+
)
|
3318
4650
|
if make_uc_driver_from_chromedriver:
|
3319
4651
|
if os.path.exists(LOCAL_CHROMEDRIVER):
|
3320
|
-
|
3321
|
-
|
3322
|
-
|
4652
|
+
with suppress(Exception):
|
4653
|
+
make_driver_executable_if_not(
|
4654
|
+
LOCAL_CHROMEDRIVER
|
4655
|
+
)
|
4656
|
+
shutil.copy2(LOCAL_CHROMEDRIVER, LOCAL_UC_DRIVER)
|
3323
4657
|
elif os.path.exists(path_chromedriver):
|
3324
|
-
|
3325
|
-
|
3326
|
-
|
4658
|
+
with suppress(Exception):
|
4659
|
+
make_driver_executable_if_not(
|
4660
|
+
path_chromedriver
|
4661
|
+
)
|
4662
|
+
shutil.copy2(path_chromedriver, LOCAL_UC_DRIVER)
|
3327
4663
|
try:
|
3328
4664
|
make_driver_executable_if_not(LOCAL_UC_DRIVER)
|
3329
4665
|
except Exception as e:
|
@@ -3354,6 +4690,12 @@ def get_local_driver(
|
|
3354
4690
|
chrome_options.arguments.remove(
|
3355
4691
|
"--headless"
|
3356
4692
|
)
|
4693
|
+
if "--headless=old" in (
|
4694
|
+
chrome_options.arguments
|
4695
|
+
):
|
4696
|
+
chrome_options.arguments.remove(
|
4697
|
+
"--headless=old"
|
4698
|
+
)
|
3357
4699
|
uc_chrome_version = None
|
3358
4700
|
if (
|
3359
4701
|
use_version.isnumeric()
|
@@ -3388,7 +4730,7 @@ def get_local_driver(
|
|
3388
4730
|
chrome_options.add_argument(
|
3389
4731
|
"--user-agent=%s" % user_agent
|
3390
4732
|
)
|
3391
|
-
|
4733
|
+
with suppress(Exception):
|
3392
4734
|
if (
|
3393
4735
|
(
|
3394
4736
|
not user_agent
|
@@ -3397,6 +4739,7 @@ def get_local_driver(
|
|
3397
4739
|
and uc_chrome_version
|
3398
4740
|
and uc_chrome_version >= 117
|
3399
4741
|
and (headless or headless2)
|
4742
|
+
and chromium_arg != "decoy"
|
3400
4743
|
):
|
3401
4744
|
from seleniumbase.console_scripts import (
|
3402
4745
|
sb_install
|
@@ -3416,6 +4759,7 @@ def get_local_driver(
|
|
3416
4759
|
None, # multi_proxy
|
3417
4760
|
None, # user_agent
|
3418
4761
|
None, # recorder_ext
|
4762
|
+
disable_cookies,
|
3419
4763
|
disable_js,
|
3420
4764
|
disable_csp,
|
3421
4765
|
enable_ws,
|
@@ -3427,6 +4771,7 @@ def get_local_driver(
|
|
3427
4771
|
False, # log_cdp_events
|
3428
4772
|
no_sandbox,
|
3429
4773
|
disable_gpu,
|
4774
|
+
False, # headless1
|
3430
4775
|
False, # headless2
|
3431
4776
|
incognito,
|
3432
4777
|
guest_mode,
|
@@ -3494,7 +4839,7 @@ def get_local_driver(
|
|
3494
4839
|
service=service,
|
3495
4840
|
options=headless_options,
|
3496
4841
|
)
|
3497
|
-
|
4842
|
+
with suppress(Exception):
|
3498
4843
|
user_agent = driver.execute_script(
|
3499
4844
|
"return navigator.userAgent;"
|
3500
4845
|
)
|
@@ -3516,16 +4861,12 @@ def get_local_driver(
|
|
3516
4861
|
"--user-agent=%s" % user_agent
|
3517
4862
|
)
|
3518
4863
|
sb_config.uc_agent_cache = user_agent
|
3519
|
-
except Exception:
|
3520
|
-
pass
|
3521
4864
|
driver.quit()
|
3522
|
-
|
3523
|
-
|
4865
|
+
uc_path = None
|
4866
|
+
if os.path.exists(LOCAL_UC_DRIVER):
|
4867
|
+
uc_path = LOCAL_UC_DRIVER
|
4868
|
+
uc_path = os.path.realpath(uc_path)
|
3524
4869
|
try:
|
3525
|
-
uc_path = None
|
3526
|
-
if os.path.exists(LOCAL_UC_DRIVER):
|
3527
|
-
uc_path = LOCAL_UC_DRIVER
|
3528
|
-
uc_path = os.path.realpath(uc_path)
|
3529
4870
|
driver = undetected.Chrome(
|
3530
4871
|
options=chrome_options,
|
3531
4872
|
user_data_dir=user_data_dir,
|
@@ -3538,10 +4879,28 @@ def get_local_driver(
|
|
3538
4879
|
)
|
3539
4880
|
uc_activated = True
|
3540
4881
|
except URLError as e:
|
3541
|
-
if
|
4882
|
+
if (
|
4883
|
+
IS_MAC
|
4884
|
+
and hasattr(e, "args")
|
4885
|
+
and isinstance(e.args, (list, tuple))
|
4886
|
+
and cert in e.args[0]
|
4887
|
+
):
|
3542
4888
|
mac_certificate_error = True
|
3543
4889
|
else:
|
3544
4890
|
raise
|
4891
|
+
except SessionNotCreatedException:
|
4892
|
+
time.sleep(0.2)
|
4893
|
+
driver = undetected.Chrome(
|
4894
|
+
options=chrome_options,
|
4895
|
+
user_data_dir=user_data_dir,
|
4896
|
+
driver_executable_path=uc_path,
|
4897
|
+
browser_executable_path=b_path,
|
4898
|
+
enable_cdp_events=cdp_events,
|
4899
|
+
headless=False, # Xvfb needed!
|
4900
|
+
version_main=uc_chrome_version,
|
4901
|
+
use_subprocess=True, # Always!
|
4902
|
+
)
|
4903
|
+
uc_activated = True
|
3545
4904
|
if mac_certificate_error:
|
3546
4905
|
cf_lock_path = (
|
3547
4906
|
constants.MultiBrowser.CERT_FIXING_LOCK
|
@@ -3552,6 +4911,10 @@ def get_local_driver(
|
|
3552
4911
|
if not os.path.exists(cf_lock_path):
|
3553
4912
|
# Avoid multithreaded issues
|
3554
4913
|
with cf_lock:
|
4914
|
+
with suppress(Exception):
|
4915
|
+
shared_utils.make_writable(
|
4916
|
+
cf_lock_path
|
4917
|
+
)
|
3555
4918
|
# Install Python Certificates (MAC)
|
3556
4919
|
os.system(
|
3557
4920
|
r"bash /Applications/Python*/"
|
@@ -3648,6 +5011,7 @@ def get_local_driver(
|
|
3648
5011
|
None, # multi_proxy
|
3649
5012
|
None, # user_agent
|
3650
5013
|
None, # recorder_ext
|
5014
|
+
disable_cookies,
|
3651
5015
|
disable_js,
|
3652
5016
|
disable_csp,
|
3653
5017
|
enable_ws,
|
@@ -3659,6 +5023,7 @@ def get_local_driver(
|
|
3659
5023
|
False, # log_cdp_events
|
3660
5024
|
no_sandbox,
|
3661
5025
|
disable_gpu,
|
5026
|
+
False, # headless1
|
3662
5027
|
False, # headless2
|
3663
5028
|
incognito,
|
3664
5029
|
guest_mode,
|
@@ -3693,6 +5058,10 @@ def get_local_driver(
|
|
3693
5058
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3694
5059
|
)
|
3695
5060
|
with chromedriver_fixing_lock:
|
5061
|
+
with suppress(Exception):
|
5062
|
+
shared_utils.make_writable(
|
5063
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5064
|
+
)
|
3696
5065
|
if not _was_driver_repaired():
|
3697
5066
|
_repair_chromedriver(
|
3698
5067
|
chrome_options, headless_options, mcv
|
@@ -3724,6 +5093,9 @@ def get_local_driver(
|
|
3724
5093
|
options=chrome_options,
|
3725
5094
|
)
|
3726
5095
|
driver.default_get = driver.get # Save copy of original
|
5096
|
+
driver.cdp = None # Set a placeholder
|
5097
|
+
driver._is_using_cdp = False
|
5098
|
+
driver._is_connected = True
|
3727
5099
|
if uc_activated:
|
3728
5100
|
driver.get = lambda url: uc_special_open_if_cf(
|
3729
5101
|
driver,
|
@@ -3743,20 +5115,87 @@ def get_local_driver(
|
|
3743
5115
|
driver, *args, **kwargs
|
3744
5116
|
)
|
3745
5117
|
)
|
5118
|
+
driver.uc_open_with_disconnect = (
|
5119
|
+
lambda *args, **kwargs: uc_open_with_disconnect(
|
5120
|
+
driver, *args, **kwargs
|
5121
|
+
)
|
5122
|
+
)
|
3746
5123
|
driver.uc_click = lambda *args, **kwargs: uc_click(
|
3747
5124
|
driver, *args, **kwargs
|
3748
5125
|
)
|
5126
|
+
driver.uc_activate_cdp_mode = (
|
5127
|
+
lambda *args, **kwargs: uc_activate_cdp_mode(
|
5128
|
+
driver, *args, **kwargs
|
5129
|
+
)
|
5130
|
+
)
|
5131
|
+
driver.uc_open_with_cdp_mode = (
|
5132
|
+
lambda *args, **kwargs: uc_open_with_cdp_mode(
|
5133
|
+
driver, *args, **kwargs
|
5134
|
+
)
|
5135
|
+
)
|
5136
|
+
driver.uc_gui_press_key = (
|
5137
|
+
lambda *args, **kwargs: uc_gui_press_key(
|
5138
|
+
driver, *args, **kwargs
|
5139
|
+
)
|
5140
|
+
)
|
5141
|
+
driver.uc_gui_press_keys = (
|
5142
|
+
lambda *args, **kwargs: uc_gui_press_keys(
|
5143
|
+
driver, *args, **kwargs
|
5144
|
+
)
|
5145
|
+
)
|
5146
|
+
driver.uc_gui_write = (
|
5147
|
+
lambda *args, **kwargs: uc_gui_write(
|
5148
|
+
driver, *args, **kwargs
|
5149
|
+
)
|
5150
|
+
)
|
5151
|
+
driver.uc_gui_click_x_y = (
|
5152
|
+
lambda *args, **kwargs: uc_gui_click_x_y(
|
5153
|
+
driver, *args, **kwargs
|
5154
|
+
)
|
5155
|
+
)
|
5156
|
+
driver.uc_gui_click_captcha = (
|
5157
|
+
lambda *args, **kwargs: uc_gui_click_captcha(
|
5158
|
+
driver, *args, **kwargs
|
5159
|
+
)
|
5160
|
+
)
|
5161
|
+
driver.uc_gui_click_cf = (
|
5162
|
+
lambda *args, **kwargs: uc_gui_click_cf(
|
5163
|
+
driver, *args, **kwargs
|
5164
|
+
)
|
5165
|
+
)
|
5166
|
+
driver.uc_gui_click_rc = (
|
5167
|
+
lambda *args, **kwargs: uc_gui_click_rc(
|
5168
|
+
driver, *args, **kwargs
|
5169
|
+
)
|
5170
|
+
)
|
5171
|
+
driver.uc_gui_handle_captcha = (
|
5172
|
+
lambda *args, **kwargs: uc_gui_handle_captcha(
|
5173
|
+
driver, *args, **kwargs
|
5174
|
+
)
|
5175
|
+
)
|
5176
|
+
driver.uc_gui_handle_cf = (
|
5177
|
+
lambda *args, **kwargs: uc_gui_handle_cf(
|
5178
|
+
driver, *args, **kwargs
|
5179
|
+
)
|
5180
|
+
)
|
5181
|
+
driver.uc_gui_handle_rc = (
|
5182
|
+
lambda *args, **kwargs: uc_gui_handle_rc(
|
5183
|
+
driver, *args, **kwargs
|
5184
|
+
)
|
5185
|
+
)
|
3749
5186
|
driver.uc_switch_to_frame = (
|
3750
5187
|
lambda *args, **kwargs: uc_switch_to_frame(
|
3751
5188
|
driver, *args, **kwargs
|
3752
5189
|
)
|
3753
5190
|
)
|
5191
|
+
driver._is_hidden = (headless or headless2)
|
5192
|
+
driver._is_using_uc = True
|
3754
5193
|
if mobile_emulator:
|
3755
5194
|
uc_metrics = {}
|
3756
5195
|
if (
|
3757
5196
|
isinstance(device_width, int)
|
3758
5197
|
and isinstance(device_height, int)
|
3759
|
-
and isinstance(device_pixel_ratio, int)
|
5198
|
+
and isinstance(device_pixel_ratio, (int, float))
|
3760
5199
|
):
|
3761
5200
|
uc_metrics["width"] = device_width
|
3762
5201
|
uc_metrics["height"] = device_height
|
@@ -3773,13 +5212,11 @@ def get_local_driver(
|
|
3773
5212
|
"mobile": True
|
3774
5213
|
}
|
3775
5214
|
)
|
3776
|
-
|
5215
|
+
with suppress(Exception):
|
3777
5216
|
driver.execute_cdp_cmd(
|
3778
5217
|
'Emulation.setDeviceMetricsOverride',
|
3779
5218
|
set_device_metrics_override
|
3780
5219
|
)
|
3781
|
-
except Exception:
|
3782
|
-
pass
|
3783
5220
|
return extend_driver(driver)
|
3784
5221
|
else: # Running headless on Linux (and not using --uc)
|
3785
5222
|
try:
|
@@ -3823,25 +5260,24 @@ def get_local_driver(
|
|
3823
5260
|
chromedr_fixing_lock = fasteners.InterProcessLock(
|
3824
5261
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3825
5262
|
)
|
5263
|
+
D_F_L = constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3826
5264
|
with chromedr_fixing_lock:
|
5265
|
+
with suppress(Exception):
|
5266
|
+
shared_utils.make_writable(D_F_L)
|
3827
5267
|
if not _was_driver_repaired():
|
3828
|
-
|
5268
|
+
with suppress(Exception):
|
3829
5269
|
_repair_chromedriver(
|
3830
5270
|
chrome_options, chrome_options, mcv
|
3831
5271
|
)
|
3832
5272
|
_mark_driver_repaired()
|
3833
|
-
except Exception:
|
3834
|
-
pass
|
3835
5273
|
else:
|
3836
5274
|
if not _was_driver_repaired():
|
3837
|
-
|
5275
|
+
with suppress(Exception):
|
3838
5276
|
_repair_chromedriver(
|
3839
5277
|
chrome_options, chrome_options, mcv
|
3840
5278
|
)
|
3841
|
-
except Exception:
|
3842
|
-
pass
|
3843
5279
|
_mark_driver_repaired()
|
3844
|
-
|
5280
|
+
with suppress(Exception):
|
3845
5281
|
service = ChromeService(
|
3846
5282
|
log_output=os.devnull,
|
3847
5283
|
service_args=["--disable-build-check"],
|
@@ -3851,8 +5287,6 @@ def get_local_driver(
|
|
3851
5287
|
options=chrome_options,
|
3852
5288
|
)
|
3853
5289
|
return extend_driver(driver)
|
3854
|
-
except Exception:
|
3855
|
-
pass
|
3856
5290
|
# Use the virtual display on Linux during headless errors
|
3857
5291
|
logging.debug(
|
3858
5292
|
"\nWarning: Chrome failed to launch in"
|
@@ -3861,6 +5295,8 @@ def get_local_driver(
|
|
3861
5295
|
)
|
3862
5296
|
if "--headless" in chrome_options.arguments:
|
3863
5297
|
chrome_options.arguments.remove("--headless")
|
5298
|
+
if "--headless=old" in chrome_options.arguments:
|
5299
|
+
chrome_options.arguments.remove("--headless=old")
|
3864
5300
|
service = ChromeService(
|
3865
5301
|
log_output=os.devnull,
|
3866
5302
|
service_args=["--disable-build-check"]
|
@@ -3869,18 +5305,16 @@ def get_local_driver(
|
|
3869
5305
|
service=service, options=chrome_options
|
3870
5306
|
)
|
3871
5307
|
return extend_driver(driver)
|
3872
|
-
except Exception:
|
5308
|
+
except Exception as original_exception:
|
3873
5309
|
if is_using_uc(undetectable, browser_name):
|
3874
5310
|
raise
|
3875
5311
|
# Try again if Chrome didn't launch
|
3876
|
-
|
5312
|
+
with suppress(Exception):
|
3877
5313
|
service = ChromeService(service_args=["--disable-build-check"])
|
3878
5314
|
driver = webdriver.Chrome(
|
3879
5315
|
service=service, options=chrome_options
|
3880
5316
|
)
|
3881
5317
|
return extend_driver(driver)
|
3882
|
-
except Exception:
|
3883
|
-
pass
|
3884
5318
|
if user_data_dir:
|
3885
5319
|
print("\nUnable to set user_data_dir while starting Chrome!\n")
|
3886
5320
|
raise
|
@@ -3905,8 +5339,11 @@ def get_local_driver(
|
|
3905
5339
|
log_output=os.devnull,
|
3906
5340
|
service_args=["--disable-build-check"]
|
3907
5341
|
)
|
3908
|
-
|
3909
|
-
|
5342
|
+
try:
|
5343
|
+
driver = webdriver.Chrome(service=service)
|
5344
|
+
return extend_driver(driver)
|
5345
|
+
except Exception:
|
5346
|
+
raise original_exception
|
3910
5347
|
else:
|
3911
5348
|
raise Exception(
|
3912
5349
|
"%s is not a valid browser option for this system!" % browser_name
|