使用 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 中从元素选项卡切换到网络选项卡?
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