使用Selenium和Java设置Firefox配置文件自动下载文件

34
我想使用Selenium WebDriver和Java来验证文件下载。要下载的文件是PDF格式。当WebDriver在AUT中单击“下载”链接时,Firefox会打开以下下载确认窗口: Download Confirmation Window 我希望Firefox能够自动下载文件,而不显示上面的确认窗口,因此我使用了以下代码:
FirefoxProfile firefoxProfile=new FirefoxProfile();
firefoxProfile.setPreference("browser.download.folderList",2);
firefoxProfile.setPreference("browser.download.manager.showWhenStarting",false);
firefoxProfile.setPreference("browser.download.dir",downloadPath);
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/pdf");
WebDriver driver=new FirefoxDriver(firefoxProfile); 

但是Firefox仍然显示相同的窗口。我该如何设置Firefox配置文件,使得PDF文件能够自动下载而无需显示确认对话框?


6
响应的mime-type是什么?试试这个:firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/pdf,application/x-pdf,application/octet-stream"); - JRodDynamite
JRodDynamite是正确的,你需要把它们都放在一行上,否则它只会取最后一个。 - user890332
8个回答

62

就像 @Jason 建议的那样,很可能是另一种 MIME 类型。

  • 打开开发者工具
  • 进入网络选项卡
  • 点击下载 PDF 的链接
  • 在网络面板中,选择第一个请求
  • MIME 类型是来自响应头的 Content-Type:

输入图片描述

然后使用 Firefox 下载 PDF:

FirefoxOptions options = new FirefoxOptions();
options.setPreference("browser.download.folderList", 2);
options.setPreference("browser.download.dir", "C:\\Windows\\temp");
options.setPreference("browser.download.useDownloadDir", true);
options.setPreference("browser.download.viewableInternally.enabledTypes", "");
options.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf;text/plain;application/text;text/xml;application/xml");
options.setPreference("pdfjs.disabled", true);  // disable the built-in PDF viewer

WebDriver driver = new FirefoxDriver(options);
driver.get("https://www.mozilla.org/en-US/foundation/documents");
driver.findElement(By.linkText("IRS Form 872-C")).click();

MIME类型为application/pdf。我可以在开发者选项卡控制台中看到一条消息:“资源被解释为文档,但传输的MIME类型为application/pdf”。这条消息与@Jason的问题有关吗? - stackoverflow
1
我已经更新了答案,并提供了一个示例,其中禁用了内置查看器。如果对您有用,请告诉我。 - Florent B.
2
我不得不使用此答案中列出的所有选项以及一个额外的选项:profile.setPreference("browser.download.useDownloadDir", true); - bparry
5
现在FirefoxDriver(profile)已被标记为过时。可以使用以下替代方法:FirefoxOptions options = new FirefoxOptions(); options.setProfile(profile); WebDriver driver = new FirefoxDriver(options); - ptstone
2
自Firefox 81版本开始,您还需要清除偏好设置browser.download.viewableInternally.enabledTypes。否则,不在该列表中的文件类型将无法在没有用户交互的情况下下载。 - blaz
显示剩余6条评论

8
目前Firefox 57.0b13的工作方式是:
FirefoxProfile profile = new FirefoxProfile();
// profile.setPreference("browser.download.useDownloadDir", true); This is true by default. Add it if it's not working without it.

profile.setPreference("browser.download.folderList",2); //Use for the default download directory the last folder specified for a download
profile.setPreference("browser.download.dir", "/Path/to/directory"); //Set the last directory used for saving a file from the "What should (browser) do with this file?" dialog.
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf"); //list of MIME types to save to disk without asking what to use to open the file
profile.setPreference("pdfjs.disabled", true);  // disable the built-in PDF viewer

firefoxOptions.setProfile(profile);

关于每个Firefox配置文件设置的详细信息。


3
如果在SPA环境中遇到此问题,则我遇到了一个问题,即将saveToDisk偏好设置为预期的内容类型无效(在我的情况下是text/csv)。
原因是SPA UI发起HTTP调用以获取CSV数据。然后它会使用技巧创建一个<A>元素,然后单击该元素以启动下载到本地计算机。该技巧创建了一个包含CSV数据的Blob对象,并且其类型必须设置为application/octet-stream。因此,saveToDisk也必须设置为application/octet-stream才能正常工作。

3
我确定你的意思是"application/octet-stream"而不是"octet/stream"。 - tonysepia

3

现在是2020年。按照@Florent B.上面提到的方式查找MIME类型。 对于我来说,下载CSV文件并发现Content-Type为"application/octet-stream"。

要下载到Downloads文件夹:

FirefoxOptions options = new FirefoxOptions();
options.addPreference("browser.download.folderList",1);
options.addPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream");
WebDriver driver = new FirefoxDriver(options);

要下载到桌面,请将第二行中的值更改为0:

FirefoxOptions options = new FirefoxOptions();
options.addPreference("browser.download.folderList",0);
options.addPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream");
WebDriver driver = new FirefoxDriver(options);

将文件下载到其他文件夹中:

FirefoxOptions options = new FirefoxOptions();
options.addPreference("browser.download.dir", "D:\\Test");
options.addPreference("browser.download.folderList",2);
options.addPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream");
WebDriver driver = new FirefoxDriver(options);

是的!谢谢你!当我尝试下载一些zip文件时,我使用了“application/zip”,但服务器没有发送该mimetype。我将其更改为“application/octet-stream”(即通用mimetype),然后它就起作用了! - farenorth

2
我会把这个写成评论,但我没有足够的声望点——一旦 selenium webdriver 启动,你可以导航到 about:config 并搜索 browser.helperApps.neverAsk.saveToDisk 来确认你特定的类型被正确记录。在我的情况下,问题也得到了解决,包括最初的回答。
prof.set_preference("browser.helperApps.neverAsk.openFile", "application/pdf, application/octet-stream, application/x-winzip, application/x-pdf, application/x-gzip")

1

如果你和我一样,正在寻找其他文件类型或多种类型的解决方案。请确保只设置neverAsk偏好一次。

opts.set_preference('browser.download.folderList', 2)
opts.set_preference('browser.download.manager.showWhenStarting', False)   opts.set_preference('browser.download.dir', str(download_directory))    opts.set_preference('browser.download.useDownloadDir', True)

# important part!
opts.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip')

我很乐意更新这篇文章,如果有人知道如何包含多个MIME类型!其他快速参考的MIME类型:
# CSV mimetype = 'text/csv'
# TXT mimetype = 'text/txt'
# EXCEL mimetype = 'application/vnd.ms-excel'

1
这是/曾经是对我来说的答案。永远不要问一遍又一遍的偏好,如果我能够重新获得那些时间就好了。 - grantiago

0
    WebDriver driver;
//For firefox
    FirefoxOptions options = new FirefoxOptions(); //For setting up options for Firefox
    DesiredCapabilities firefoxDesiredCapabilities = new DesiredCapabilities(); //Initializing desired capabilities
    options.addPreference("browser.download.folderList", 2); //Last downloaded folder
    options.addPreference("browser.download.dir", "[path]"); // Set your default download directory's path
    options.addPreference("browser.privatebrowsing.autostart", true); 
    options.addPreference("browser.helperApps.neverAsk.saveToDisk", "text/plain; charset=utf-8; text/csv;application/json;charset=utf-8;application/pdf;text/plain;application/text;text/xml;application/xml"); //includes a varied list of context-type but feel free to add others
    options.addPreference("pdfjs.disabled", true);
    options.addArguments("-private");//for incognito
    firefoxDesiredCapabilities.setCapability("moz:firefoxOptions",options); //Load all options to desired capabilities
    driver = new FirefoxDriver(firefoxDesiredCapabilities); //launch your driver using desiredcapalities

//对于Chrome浏览器

ChromeOptions options = new ChromeOptions();
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("profile.default_content_settings.popups", 0);//Don't display any popup for download
prefs.put("download.default_directory", "[path]");//Default download directory
options.setExperimentalOption("prefs", prefs);
options.addArguments("--incognito");
DesiredCapabilities desiredCapabilities = DesiredCapabilities.chrome();
desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options);
desiredCapabilities.setCapability("applicationCacheEnabled", false);
driver = new ChromeDriver(desiredCapabilities);

0

根据JRoddynamite的回答:

opts.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip,text/csv,text/txt')

对于多个MIME类型,这应该能起作用-在这种情况下仅适用于zip、csv和txt文件。

就我个人而言(也是我现在在这个页面上的原因),我发现“只保存#$&*!”选项不是“未知” - 即“application / octet-stream”文件类型的默认选项令人困惑。哦,好吧,这就是生活! :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接