54

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)

Jareq
  • 31
  • 1
  • 7
Parzival
  • 2,004
  • 4
  • 33
  • 47

9 Answers9

91

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

Abraham
  • 8,525
  • 5
  • 47
  • 53
MervS
  • 5,724
  • 3
  • 23
  • 37
  • 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. – Parzival Sep 27 '13 at 01:16
  • 1
    Alas, I just tested it and it didn't work for me. The code doesn't crash, it just silently downloads nothing. – Parzival Nov 14 '13 at 03:10
  • A virtually identical version of this works for me where I omit the `executable_path=chromedriver,` argument to the `Chrome` call. – jbryanscott Feb 14 '17 at 19:28
  • 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. – Kenny Sep 08 '19 at 23:21
  • 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. – MervS Sep 10 '19 at 02:16
  • 2
    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. – Kenny Sep 15 '19 at 22:07
  • 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. – ggrant Oct 29 '19 at 18:22
42

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)
yvesva
  • 711
  • 7
  • 10
  • 5
    You are a rock star. This ought to be the best answer – Prayson W. Daniel Nov 12 '17 at 08:49
  • @yvesva What is the purpose of adding the double dashes -- before "start-maximised"? – doyz Jan 03 '18 at 04:37
  • @doyz Just standard nomenclature I think. This seems to be a complete list of them. https://peter.sh/experiments/chromium-command-line-switches/ – yvesva Jan 03 '18 at 05:15
  • 2
    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, @yvesva :) – natka_m Aug 30 '19 at 13:45
  • 2
    Hmmm. Sad that it's 2020 and still adding slashes to the downloads path to make our code work. – Abhi Jan 03 '20 at 13:49
  • Hi Is there someway i can implement the same in IE? – anandhu Jan 30 '20 at 11:02
  • Inputting the download directory as per this answer seems to be the solution to the issue with trying to deploy the currently selected answer. – agftrading Oct 02 '20 at 12:33
  • does this not work without `--start-maximized` option added? – manas Oct 18 '20 at 13:25
  • 1
    @manas `--start-maximized` is not necessary for the download path to work – yvesva Oct 19 '20 at 02:28
9
# -*- 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()
Mhadhbi issam
  • 197
  • 3
  • 6
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": ""}}}
R Dub
  • 678
  • 6
  • 23
  • 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. – Parzival Aug 02 '13 at 23:56
  • 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). – Parzival Aug 02 '13 at 23:56
  • 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. – R Dub Aug 03 '13 at 14:11
  • Edited answer with a code sample. One other thought... Does the downloaded_files folder exist on the desktop? – R Dub Aug 03 '13 at 14:16
  • 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. – Parzival Aug 03 '13 at 15:34
  • 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. – R Dub Aug 03 '13 at 17:11
  • 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). – Parzival Aug 03 '13 at 18:01
4

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)
rescdsk
  • 8,739
  • 4
  • 36
  • 32
shakaran
  • 10,612
  • 2
  • 29
  • 46
  • 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? – Martin Thoma Aug 17 '17 at 19:06
  • 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 ;) – shakaran Aug 21 '17 at 10:53
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.

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");
Naresh Kumar
  • 449
  • 4
  • 5
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()
Greg W.F.R
  • 544
  • 1
  • 5
  • 13
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.