I cannot configure the path of downloading a file in headless mode with chrome but if I remove the headless mode, I can change the download path.
The current behaviour downloading the file in the current directory of the running code with headless mode.
class ChromeWithPrefs(uc.Chrome):
def __init__(self, *args, options=None, **kwargs):
if options:
self._handle_prefs(options)
super().__init__(*args, options=options, **kwargs)
# remove the user_data_dir when quitting
self.keep_user_data_dir = False
@staticmethod
def _handle_prefs(options):
if prefs := options.experimental_options.get("prefs"):
# turn a (dotted key, value) into a proper nested dict
def undot_key(key, value):
if "." in key:
key, rest = key.split(".", 1)
# print("Key dotted", key)
# print("rest dotted", rest)
value = undot_key(rest, value)
# print("Value dotted: ", 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 an user_data_dir and add its path to the options
user_data_dir = os.path.normpath(tempfile.mkdtemp())
options.add_argument(f"--user-data-dir={user_data_dir}")
# 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"]
options = uc.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
prefs = {
"download.default_directory": path, ### Set the path accordingly
"profile.default_content_settings.popups": 0,
"download.prompt_for_download": False, ## change the downpath accordingly
"download.directory_upgrade": True,
}
options.add_experimental_option("prefs", prefs)
browser = ChromeWithPrefs(options=options)