如何使用selenium-python从弹出对话框中自动下载文件

时间:2014-07-20 16:47:41

标签: python selenium

我正在尝试使用selenium-python从弹出对话框中自动下载文件。

firefox弹出窗口看起来像这样

enter image description here

我想模拟点击"确定"

我找到了这个答案How do I trap a popup in Selenium 2 python,它将我发送到了文档https://selenium-python.readthedocs.org/en/latest/navigating.html?highlight=popup#popup-dialogs

我试过这个

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

和这个

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

如果我运行pprint.pprint(driver.window_handles),它只打印一个GUID - 显示只有一个窗口存在。

因此,如果没有警报且只有一个窗口 - 我该如何下载这些文件?

12 个答案:

答案 0 :(得分:10)

在python中,但这也适用于Java,因为firefox首选项是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)

适用于CSV文件,可根据您要下载的任何文件类型进行修改。

答案 1 :(得分:5)

根据Amey的回答1),当然Yi Zeng's blog (in ruby)引用Selenium本身不会与像这样的系统级对话框以及documentation进行交互,这里是python代码段解决问题

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()

答案 2 :(得分:3)

我发现了一个有用的解决方案,希望可以对那里的人有所帮助。

如果按住ALT键单击即可开始下载,则可以完全跳过提示与firefox。

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()

这应该下载任何文件,而无需指定任何MIME类型。

答案 3 :(得分:2)

您有两种选择:

1)使用预先确定下载位置的设置创建自定义firefox配置文件,firefox不要求确认下载。 只需用Google搜索,然后找到一个解释如何操作的blog

2)使用sikuli自动点击下载对话框。 Blog解释 - 如何使用Sikuli

P.S。 - 不读博客,但我相信他们会给你一个线索。

答案 4 :(得分:2)

通过我在Selenium UI自动化测试中的使用和测试,配置Firefox Profile比Robot Class更稳定。例如。禁用弹出系统非网页下载/保存对话框。

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");

答案 5 :(得分: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);

答案 6 :(得分:1)

我今天花了一些时间试图解决这个问题(再次……在家中有解决方案,但无法解决...),在此期间,我发现了这一点……没有一种解决方案对我有帮助我以为我愿意为解决这个问题做些什么。

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")

答案 7 :(得分:0)

大多数浏览器(在我的情况下为Firefox)默认选择“确定”按钮。所以我设法通过使用以下代码解决了这个问题。它基本上按下输入并下载文件。

calendarView = (CalendarView) findViewById(R.id.calendarView1);

        calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
            @Override
            public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {
                String yearFormat = "", monthFormat = "", dayFormat = "";
                // El mes empieza en 0, así que aumentamos en uno para que cada mes coincida
                // con su número correspondiente: enero -> 1, febrero -> 2, etc...
                month += 1;
                if (month < 10) {
                    monthFormat = String.format("%02d", month);
                } else {
                    monthFormat = Integer.toString(month);
                }
                if (dayOfMonth < 10) {
                    dayFormat = String.format("%02d", dayOfMonth);
                } else {
                    dayFormat = Integer.toString(dayOfMonth);
                }
                yearFormat = Integer.toString(year);
                // Calculamos el día de la semana para mostrarlo en el Dialog
                Calendar selected = Calendar.getInstance();
                selected.setTimeInMillis(view.getDate());
                int dayOfWeek = selected.get(Calendar.DAY_OF_WEEK);
                HoursDialog hoursDialog = new HoursDialog(CalendarActivity.this,
                        yearFormat, monthFormat, dayFormat, dayOfWeek);
                hoursDialog.show();
            }
        });
    GregorianCalendar cal = new GregorianCalendar();
    GregorianCalendar cal2 = new GregorianCalendar(); // Hoy

    int daysBefore = daysEnabled * -1;

    cal.add(GregorianCalendar.DATE, daysBefore);

    calendarView.setMinDate(cal.getTime().getTime());
    calendarView.setMaxDate(cal2.getTime().getTime());

答案 8 :(得分:0)

公共类DemoFileDownload {

FirefoxProfile prof =新的FirefoxProfile();  prof.setpreference(“ browser.helperApps.neverAsk.SaveToDisk”,“ mimetype_of_file”);  prof.setpreference(“ browser.download.folderlist”,int_value);  prof.setpreference(“ browser.download.dir,” folder_path“); //如果上述int_value为2  // int_value可以具有以下值:  // 1-下载文件夹  // 0-桌面  // 2-自定义文件夹 } 从以下网站获取MIME类型: www.sitepoint.com/mimetypes-complete-list /

对于chrome浏览器,请使用chromeoptions代替firefoxprofile

答案 9 :(得分:0)

上述解决方案很棒。但是很遗憾,我要下载的目标文件是一种罕见的文件类型,该文件类型不在iana.org/assignments/media-types/media-types.xhtml中。 我的解决方案是:

  1. 单击Firefox中的下载链接。选择“保存文件”和“从现在开始自动对此类文件执行此操作”。处理下载时,这将在Firefox配置文件中创建一个新的“内容类型”。

  2. 找到并复制您的Firefox配置文件(https://support.mozilla.org/en-US/kb/back-and-restore-information-firefox-profiles)。将配置文件文件夹命名为“ prepared_firefox_profile”。

  3. 阅读自定义配置文件:
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)

答案 10 :(得分:0)

第一次勾选“从现在开始自动对此类文件执行此操作”小框后,它不会再次弹出。

enter image description here

答案 11 :(得分:0)

我使用以下 handlers.jsonuser.js 首选项下载 PDF:

{
    "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);