【问题标题】:How to download file using headless (gui-less) Selenium WebDriver如何使用无头(无gui)Selenium WebDriver下载文件
【发布时间】:2017-12-29 11:20:20
【问题描述】:

我需要使用 Java 中的无头 Web 浏览器下载文件。我检查了HtmlUnit,在一些简单的情况下我可以下载文件,但是当Ajax初始化下载时我无法下载(实际上它更复杂,因为有两个请求,第一个下载第二个请求实际下载文件的URL从给定的 URL)。我已经用 Selenium 替换了 HtmlUnit。我已经检查了两个 WebDriver,HtmlUnitDriver 和 ChromeDriver。

  • HtmlUnitDriver - 类似 HtmlUnit 的行为
  • ChromeDriver - 我可以在可见模式下下载文件,但是当我打开无头模式时,不再下载文件

    ChromeOptions lChromeOptions = new ChromeOptions();
    HashMap<String, Object> lChromePrefs = new HashMap<String, Object>();
    lChromePrefs.put("profile.default_content_settings.popups", 0);
    lChromePrefs.put("download.default_directory", _PATH_TO_DOWNLOAD_DIR);
    lChromeOptions.setExperimentalOption("prefs", lChromePrefs);
    lChromeOptions.addArguments("--headless");
    
    return new ChromeDriver(lChromeOptions);
    

我知道出于安全原因,以无头模式下载文件已关闭,但必须有一些解决方法


我之前使用过 2.28 httpunit,几分钟前我开始使用 2.29,但 Ajax 功能似乎在某处停止。这是我点击后检索数据并期望文件数据的方式:_link.click().getWebResponse().getContentAsStream()

WebConnectionWrapper 是否显示网站上的所有请求/响应?你知道我怎样才能调试它以获得更好的洞察力吗?我看到单击链接后 Ajax 函数的第一部分被正确调用(此函数中有 2 个 http 请求)。在WebConnectionWrapper -&gt; getResponse 中获取第一个响应后,我什至尝试创建我的自定义 http 请求以检索数据/文件,但它返回 404 错误,这表明第二个请求已以某种方式完成,但我在 @ 中也没有看到任何日志/调试信息987654323@也不是WebConnectionWrapper -&gt; getResponse()

【问题讨论】:

  • HtmlUnit 在这里适用于 PrimeFaces 完成的所有 ajax 魔法。如果您愿意,我们可以尝试为您提供帮助。但是你必须分享更多细节,也许 HtmlUnit 用户列表是讨论此类问题的地方。
  • 实际上我无法在此处提供我使用的网站的链接,但是在使用 HtmlUnit 时,我使用了:WebConnectionWrapper 并调试每个请求/响应。 Ajax 函数在中间停止(在第一个 HTTP 请求完成后,没有出现下载所需数据/文件的第二个 HTTP 请求)。 ajax 函数被混淆了,所以把它们放在这里是没有用的
  • 如果你使用某种库,也许有机会找到一个公开的演示。如果没有机会对此进行调试,很难猜测出了什么问题。你用过最新版本吗? 2.28 版本在 Promise 方面有一些很大的改进。也许值得尝试最新的(昨天的 2.29 ;-)
  • 我检查了 2.29v 并添加到主题附加信息

标签: java file selenium download selenium-chromedriver


【解决方案1】:

关于 HtmlUnit 你可以试试这个:

在 dom 元素上调用 click() 是同步调用。这意味着, this 在此调用的响应被检索和处理后返回。通常所有的 JS 库都在做一些异步魔法(比如出于各种(好的)原因使用 setTimeout(,10) 开始一些处理。你的代码会意识到这一点。

更好的方法是做这样的事情

Page page = _link.click();
webClient.waitForBackgroundJavaScript(1000);

有时 Ajax 请求会重定向到新内容。我们必须通过检查当前窗口内容来解决这个新问题

page = page.getEnclosingWindow().getEnclosedPage();

或许更好 在下载的情况下,(二进制)响应可能会在新窗口中打开

WebWindow tmpWebWindow = webClient.getCurrentWindow();
tmpWebWindow = tmpWebWindow.getTopWindow();
page = tmpWebWindow.getEnclosedPage();

这可能是您正在寻找的响应。

page.getWebResponse().getContentAsStream();

猜测您的 Web 应用程序发生了什么有点棘手。如果您愿意,可以通过私人邮件与我联系或在 HtmlUnit 用户邮件列表中讨论此问题。

【讨论】:

  • 好的,所以我检查了所有这些选项,并且总是有一些 html 代码,而不是来自内部 AJAX 请求的实际响应,它应该返回 CSV 格式的文本。我不知道如何使用 HtmlUnit 进行调试。我不确定 HtmlUnit 层次结构,但如果 Ajax 函数真的没有在中间停止,我希望在 currentWindow 中有这个响应:/
  • 关于 currentWindow - HtmlUnit 总是需要一个内容窗口。通常,您的浏览器会打开文件对话框,让您可以选择将下载的文件保存到磁盘 - 在这种情况下会打开 HtmlUnti 一个包含您的文件作为内容的新窗口。
  • 作为起点,我建议使用像 Charles 或 Fiddler 这样的网络代理。为您的真实浏览器启用代理并为您的案例捕获流量。比在代理上使用 HtmlUnit 运行相同的案例并捕获流量。比比较.... 作为起点,确定 csv 数据是通过网络发送还是 HtmlUnit 根本不要求数据。如果你喜欢,你可以给我发一封私人邮件,里面有你的代码,我会看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 2020-02-10
  • 1970-01-01
  • 2017-03-09
  • 2017-08-26
  • 2018-04-14
  • 1970-01-01
相关资源
最近更新 更多