i am using undetected chrome driver for my project.
i wanted to turn off Use Secure DNS option seen there chrome://settings/security
.
i found here https://stackoverflow.com/a/74334553 that using localState option we can achieve that and its working perfectly in simple selenium.
but in undetected chrome driver i get error "invalid argument: unrecognized chrome option: localState", i guess thats because undetected chromedriver does not support experimental options.
so i did something like that: attach user-data-dir in options. make Local State file in that dir. saved my json in that file.
Results:
when i launch driver and go to chrome://settings/security
i see secure DNS option turned off, but it didnt make any effect in ja3 fingerprint.
sample code:
class ChromeWithPrefs(uc.Chrome):
def __init__(self, *args, options=None, **kwargs):
if options:
user_data_dir = os.path.normpath(tempfile.mkdtemp())
options.add_argument(f"--user-data-dir={user_data_dir}")
self._handle_local(options, user_data_dir)
self._handle_prefs(options, user_data_dir)
super().__init__(*args, options=options, **kwargs)
# remove the user_data_dir when quitting
self.keep_user_data_dir = False
@staticmethod
def _handle_prefs(options, user_data_dir):
prefs = options.experimental_options.get("prefs")
if prefs:
# turn a (dotted key, value) into a proper nested dict
def undot_key(key, value):
if "." in key:
key, rest = key.split(".", 1)
value = undot_key(rest, value)
return {key: value}
# undot prefs dict keys
undot_prefs = reduce(
lambda d1, d2: {**d1, **d2}, # merge dicts
(undot_key(key, value) for key, value in prefs.items()),
)
# create the preferences json file in its default directory
default_dir = os.path.join(user_data_dir, "Default")
os.mkdir(default_dir)
prefs_file = os.path.join(default_dir, "Preferences")
with open(prefs_file, encoding="latin1", mode="w") as f:
json.dump(undot_prefs, f)
# pylint: disable=protected-access
# remove the experimental_options to avoid an error
del options._experimental_options["prefs"]
@staticmethod
def _handle_local(options, user_data_dir):
prefs = options.experimental_options.get("localState")
if prefs:
# turn a (dotted key, value) into a proper nested dict
def undot_key(key, value):
if "." in key:
key, rest = key.split(".", 1)
value = undot_key(rest, value)
return {key: value}
# undot prefs dict keys
undot_prefs = reduce(
lambda d1, d2: {**d1, **d2}, # merge dicts
(undot_key(key, value) for key, value in prefs.items()),
)
# create the preferences json file in its default directory
prefs_file = os.path.join(user_data_dir, "Local State")
with open(prefs_file, encoding="latin1", mode="w") as f:
json.dump(undot_prefs, f)
# pylint: disable=protected-access
# remove the experimental_options to avoid an error
del options._experimental_options["localState"]
options_chrome = webdriver.ChromeOptions() # undetected
options_chrome.add_argument("--start-maximized")
local_state = {
"dns_over_https.mode": "off"
}
options_chrome.add_experimental_option('localState', local_state)
driver = ChromeWithPrefs(
options=options_chrome, suppress_welcome=True
)