Java 使用Selenium WebDriver for Firefox下载pdf

Java 使用Selenium WebDriver for Firefox下载pdf,java,selenium,pdf,firefox,Java,Selenium,Pdf,Firefox,我正在尝试将一个.pdf下载到本地,这样我就可以使用ApachePDFBox读取其中的文本,并将其作为测试套件的一部分进行验证。我已经找到了一些通过点击URL从Firefox下载pdf的代码。这对我不起作用,因为我正在使用的pdf是一个机密文档,所以它不会通过URL公开,而是作为弹出窗口加载到pdf查看器中。在我将PDF查看器加载到浏览器中后,有人知道如何在Firefox PDF查看器中点击下载按钮吗 我尝试通过元素的id=“下载”来查找它: 不幸的是,这不起作用,因为它说它找不到元素。有人知

我正在尝试将一个.pdf下载到本地,这样我就可以使用ApachePDFBox读取其中的文本,并将其作为测试套件的一部分进行验证。我已经找到了一些通过点击URL从Firefox下载pdf的代码。这对我不起作用,因为我正在使用的pdf是一个机密文档,所以它不会通过URL公开,而是作为弹出窗口加载到pdf查看器中。在我将PDF查看器加载到浏览器中后,有人知道如何在Firefox PDF查看器中点击下载按钮吗

我尝试通过元素的id=“下载”来查找它:

不幸的是,这不起作用,因为它说它找不到元素。有人知道解决办法吗

更新:我描述的弹出窗口是一个iframe元素。这导致无法找到“下载”元素。已修复@4M01的switchTo()答案。

如您所述

而是作为弹出窗口加载到PDF查看器中

您需要使用driver对象的方法处理不同窗口之间的切换

下面的代码对我来说运行良好,没有问题,我可以点击下载图标

public class FirefoxPDFTest {
      WebDriver driver;

    @BeforeClass
    void Setup(){
        System.setProperty("webdriver.gecko.driver", "C:\\Automation\\Selenium\\drivers\\geckodriver.exe");
        driver = new FirefoxDriver();
        driver.manage().window().maximize();
    }

    @Test
    void downloadPDF(){
        driver.get("http://www.pdf995.com/samples/pdf.pdf");
        waitTillPageLoad();
        driver.findElement(By.id("download")).click();
    }



    private void waitTillPageLoad(){
        new WebDriverWait(driver, 30).until(driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
    }


    @AfterClass
    void tearDown(){
        driver.close();
        driver.quit();
    }

}

只需使用以下代码单击下载按钮:

    driver.findElement(By.xpath("//button[@id='download']")).click();

    Thread.sleep(8000);

    Robot robot = new Robot();

    robot.keyPress(KeyEvent.VK_ENTER);
    robot.keyRelease(KeyEvent.VK_ENTER);

我们可以使用Firefox浏览器设置处理Firefox浏览器中的下载弹出窗口,使用WebDriver处理Firefox配置文件设置

步骤1:在Firefox浏览器中更新设置。

打开Firefox浏览器并导航到工具->选项 导航到应用程序。 将PDF的操作类型设置为“保存文件”

步骤2:使用FirefoxProfile初始化FireFoxDriver

File downloadsDir = new File("");

// Set Preferences for FirefoxProfile.
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", downloadsDir.getAbsolutePath());
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("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.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.manager.focusWhenStarting", false);
profile.setPreference("browser.download.useDownloadDir", true);
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.download.manager.closeWhenDone", true);
profile.setPreference("browser.download.manager.showAlertOnComplete", false);
profile.setPreference("browser.download.manager.useWindow", false);
profile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
profile.setPreference("pdfjs.disabled", true);

// Initialize the FireFoxDriver instance.
FirefoxDriver webDriver = new FirefoxDriver(profile);
步骤3:执行脚本

执行单击下载PDF图标的脚本


结果:将下载PDF文件,并且不会显示下载弹出窗口。

您可以使用以下(C#)代码处理下载图标(使用Firefox):


我明白,在您的情况下,您必须先
切换()
到弹出式浏览器,然后单击Firefox浏览器中的下载图标。即使这样做了,PDF也无法立即下载。您必须进行一些设置,以帮助您直接下载PDF。@zsbapa提到了这些设置。您的问题是,Selenium抛出了一个异常,因为找不到元素。事实上,在查找元素方面并没有什么困难,但您并没有切换到打开机密文档的弹出窗口。很抱歉,当我意识到这一点时,我删除了我的评论。你的回答解决了我的问题谢谢!我创建了一个Robot(java.awt),当它询问我是否要保存或打开文件时,我按下OK按钮,但它的工作方式很有魅力。还必须确保在之后切换到.defaultContent()。我认为我不必通过更改首选项“browser.helperApps.neverAsk.saveToDisk”来创建机器人。很高兴它帮助了您:-)不幸的是,它无法按照您的建议直接找到删除。原因是它找不到“download”元素(通过id或xpath),因为它在iframe中。在我完成之后,我必须先创建driver.switchTo().frame(“nameOfMyFrame”),然后创建driver.switchTo().defaultContent()。所以这个findElement策略不适合我的情况。虽然机器人的东西很好用,谢谢!对于步骤1,我试图在java代码中自动实现这一点,而不是手动实现。这可能吗?我的建议是,您应该能够通过“browser.helperApps.neverAsk.saveToDisk”setPreference方法调用更改此设置,但这似乎不起作用。很抱歉,按照您发布的方式设置了首选项,我甚至无法让pdf查看器加载pdf。我确定了为我打断它的特定行(“pdfjs.disabled”、“true”)。这是在使用[driver.get(“页面经过一些测试,我现在明白了您的意图。您发布的这两行内容就是我使用的。profile.setPreference(“pdfjs.disabled”,true);profile.setPreference(“browser.helperApps.neverAsk.saveToDisk”,“application/pdf”)。第一行禁用了pdf查看器(与您的意图相同),第二个禁用了提示。没有单击任何元素,我就可以下载pdf。我不知道如何让它与我的iframe问题一起工作,但是使用一个直接的pdf URL,这非常有效,谢谢!
File downloadsDir = new File("");

// Set Preferences for FirefoxProfile.
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", downloadsDir.getAbsolutePath());
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("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.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.manager.focusWhenStarting", false);
profile.setPreference("browser.download.useDownloadDir", true);
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.download.manager.closeWhenDone", true);
profile.setPreference("browser.download.manager.showAlertOnComplete", false);
profile.setPreference("browser.download.manager.useWindow", false);
profile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
profile.setPreference("pdfjs.disabled", true);

// Initialize the FireFoxDriver instance.
FirefoxDriver webDriver = new FirefoxDriver(profile);
IWebElement element = Driver.FindElement(By.Id("download"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)Driver;
executor.ExecuteScript("arguments[0].click();", element);