使用 Selenium WebDriver for Firefox 下载 pdf

Posted

技术标签:

【中文标题】使用 Selenium WebDriver for Firefox 下载 pdf【英文标题】:Downloading pdf with Selenium WebDriver for Firefox 【发布时间】:2018-03-08 05:44:56 【问题描述】:

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

我尝试通过元素的 id which = "download":

(new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("download")));
driver.findElement(By.id("download")).click(); 

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

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

【问题讨论】:

【参考方案1】:

正如你所说,

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

你需要使用驱动对象的switchTo()方法来处理不同窗口之间的切换。

下面的代码对我来说工作正常,没有问题,我可以点击下载图标。

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


【讨论】:

我了解到,在您的情况下,您必须先switch() 到弹出式浏览器,然后单击 Firefox 浏览器中的下载图标。即使在完成该 PDF 之后也不会立即下载。您必须进行一些设置,以帮助您直接下载 PDF。 @zsbappa 提到了这些设置。 你的问题是,Selenium 抛出异常,因为找不到元素。实际上在查找元素方面没有挑战,但是您还没有切换到打开您的机密文档的弹出窗口。 对不起,我意识到时删除了我的评论。您的回答解决了我的问题,谢谢!我创建了一个机器人 (java.awt) 在它询问我是要保存还是打开文件后点击 OK 按钮,但它的作用就像魅力一样。必须确保 switchTo.defaultContent() 之后也是如此。我认为我不必通过更改首选项“browser.helperApps.neverAsk.saveToDisk”来创建机器人。 很高兴它帮助了你:-)【参考方案2】:

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

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

【讨论】:

不幸的是,它无法按照您的建议直接找到元素。原因是它没有找到“下载”元素(通过 id 或 xpath),因为它位于 iframe 中。完成后,我必须先 driver.switchTo().frame("nameOfMyFrame") 和 driver.switchTo().defaultContent()。所以这个 findElement 策略不适用于我的情况。虽然机器人的东西很好用,谢谢!【参考方案3】:

我们可以使用 Firefox 浏览器设置和使用 WebDriver 的 Firefox Profile 设置来处理 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 文件,并且不会显示“下载”弹出窗口。

【讨论】:

对于第 1 步,我试图在 java 代码中自动实现这一点,而不是手动实现。这可能吗?我的research 说您应该可以使用“browser.helperApps.neverAsk.saveToDisk”setPreference 方法调用来更改它,但这似乎不起作用。 抱歉,您设置的首选项设置为您发布的方式,我什至无法让 pdf 查看器加载 pdf。我确定了对我来说破坏它的特定行,即 ("pdfjs.disabled","true")。这是使用 [driver.get("pdf995.com/samples/pdf.pdf")] 页面 经过更多测试后,我明白您现在的意图。您发布的这两行是我使用的。 profile.setPreference("pdfjs.disabled", true); profile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/pdf")。第一个禁用了 pdf 查看器(如您所愿),第二个禁用了提示。无需单击元素,我就可以下载 pdf。我不知道如何让它与我的 iframe 问题一起使用,但是使用直接的 pdf URL 非常感谢!【参考方案4】:

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

IWebElement element = Driver.FindElement(By.Id("download"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)Driver;
executor.ExecuteScript("arguments[0].click();", element);

【讨论】:

以上是关于使用 Selenium WebDriver for Firefox 下载 pdf的主要内容,如果未能解决你的问题,请参考以下文章

使用 Selenium WebDriver for Firefox 下载 pdf

如何使用“--auto-open-devtools-for-tabs”在 selenium webdriver 中从元素选项卡切换到网络选项卡?

webdriver-键盘操作 for java

Windows phone webdriver (selenium community)/ Nunit silverlight windows for Windows phone 单元测试框架?

如何使用 java 绑定并行化 selenium webdriver 的实例?

Selenium WebDriver: Java: Mac OS X: how control file upload automation for CuteWebUI_Uploader_Resour