Skip to content

Commit 9c19808

Browse files
committed
Prevent detection by anti-bot services (with --uc)
1 parent 6dece1d commit 9c19808

File tree

4 files changed

+106
-47
lines changed

4 files changed

+106
-47
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,15 @@ chromedriver
7171
geckodriver
7272
msedgedriver
7373
operadriver
74+
uc_driver
7475
MicrosoftWebDriver.exe
7576
headless_ie_selenium.exe
7677
IEDriverServer.exe
7778
chromedriver.exe
7879
geckodriver.exe
7980
msedgedriver.exe
8081
operadriver.exe
82+
uc_driver.exe
8183

8284
# msedgedriver requirements
8385
libc++.dylib

seleniumbase/console_scripts/sb_mkdir.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,15 @@ def main():
244244
data.append("geckodriver")
245245
data.append("msedgedriver")
246246
data.append("operadriver")
247+
data.append("uc_driver")
247248
data.append("MicrosoftWebDriver.exe")
248249
data.append("headless_ie_selenium.exe")
249250
data.append("IEDriverServer.exe")
250251
data.append("chromedriver.exe")
251252
data.append("geckodriver.exe")
252253
data.append("msedgedriver.exe")
253254
data.append("operadriver.exe")
255+
data.append("uc_driver.exe")
254256
data.append("logs")
255257
data.append("latest_logs")
256258
data.append("log_archives")

seleniumbase/core/browser_launcher.py

Lines changed: 97 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
import logging
33
import os
44
import re
5-
import sys
5+
import shutil
66
import subprocess
7+
import sys
78
import time
89
import urllib3
910
import warnings
@@ -53,11 +54,13 @@
5354
LOCAL_IEDRIVER = None
5455
LOCAL_HEADLESS_IEDRIVER = None
5556
LOCAL_OPERADRIVER = None
57+
LOCAL_UC_DRIVER = None
5658
if "darwin" in PLATFORM or "linux" in PLATFORM:
5759
LOCAL_CHROMEDRIVER = DRIVER_DIR + "/chromedriver"
5860
LOCAL_GECKODRIVER = DRIVER_DIR + "/geckodriver"
5961
LOCAL_EDGEDRIVER = DRIVER_DIR + "/msedgedriver"
6062
LOCAL_OPERADRIVER = DRIVER_DIR + "/operadriver"
63+
LOCAL_UC_DRIVER = DRIVER_DIR + "/uc_driver"
6164
elif "win32" in PLATFORM or "win64" in PLATFORM or "x64" in PLATFORM:
6265
IS_WINDOWS = True
6366
LOCAL_EDGEDRIVER = DRIVER_DIR + "/msedgedriver.exe"
@@ -66,6 +69,7 @@
6669
LOCAL_CHROMEDRIVER = DRIVER_DIR + "/chromedriver.exe"
6770
LOCAL_GECKODRIVER = DRIVER_DIR + "/geckodriver.exe"
6871
LOCAL_OPERADRIVER = DRIVER_DIR + "/operadriver.exe"
72+
LOCAL_UC_DRIVER = DRIVER_DIR + "/uc_driver.exe"
6973
else:
7074
# Cannot determine system
7175
pass # SeleniumBase will use web drivers from the System PATH by default
@@ -356,24 +360,24 @@ def _set_chrome_options(
356360
chrome_options = undetected.ChromeOptions()
357361
elif browser_name == constants.Browser.OPERA:
358362
chrome_options = webdriver.opera.options.Options()
359-
prefs = {
360-
"download.default_directory": downloads_path,
361-
"local_discovery.notifications_enabled": False,
362-
"credentials_enable_service": False,
363-
"download.prompt_for_download": False,
364-
"download.directory_upgrade": True,
365-
"safebrowsing.enabled": False,
366-
"safebrowsing.disable_download_protection": True,
367-
"default_content_setting_values.notifications": 0,
368-
"default_content_settings.popups": 0,
369-
"managed_default_content_settings.popups": 0,
370-
"content_settings.exceptions.automatic_downloads.*.setting": 1,
371-
"profile.password_manager_enabled": False,
372-
"profile.default_content_setting_values.notifications": 2,
373-
"profile.default_content_settings.popups": 0,
374-
"profile.managed_default_content_settings.popups": 0,
375-
"profile.default_content_setting_values.automatic_downloads": 1,
376-
}
363+
364+
prefs = {}
365+
prefs["download.default_directory"] = downloads_path
366+
prefs["local_discovery.notifications_enabled"] = False
367+
prefs["credentials_enable_service"] = False
368+
prefs["download.prompt_for_download"] = False
369+
prefs["download.directory_upgrade"] = True
370+
prefs["safebrowsing.enabled"] = False
371+
prefs["default_content_setting_values.notifications"] = 0
372+
prefs["content_settings.exceptions.automatic_downloads.*.setting"] = 1
373+
prefs["safebrowsing.disable_download_protection"] = True
374+
prefs["default_content_settings.popups"] = 0
375+
prefs["managed_default_content_settings.popups"] = 0
376+
prefs["profile.password_manager_enabled"] = False
377+
prefs["profile.default_content_setting_values.notifications"] = 2
378+
prefs["profile.default_content_settings.popups"] = 0
379+
prefs["profile.managed_default_content_settings.popups"] = 0
380+
prefs["profile.default_content_setting_values.automatic_downloads"] = 1
377381
if locale_code:
378382
prefs["intl.accept_languages"] = locale_code
379383
if block_images:
@@ -477,31 +481,6 @@ def _set_chrome_options(
477481
# load-extension input can be a comma-separated list
478482
abs_path = os.path.abspath(extension_dir)
479483
chrome_options = add_chrome_ext_dir(chrome_options, abs_path)
480-
chrome_options.add_argument("--test-type")
481-
chrome_options.add_argument("--log-level=3")
482-
chrome_options.add_argument("--no-first-run")
483-
if devtools and not headless:
484-
chrome_options.add_argument("--auto-open-devtools-for-tabs")
485-
chrome_options.add_argument("--allow-file-access-from-files")
486-
chrome_options.add_argument("--allow-insecure-localhost")
487-
chrome_options.add_argument("--allow-running-insecure-content")
488-
if user_agent:
489-
chrome_options.add_argument("--user-agent=%s" % user_agent)
490-
chrome_options.add_argument("--disable-infobars")
491-
chrome_options.add_argument("--disable-notifications")
492-
chrome_options.add_argument("--disable-save-password-bubble")
493-
chrome_options.add_argument("--disable-single-click-autofill")
494-
chrome_options.add_argument(
495-
"--disable-autofill-keyboard-accessory-view[8]"
496-
)
497-
chrome_options.add_argument("--disable-browser-side-navigation")
498-
chrome_options.add_argument("--disable-translate")
499-
chrome_options.add_argument("--homepage=about:blank")
500-
chrome_options.add_argument("--dns-prefetch-disable")
501-
chrome_options.add_argument("--dom-automation")
502-
chrome_options.add_argument("--disable-hang-monitor")
503-
chrome_options.add_argument("--disable-prompt-on-repost")
504-
chrome_options.add_argument("--disable-3d-apis")
505484
if (
506485
selenium4_or_newer
507486
and page_load_strategy
@@ -619,6 +598,33 @@ def _set_chrome_options(
619598
chromium_arg_item = "--" + chromium_arg_item
620599
if len(chromium_arg_item) >= 3:
621600
chrome_options.add_argument(chromium_arg_item)
601+
if devtools and not headless:
602+
chrome_options.add_argument("--auto-open-devtools-for-tabs")
603+
if user_agent:
604+
chrome_options.add_argument("--user-agent=%s" % user_agent)
605+
chrome_options.add_argument("--disable-browser-side-navigation")
606+
chrome_options.add_argument("--disable-save-password-bubble")
607+
chrome_options.add_argument("--disable-single-click-autofill")
608+
chrome_options.add_argument("--allow-file-access-from-files")
609+
chrome_options.add_argument("--disable-prompt-on-repost")
610+
chrome_options.add_argument("--dns-prefetch-disable")
611+
chrome_options.add_argument("--disable-translate")
612+
chrome_options.add_argument("--disable-3d-apis")
613+
if is_using_uc(undetectable, browser_name):
614+
return chrome_options
615+
chrome_options.add_argument("--test-type")
616+
chrome_options.add_argument("--log-level=3")
617+
chrome_options.add_argument("--no-first-run")
618+
chrome_options.add_argument("--allow-insecure-localhost")
619+
chrome_options.add_argument("--allow-running-insecure-content")
620+
chrome_options.add_argument("--disable-infobars")
621+
chrome_options.add_argument("--disable-notifications")
622+
chrome_options.add_argument(
623+
"--disable-autofill-keyboard-accessory-view[8]"
624+
)
625+
chrome_options.add_argument("--homepage=about:blank")
626+
chrome_options.add_argument("--dom-automation")
627+
chrome_options.add_argument("--disable-hang-monitor")
622628
return chrome_options
623629

624630

@@ -2340,6 +2346,45 @@ def get_local_driver(
23402346
override="chromedriver %s" % use_version
23412347
)
23422348
sys.argv = sys_args # Put back original sys args
2349+
if is_using_uc(undetectable, browser_name):
2350+
uc_lock = fasteners.InterProcessLock(
2351+
constants.MultiBrowser.DRIVER_FIXING_LOCK
2352+
)
2353+
with uc_lock: # No UC multithreaded tests
2354+
uc_driver_version = None
2355+
if os.path.exists(LOCAL_UC_DRIVER):
2356+
try:
2357+
output = subprocess.check_output(
2358+
"%s --version" % LOCAL_UC_DRIVER, shell=True
2359+
)
2360+
if IS_WINDOWS:
2361+
output = output.decode("latin1")
2362+
else:
2363+
output = output.decode("utf-8")
2364+
output = output.split(" ")[1].split(".")[0]
2365+
if int(output) >= 72:
2366+
uc_driver_version = output
2367+
except Exception:
2368+
pass
2369+
if (
2370+
uc_driver_version != use_version
2371+
and use_version != "latest"
2372+
):
2373+
if os.path.exists(LOCAL_CHROMEDRIVER):
2374+
shutil.copyfile(
2375+
LOCAL_CHROMEDRIVER, LOCAL_UC_DRIVER
2376+
)
2377+
elif os.path.exists(path_chromedriver):
2378+
shutil.copyfile(
2379+
path_chromedriver, LOCAL_UC_DRIVER
2380+
)
2381+
try:
2382+
make_driver_executable_if_not(LOCAL_UC_DRIVER)
2383+
except Exception as e:
2384+
logging.debug(
2385+
"\nWarning: Could not make uc_driver"
2386+
" executable: %s" % e
2387+
)
23432388
if (
23442389
not headless
23452390
or "linux" not in PLATFORM
@@ -2377,9 +2422,14 @@ def get_local_driver(
23772422
)
23782423
with uc_lock: # No UC multithreaded tests
23792424
try:
2425+
uc_path = None
2426+
if os.path.exists(LOCAL_UC_DRIVER):
2427+
uc_path = LOCAL_UC_DRIVER
2428+
uc_path = os.path.realpath(uc_path)
23802429
driver = undetected.Chrome(
23812430
options=chrome_options,
2382-
headless=False, # Xvfb needed
2431+
driver_executable_path=uc_path,
2432+
headless=False, # Xvfb needed!
23832433
version_main=uc_chrome_version,
23842434
)
23852435
except URLError as e:
@@ -2394,7 +2444,8 @@ def get_local_driver(
23942444
)
23952445
driver = undetected.Chrome(
23962446
options=chrome_options,
2397-
headless=False, # Xvfb needed
2447+
driver_executable_path=uc_path,
2448+
headless=False, # Xvfb needed!
23982449
version_main=uc_chrome_version,
23992450
)
24002451
else:

seleniumbase/undetected/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import time
77
import selenium.webdriver.chrome.webdriver
88
import selenium.webdriver.common.service
9+
from selenium.webdriver.chrome.service import Service as ChromeService
910
from .dprocess import start_detached
1011
from .options import ChromeOptions
1112
from .patcher import IS_POSIX
@@ -50,7 +51,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
5051
def __init__(
5152
self,
5253
options=None,
53-
service_=None,
5454
user_data_dir=None,
5555
driver_executable_path=None,
5656
browser_executable_path=None,
@@ -263,6 +263,10 @@ def __init__(
263263
close_fds=IS_POSIX,
264264
)
265265
self.browser_pid = browser.pid
266+
service_ = ChromeService(
267+
executable_path=patcher.executable_path,
268+
log_path=os.devnull,
269+
)
266270
super(Chrome, self).__init__(
267271
port=port,
268272
options=options,

0 commit comments

Comments
 (0)