Selenium Webdriver in Python - files download directory change in Chrome preferences
Asked Answered
D

11

58

I'm using Selenium Webdriver (in Python) to automate the downloading of thousands of files. I want to set Chrome's download folder programmatically. After reading this, I tried this:

chromepath = '/Users/thiagomarzagao/Desktop/searchcode/chromedriver'
desired_caps = {'prefs': {'download': {'default_directory': '/Users/thiagomarzagao/Desktop/downloaded_files/'}}}
driver = webdriver.Chrome(executable_path = chromepath, desired_capabilities = desired_caps)

No good. Downloads still go to the default download folder ("/Users/thiagomarzagao/Downloads").

Any thoughts?

(Python 2.7.5, Selenium 2.2.0, Chromedriver 2.1.210398, Mac OS X 10.6.8)

Dov answered 2/8, 2013 at 21:26 Comment(0)
V
97

The following worked for me:

chromeOptions = webdriver.ChromeOptions()
prefs = {"download.default_directory" : "/some/path"}
chromeOptions.add_experimental_option("prefs",prefs)
chromedriver = "path/to/chromedriver.exe"
driver = webdriver.Chrome(executable_path=chromedriver, options=chromeOptions)

Source: https://sites.google.com/a/chromium.org/chromedriver/capabilities

Varini answered 26/9, 2013 at 9:46 Comment(7)
This looks promising. Alas, in the end I gave up on Chrome altogether and completely rewrote the code, but eventually I'll go back to it and test your solution.Dov
Alas, I just tested it and it didn't work for me. The code doesn't crash, it just silently downloads nothing.Dov
A virtually identical version of this works for me where I omit the executable_path=chromedriver, argument to the Chrome call.Cabanatuan
Do I understand correctly that this solution will re-initiate the driver and hence you need to driver.get(_) a new site to bear this settings ? Is there a way that does not require a new session ? I would like to keep the old session, just modify the download location as we could do manually with a Chrome session that is available. I am downloading multiple files and would like each batch to be saved to their respective directory.Knight
I'm not sure about your use case but when I used this solution, the above code belongs in the setup of the suite (I am using Robot Framework) hence this is the driver used throughout the test execution.Varini
Is there a way to change download path while on current session, similar to how you click Chrome Settings->Download ? The answer I saw always incur building new option + new driver + get a whole new session . I would wish not to close the current session, since my folder separation based on each item in a drop-down list and there's no need to reload a new page. There are thousands of items in that drop-down; the accepted method means closing and loading the page thousands times.Knight
This solution worked for me but with one caveat. I found that I needed to put time.sleep(5) to get it to download to that folder, or any folder really. It was the last thing I was doing in my program so it would shut down the browser before it could finish downloading. Obviously you can adjust the sleep time based on your needs.Keeley
A
46

If anyone is still having trouble and the above solutions didn't work, I found adding a following slash ('\') to my download path.

Mine looked like this:

    if browser == 'chrome':
        options = webdriver.ChromeOptions()
        options.add_argument("--start-maximized")
        prefs = {"profile.default_content_settings.popups": 0,
                 "download.default_directory": r"C:\Users\user_dir\Desktop\\", # IMPORTANT - ENDING SLASH V IMPORTANT
                 "directory_upgrade": True}
        options.add_experimental_option("prefs", prefs)
        return webdriver.Chrome(executable_path=Base.chromedriver_dir, chrome_options=options)
Aerodrome answered 22/3, 2017 at 5:41 Comment(9)
You are a rock star. This ought to be the best answerGoing
@Aerodrome What is the purpose of adding the double dashes -- before "start-maximised"?Chilton
@Chilton Just standard nomenclature I think. This seems to be a complete list of them. peter.sh/experiments/chromium-command-line-switchesAerodrome
This also helped on Linux (Ubuntu) - I had an exact same issue. Adding a trailing slash to my custom downloads folder made it work: "/home/me/Desktop/" instead of "/home/me/Desktop". Thanks for this answer, @Aerodrome :)Pleochroism
Hmmm. Sad that it's 2020 and still adding slashes to the downloads path to make our code work.Brainwork
Hi Is there someway i can implement the same in IE?Reduplicative
Inputting the download directory as per this answer seems to be the solution to the issue with trying to deploy the currently selected answer.Paulie
does this not work without --start-maximized option added?Hollo
@Hollo --start-maximized is not necessary for the download path to workAerodrome
I
11
# -*- coding: utf-8 -*-
from selenium import webdriver 
from selenium.webdriver.chrome.options import Options
import time
temp_directory = ""
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1920x1080")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--verbose')
chrome_options.add_experimental_option("prefs", {
        "download.default_directory": "<path to the folder of download>",
        "download.prompt_for_download": False,
        "download.directory_upgrade": True,
        "safebrowsing_for_trusted_sources_enabled": False,
        "safebrowsing.enabled": False
})
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-software-rasterizer')
url = "https://www.thinkbroadband.com/download"
driver = webdriver.Chrome(executable_path = './chromedriver' ,chrome_options = chrome_options)
driver.get(url)
time.sleep(5)
driver.find_element_by_css_selector("div.module:nth-child(8) > p:nth-child(1) > a:nth-child(1) > img:nth-child(1)").click()
Ivan answered 7/4, 2021 at 20:50 Comment(4)
In my case I only needed the parameter to pass in chrome options, in prefs download.default_directory : path/to/file worked for meDekameter
Keep in mind i saw many cases depending on the version of selenium driver , the custom download directory won't works only in headless mode .Ivan
This is the only example that works for me. Great job!Loseff
In my case it works with the recommendation of @Mhadhbiissam the directory works only if it is executed in headless modeAlterant
T
8

I think you also need

"directory_upgrade": true

Using the dictionary directly in a Chrome 'Prefrences' file, on a local windows install of chrome Version 28.0.1500.95 m, with the following download options:

   "download": {
      "default_directory": "C:\\Users\\rdub\\Desktop",
      "extensions_to_open": ""
   },

I get the default location, versus the desktop. When I change it to this:

   "download": {
      "default_directory": "C:\\Users\\rdub\\Desktop",
      "directory_upgrade": true,
      "extensions_to_open": ""
   },

I get the desktop location.

Try the following:

desired_caps = {'prefs': {'download': {'default_directory': '/Users/thiagomarzagao/Desktop/downloaded_files/', "directory_upgrade": true, "extensions_to_open": ""}}}
Tindall answered 2/8, 2013 at 22:23 Comment(7)
Somehow that's not working for me. I added the "default_directory" and the "extensions_to_open" preferences to that dictionary in my code, but the downloaded files still go to the default folder. I even tried both "true" and True (since I don't know if that's supposed to be a string or a boolean), but neither syntax worked.Dov
Unfortunately, modifying Chrome's Preferences file directly is not an option to me. The thing is, I need to set the download folder on my Python script, not on Chrome's Preferences file. (That's because I'll need to have several different download folders and iterate over them, saving a few hundred downloaded files to each folder).Dov
I was not recommending you hand edit the file, I was just using that method as a quick test bed. Did you try setting directory_upgrade to true? That was the key for me.Tindall
Edited answer with a code sample. One other thought... Does the downloaded_files folder exist on the desktop?Tindall
Thanks for the follow up, R Dub. Alas, I still can't make it work. I've set directory_upgrade to true, but no good (I tried it both as a string - "true" - and as a boolean - True). The downloaded_files folder does exist on the desktop. You mentioned you are using a Windows install, so I wonder if it's some Mac issue. Well, I'll keep trying.Dov
If you have chrome installed on your mac, you could change the download dir through the settings interface and then examine the preferences file for any differences on the mac platform.Tindall
When I change the download folder through Chrome's settings interface the 'Preferences' file is updated correctly (the value associated with the 'default_directory' key changes to the folder I chose). Then when I download anything manually, it goes to that folder. But somehow that doesn't happen when I start Chrome via the webdriver. It's seems as if the webdriver implicitly tells Chrome to use "/Users/thiagomarzagao/Downloads" anyway, regardless of what is in the 'Preferences' file or on my script (which in theory should supersede the corresponding entries on the 'Preferences' file).Dov
N
5

I try all the anwsers in this question, but it doesn't work for my in Ubuntu 16.10. So I add the change with os.environ for the variable XDG_DOWNLOAD_DIR. Which doesn't work, but I think that it helps.

That is:

os.environ['XDG_DOWNLOAD_DIR'] = default_download_directory

The really change that works perfectly for me is setup the download folder via the command xdg-user-dirs-update through a system call in execution time:

os.system("xdg-user-dirs-update --set DOWNLOAD " + default_download_directory)

So, all my code related to setup the download dir is the following:

import os
from selenium import webdriver

default_download_directory = str(os.path.dirname(os.path.abspath(__file__))) + "/download"

os.environ['XDG_DOWNLOAD_DIR'] = default_download_directory

os.system("xdg-user-dirs-update --set DOWNLOAD " + default_download_directory)

desired_caps = {
    'prefs': {
            'download': {
                'default_directory': str(os.path.dirname(os.path.abspath(__file__))) + "/download", 
                "directory_upgrade": "true", 
                "extensions_to_open": ""
                }
              }
        }

options = webdriver.ChromeOptions() 
options.add_argument("download.default_directory=" + str(os.path.dirname(os.path.abspath(__file__))) + "/download")

browser = webdriver.Chrome(chrome_options=options, desired_capabilities=desired_caps)
Nath answered 29/1, 2017 at 12:20 Comment(2)
So your solution is to set it permanently, system-wide on the machine I'm running this? So when any other application, even outside of this script wants a download folder it gets what was last set by this script, correct?Russom
You are right, there is a big problem setting the variable as system-wide (I discover the side effects that you comment some weeks ago). A workaround could be store temporally the older path and restore after finish the app (and really ensure that it is restored the path if the script fails or so). If you have better ideas to avoid that, I would like to know it ;)Nath
E
3

For anybody still wondering why their implementation doesn't work: You have to put the FULL PATH for it to work. e.g. '/Users/you/dlfolder' won't work, while 'C:/Users/you/dlfolder' will.

Edmondo answered 24/2, 2018 at 21:32 Comment(0)
A
2

Pass the variable to "download.default_directory"

Store the dir path in variable and pass the variable to "download.default_directory"

Note: Both .py file and Folder "PDF_Folder" in same location and file should download in Folder "PDF_Folder"

exepath = sys.arg[0]
# get the path from the .py file
Dir_path = os.path.dirname(os.path.abspath(exepath))
# get the path of "PDF_Folder" directory
Download_dir = Dir_path+"\\PDF_Folder\\"

preferences = {"download.default_directory": Download_dir , # pass the variable
                   "download.prompt_for_download": False,
                   "directory_upgrade": True,
                   "safebrowsing.enabled": True }
chrome_options.add_experimental_option("prefs", preferences)
driver = webdriver.Chrome(chrome_options=chrome_options,executable_path=r'/pathTo/chromedriver')
driver.get("urlfiletodownload");
Aleksandrovsk answered 3/9, 2020 at 16:4 Comment(0)
C
1

this seems to work for me

chrome_options = webdriver.ChromeOptions()
settings = {
       "recentDestinations": [{
            "id": "Save as PDF",
            "origin": "local",
            "account": "",
        }],
        "selectedDestinationId": "Save as PDF",
        "version": 2,

    }



prefs = {'savefile.default_directory': '/Users/gregreynders/PycharmProjects/Webscraper'}
chrome_options.add_experimental_option('prefs', prefs)
chrome_options.add_argument('--kiosk-printing')


driver = webdriver.Chrome(chrome_options=chrome_options , executable_path="/Applications/chrome/chromedriver" )
driver.get("https://google.com")
driver.execute_script('window.print();')
driver.quit()
Clipping answered 18/7, 2021 at 20:5 Comment(0)
L
1

This work in 2024 with windows chromedriver 121.0.6167.85

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from time import sleep 

chromeOptions = webdriver.ChromeOptions()
prefs = {"download.default_directory" : r"C:\Users\adm\OneDrive\\"}
chromeOptions.add_experimental_option("prefs", prefs)
browser = webdriver.Chrome(options=chromeOptions)

Headless = False  

browser.get("url")

sleep (2)
Leonie answered 11/2 at 13:41 Comment(0)
D
0

It worked for me using the following code:

options  = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
prefs = {'profile.default_content_settings.popups': 0,
    'download.default_directory' : r'C:\Users\user\folder\\',
    'directory_upgrade': True}
options.add_experimental_option('prefs', prefs)
chromedriver = r"C:\Users\user\folder\chromedrivermanager.exe"

browser = webdriver.Chrome(options=options)

You could try to change the parameters of webdriver.Chrome() as it asks for a single parameter as I did, and it worked.

Delhi answered 10/8, 2023 at 18:34 Comment(0)
U
0
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time

chrome_options = Options()
# chrome_options.add_argument('--headless')  # Add any additional options if needed
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument("--start-maximized")
chrome_options.add_argument("--disable-infobars")
chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument('--disable-dev-shm-usage')
#
chrome_options.add_experimental_option('prefs', {
    'download.default_directory': 'C:\\Users\\61478\\PycharmProjects\\WebScraper\\',
    #'download.default_directory': r'C:\Users\61478\PycharmProjects\WebScraper\\',
    'directory_upgrade': True,
    'download.directory_upgrade': True,
    'safebrowsing.enabled': True
})

# Pass the combined options to the Chrome WebDriver
driver = webdriver.Chrome(chrome_options)
driver.maximize_window()
driver.get('https://fastest.fish/test-files')
time.sleep(1)

# Wait for the download link to be clickable
download_link = driver.find_element(By.XPATH, "(//*[@class=\"table\"]/tbody/tr/td/a)[1]")
download_link.click()

# Let the download complete
time.sleep(10)  # Adjust this wait time as needed

# Close the browser
driver.quit()
#
# Both path worked for me
# Spend some time tweaking this, finally find it.
#
# Chrome browser version: 120.0.6099.71  
# Selenium Version: 4.15.2
Underdog answered 11/12, 2023 at 2:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.