21

I am trying to automatically download files from a pop up dialog using selenium-python.

The firefox popups look like this

enter image description here

I want to simulate clicking "OK"

I found this answer How do I trap a popup in Selenium 2 python which sent me to the docs https://selenium-python.readthedocs.org/en/latest/navigating.html?highlight=popup#popup-dialogs

I've tried this

    alert = driver.switch_to_alert()
    #alert.send_keys(Keys.RETURN) #No alert is present

and this

    alert = driver.switch_to_alert()
    alert.accept()  #no alert is present

If I run pprint.pprint(driver.window_handles) it prints only a single GUID -- showing that only one window is present.

So if no alert is present and there is only one window -- how do I download these files?

Community
  • 1
  • 1
bernie2436
  • 22,841
  • 49
  • 151
  • 244

13 Answers13

17

In python, but this will work in Java as well because the firefox preferences are a javascript:

profile.set_preference("browser.download.panel.shown", False)
profile.set_preference("browser.helperApps.neverAsk.openFile","text/csv,application/vnd.ms-excel")
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/csv,application/vnd.ms-excel")
profile.set_preference("browser.download.folderList", 2);
profile.set_preference("browser.download.dir", "c:\\firefox_downloads\\")
browser = webdriver.WebDriver(firefox_profile=profile)

this works for CSV files, modify it for whatever filetype you are downloading.

Max
  • 199
  • 1
  • 5
  • 1
    What about Chrome? I tried code `options = Options() options.add_argument('--disable-download-notification') self.driver = webdriver.Chrome(chrome_options=options) saveas = ActionChains(self.driver).key_down(Keys.CONTROL).send_keys('s').key_up(Keys.CONTROL) saveas.perform()` but it opened Save As dialog – zubactik Jul 16 '16 at 18:02
  • Refer to to a list of mime types such as this one if you have file types other than CSVs. https://www.iana.org/assignments/media-types/media-types.xhtml – Charlie Haley Apr 24 '19 at 03:56
7

I've discovered a useful solution that hopefully will help somebody out there.

You can skip the prompt altogether with firefox if you're starting the download with a click by holding the ALT key.

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
...
profile.set_preference("browser.altClickSave", True)
...
element = driver.find_element_by_xpath("//a")
ActionChains(driver).key_down(Keys.ALT).click(element).key_up(Keys.ALT).perform()

This should download any file without needing to specify MIME type of anything.

Zei
  • 409
  • 5
  • 14
  • where dose it save the file? – sangharsh Jul 28 '20 at 04:04
  • Perhaps this only works on hyperlinks to actual files, but I can't get this to work on buttons that trigger the download a different way yet produce the same dialog. Say, same code as above, but with `element = driver.find_element_by_id('download_pdf_data-button')`. Dialog will still show up. – Mast Nov 10 '20 at 19:39
  • 1
    it worked like a magic for me – nitin May 19 '22 at 22:25
  • 1
    @Mast bit of a late reply but this is correct. If the button triggers javascript to start the download instead of directly linking to the file, it will not work. This solution only works for direct links because that's just how browsers work. The alt click doesn't extend to javascript events. – Zei May 30 '22 at 04:39
  • 1
    Wow, this even works in Safari! – borislubimov Jun 08 '23 at 21:48
6

Based on Amey's answer 1) and of course Yi Zeng's blog (in ruby) quoting Selenium itself doesn’t interact with system-level dialogs like this as well as the documentation, here is the python snippet to resolve the issue

from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

profile = FirefoxProfile()
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", 'application/pdf')
driver = webdriver.Firefox(firefox_profile=profile)

driver.get(target_url)
#specific to target_url
driver.find_element_by_css_selector('a[title="Click to Download"]').click()
SYK
  • 644
  • 6
  • 17
3

I spent some time today trying to figure this out (again... had the solution at home but couldn't get to it...) and during that I found this... None of the solutions helped me so I thought I'd offer up what I did to solve this problem.

from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

dl_path = "/tmp/"
profile = FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.manager.showWhenStarting", false)
profile.set_preference("browser.download.dir", dl_path)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk",
                          "text/plain,text/x-csv,text/csv,application/vnd.ms-excel,application/csv,application/x-csv,text/csv,text/comma-separated-values,text/x-comma-separated-values,text/tab-separated-values,application/pdf")
Matt Camp
  • 1,448
  • 3
  • 17
  • 38
2

You have two options :

1) Create a custom firefox profile with settings where the download location is pre-decided and firefox does not ask for confirmation to download. Just googled and found a blog that explains how to do it

2) Use sikuli to automate clicks on the download dialog box. Blog explaining- How to use Sikuli

P.S. - Not read the blogs, but I am sure they will give u a clue.

Amey
  • 8,470
  • 9
  • 44
  • 63
2

With my using and test in my Selenium UI automation test, configuring the Firefox Profile is more stable than Robot Class. E.g. Disable popping up the System non-webpage Download/Save Dialog.

FirefoxProfile prof = new FirefoxProfile();

ffprofile.setPreference("browser.download.panel.shown", false);
ffprofile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/zip");

//ffprofile.setPreference("browser.download.folderList", 1);  // Default to /home/user/Downloads in Linux.
ffprofile.setPreference("browser.download.folderList", 2); 
ffprofile.setPreference("browser.download.dir", "/tmp");
Yang
  • 51
  • 6
1
FirefoxProfile fxProfile = new FirefoxProfile();
 fxProfile.SetPreference("browser.download.panel.shown", false);
 fxProfile.SetPreference("browser.helperApps.neverAsk.openFile", "text/csv,application/vnd.ms-excel");
 fxProfile.SetPreference("browser.helperApps.neverAsk.saveToDisk", "text/csv,application/vnd.ms-excel");
 fxProfile.SetPreference("browser.download.folderList", 2); 
 fxProfile.SetPreference("browser.download.dir", "c:\\mydownloads");
 IwebDriver driver = new FirefoxDriver(fxProfile);
0

Most browsers (in mine case Firefox) select the OK button by default. So I managed to solve this by using the following code. It basically presses enter for you and the file is downloaded.

Robot robot = new Robot();

// A short pause, just to be sure that OK is selected
Thread.sleep(3000);

robot.keyPress(KeyEvent.VK_ENTER);
shish
  • 893
  • 1
  • 12
  • 20
0

public class DemoFileDownload{

FirefoxProfile prof = new FirefoxProfile(); prof.setpreference("browser.helperApps.neverAsk.SaveToDisk", "mimetype_of_file"); prof.setpreference("browser.download.folderlist",int_value); prof.setpreference("browser.download.dir,"folder_path"); // if the above int_value is 2 //int_value can be of below values: // 1 - downloads folder // 0 - desktop // 2 - custom folder } get the mime type from below website: www.sitepoint.com/mimetypes-complete-list/

for chrome browser, use chromeoptions instead of firefoxprofile

0

The above solutions are great. But unfortunately my target file to download is a rare file type not in iana.org/assignments/media-types/media-types.xhtml. My solution is:

  1. Click on the download link in Firefox. Choose "Save File" and "Do this automatically for files like this from now on". This will create a a new "content type" in the Firefox profile when handling download.

  2. Locate and copy your Firefox profile (https://support.mozilla.org/en-US/kb/back-and-restore-information-firefox-profiles). Named the profile folder as "prepared_firefox_profile".

  3. Read in the custom profile:
profile = FirefoxProfile("dir/to/your/firefox/profile/prepared_firefox_profile")
profile.set_preference("browser.download.dir", "/your/desired/download/folder")  
driver = selenium.webdriver.Firefox(firefox_profile=profile)
0

After the first time tick the little box of "Do this automatically for files like this from now on.", it doesn't pop up again.

enter image description here

Mark K
  • 8,767
  • 14
  • 58
  • 118
0

I got PDF download working with the following handlers.json and user.js preferences:

{
    "defaultHandlersVersion": {},
    "mimeTypes": {
        "application/pdf": {
            "action": 0,
            "extensions": [
                "pdf"
            ]
        }
    }
}
//
user_pref("browser.download.folderList", 2);
user_pref("browser.download.manager.showWhenStarting", false);
user_pref("browser.download.dir", "/absolute/path/to/target/folder");
user_pref("browser.helperApps.alwaysAsk.force", false);
user_pref("browser.download.manager.alertOnEXEOpen", false);
user_pref("browser.download.manager.focusWhenStarting", false);
user_pref("browser.download.manager.useWindow", false);
user_pref("browser.download.manager.showAlertOnComplete", false);
user_pref("browser.download.manager.closeWhenDone", false);

user_pref("browser.download.viewableInternally.previousHandler.alwaysAskBeforeHandling.pdf", false);
user_pref("browser.download.viewableInternally.previousHandler.preferredAction.pdf", 0);

user_pref("pdfjs.migrationVersion", 2);
ciis0
  • 311
  • 1
  • 9
0

You can possibly have this firefox profile, In Python you could this :

profile = FirefoxProfile()
profile.set_preference("browser.download.panel.shown", False)
profile.set_preference("browser.helperApps.neverAsk.openFile","text/csv,application/vnd.ms-excel")
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/msword, application/csv, application/ris, text/csv, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream");
profile.set_preference("browser.download.manager.showWhenStarting", False);
profile.set_preference("browser.download.manager.alertOnEXEOpen", False);
profile.set_preference("browser.download.manager.focusWhenStarting", False);
profile.set_preference("browser.download.folderList", 2);
profile.set_preference("browser.download.useDownloadDir", True);
profile.set_preference("browser.helperApps.alwaysAsk.force", False);
profile.set_preference("browser.download.manager.alertOnEXEOpen", False);
profile.set_preference("browser.download.manager.closeWhenDone", True);
profile.set_preference("browser.download.manager.showAlertOnComplete", False);
profile.set_preference("browser.download.manager.useWindow", False);
profile.set_preference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", False);
profile.set_preference("pdfjs.disabled", True);
profile.set_preference("browser.download.dir", "C:\\Users\\***\\****\\Desktop\\Automation")
driver = webdriver.Firefox(firefox_profile = profile, executable_path = "Full file path to gecko driver.exe")
cruisepandey
  • 28,520
  • 6
  • 20
  • 38