【问题标题】:Downloading pdf with Selenium WebDriver for Firefox使用 Selenium WebDriver for Firefox 下载 pdf
【发布时间】: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() 答案修复。

【问题讨论】:

    标签: java selenium pdf firefox


    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 2017-03-09
      • 1970-01-01
      • 2020-08-04
      • 2018-05-17
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      相关资源
      最近更新 更多