diff --git a/undetected_chromedriver/__init__.py b/undetected_chromedriver/__init__.py index 58342f3..cedae06 100644 --- a/undetected_chromedriver/__init__.py +++ b/undetected_chromedriver/__init__.py @@ -19,7 +19,7 @@ by UltrafunkAmsterdam (https://github.com/ultrafunkamsterdam) """ -__version__ = "3.1.5r2" +__version__ = "3.1.5r4" import json @@ -235,6 +235,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): if not options: options = ChromeOptions() + try: if hasattr(options, "_session") and options._session is not None: # prevent reuse of options, @@ -260,6 +261,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): options.add_argument("--remote-debugging-host=%s" % debug_host) options.add_argument("--remote-debugging-port=%s" % debug_port) + if user_data_dir: + options.add_argument('--user-data-dir=%s' % user_data_dir) + language, keep_user_data_dir = None, bool(user_data_dir) # see if a custom user profile is specified in options @@ -355,6 +359,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): or divmod(logging.getLogger().getEffectiveLevel(), 10)[0] ) + if hasattr(options, 'handle_prefs'): + options.handle_prefs(user_data_dir) + # fix exit_type flag to prevent tab-restore nag try: with open( diff --git a/undetected_chromedriver/options.py b/undetected_chromedriver/options.py index d6f8b8f..f262319 100644 --- a/undetected_chromedriver/options.py +++ b/undetected_chromedriver/options.py @@ -2,7 +2,9 @@ # this module is part of undetected_chromedriver +import json import os + from selenium.webdriver.chromium.options import ChromiumOptions as _ChromiumOptions @@ -29,6 +31,38 @@ class ChromeOptions(_ChromiumOptions): apath = os.path.abspath(path) self._user_data_dir = os.path.normpath(apath) + @staticmethod + def _undot_key(key, value): + """turn a (dotted key, value) into a proper nested dict""" + if "." in key: + key, rest = key.split(".", 1) + value = ChromeOptions._undot_key(rest, value) + return {key: value} + + def handle_prefs(self, user_data_dir): + prefs = self.experimental_options.get("prefs") + if prefs: + + user_data_dir = user_data_dir or self._user_data_dir + default_path = os.path.join(user_data_dir, "Default") + os.makedirs(default_path, exist_ok=True) + + # undot prefs dict keys + undot_prefs = {} + for key, value in prefs.items(): + undot_prefs.update(self._undot_key(key, value)) + + prefs_file = os.path.join(default_path, "Preferences") + if os.path.exists(prefs_file): + with open(prefs_file, encoding="latin1", mode="r") as f: + undot_prefs.update(json.load(f)) + + with open(prefs_file, encoding="latin1", mode="w") as f: + json.dump(undot_prefs, f) + + # remove the experimental_options to avoid an error + del self._experimental_options["prefs"] + @classmethod def from_options(cls, options): o = cls()