Skip to content

Commit 1a373e7

Browse files
committed
support stealth driver
Signed-off-by: Tin Lai <[email protected]>
1 parent 4aee542 commit 1a373e7

File tree

3 files changed

+68
-18
lines changed

3 files changed

+68
-18
lines changed

echo360/downloader.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .echo_exceptions import EchoLoginError
99
from .utils import naive_versiontuple, PERSISTENT_SESSION_FOLDER
1010

11-
11+
import pip_ensure_version
1212
from pick import pick
1313
import selenium
1414
from selenium import webdriver
@@ -21,6 +21,40 @@
2121
_LOGGER = logging.getLogger(__name__)
2222

2323

24+
def build_stealth_driver(
25+
use_local_binary,
26+
selenium_version_ge_4100,
27+
setup_credential,
28+
user_agent,
29+
log_path,
30+
persistent_session,
31+
):
32+
pip_ensure_version.require_package("undetected-chromedriver")
33+
import undetected_chromedriver as uc
34+
35+
kwargs = dict()
36+
if persistent_session:
37+
kwargs["user_data_dir"] = PERSISTENT_SESSION_FOLDER
38+
print(
39+
">> Warning: persistent session *might* not supported by stealth. If it has issue, try to delete '{}' folder.".format(
40+
PERSISTENT_SESSION_FOLDER
41+
)
42+
)
43+
44+
from selenium.webdriver.chrome.options import Options
45+
46+
opts = Options()
47+
opts.add_argument("--window-size=1920x1080")
48+
opts.add_argument("user-agent={}".format(user_agent))
49+
50+
if not selenium_version_ge_4100:
51+
print(">> This version of selenium might not be supported by stealth")
52+
53+
driver = uc.Chrome(**kwargs)
54+
55+
return driver
56+
57+
2458
def build_chrome_driver(
2559
use_local_binary,
2660
selenium_version_ge_4100,
@@ -193,6 +227,8 @@ def __init__(
193227
driver_builder = build_chrome_driver
194228
elif webdriver_to_use == "firefox":
195229
driver_builder = build_firefox_driver
230+
elif webdriver_to_use == "stealth":
231+
driver_builder = build_stealth_driver
196232
else:
197233
driver_builder = build_phantomjs_driver
198234

echo360/main.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ def handle_args():
114114
help="Force the echo360.py script to download a local \
115115
binary file for phantomjs (will override system bin)",
116116
)
117+
parser.add_argument(
118+
"--stealth",
119+
action="store_true",
120+
default=False,
121+
dest="use_stealth",
122+
help="Use Stealth Chrome Driver to bypass some bot detection (e.g. useful for FIDO).",
123+
)
117124
parser.add_argument(
118125
"--chrome",
119126
action="store_true",
@@ -222,7 +229,9 @@ def handle_args():
222229
_LOGGER.debug("Hostname: %s, UUID: %s", course_hostname, course_url)
223230

224231
webdriver_to_use = "phantomjs"
225-
if args["use_chrome"]:
232+
if args["use_stealth"]:
233+
webdriver_to_use = "stealth"
234+
elif args["use_chrome"]:
226235
webdriver_to_use = "chrome"
227236
elif args["use_firefox"]:
228237
webdriver_to_use = "firefox"
@@ -305,28 +314,32 @@ def cmd_exists(x):
305314
)
306315

307316
binary_type = "geckodriver"
317+
elif webdriver_to_use == "stealth":
318+
binary_type = None
308319
else:
309320
from .binary_downloader.phantomjs import (
310321
PhantomjsDownloader as binary_downloader,
311322
)
312323

313324
binary_type = "phantomjs"
314-
binary_downloader = binary_downloader() # initialise class
315-
_LOGGER.debug(
316-
"binary_downloader link: %s, bin path: %s",
317-
binary_downloader.get_download_link(),
318-
binary_downloader.get_bin(),
319-
)
320-
# First test for existance of localbinary file
321-
if not os.path.isfile(binary_downloader.get_bin()):
322-
# If failed, then test for existance of global executable in PATH
323-
if cmd_exists(binary_type):
324-
use_local_binary = False
325-
_LOGGER.debug("Using global binary file")
326-
else:
327-
# None exists, download binary file
328-
start_download_binary(binary_downloader, binary_type)
329-
_LOGGER.debug("Downloading binary file")
325+
326+
if binary_type:
327+
binary_downloader = binary_downloader() # initialise class
328+
_LOGGER.debug(
329+
"binary_downloader link: %s, bin path: %s",
330+
binary_downloader.get_download_link(),
331+
binary_downloader.get_bin(),
332+
)
333+
# First test for existance of localbinary file
334+
if not os.path.isfile(binary_downloader.get_bin()):
335+
# If failed, then test for existance of global executable in PATH
336+
if cmd_exists(binary_type):
337+
use_local_binary = False
338+
_LOGGER.debug("Using global binary file")
339+
else:
340+
# None exists, download binary file
341+
start_download_binary(binary_downloader, binary_type)
342+
_LOGGER.debug("Downloading binary file")
330343

331344
if download_binary:
332345
start_download_binary(binary_downloader, binary_type, manual=True)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ requests>=2.8.14
55
gevent>=1.2.2
66
wget>=3.2
77
pick==0.6.7
8+
pip_ensure_version==1.0.0
89
tqdm

0 commit comments

Comments
 (0)