【问题标题】:How to download files headless in Selenium (Java) when download happens in new tab?在新选项卡中下载时如何在 Selenium (Java) 中下载无头文件?
【发布时间】:2020-03-31 12:12:31
【问题描述】:

我有一个网页,当我单击一个按钮时,它会打开另一个选项卡,然后在其中几秒钟后下载一个 csv 文件。我试图无头地自动执行此操作,但我无法这样做。我正在使用下面的代码。但我认为以下解决方案适用于在同一窗口中进行下载。我该如何调整它以适应我的情况?

如果我通过注释掉行 options.addArguments("--headless"); 正常运行此代码(非无头),则代码可以正常工作并且文件会被下载;

    System.setProperty("webdriver.chrome.driver", webdriverpath);
    ChromeOptions options = new ChromeOptions();
    options.setExperimentalOption("useAutomationExtension", false);
    options.addArguments("--test-type");
    options.addArguments("--headless");
    options.addArguments("--disable-extensions"); 
    ChromeDriverService driverService = ChromeDriverService.createDefaultService();


    HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
    chromePrefs.put("profile.default_content_settings.popups", 0);
    chromePrefs.put("download.default_directory", downloadFilepath);
    options.setExperimentalOption("prefs", chromePrefs);


    ChromeDriver driver = new ChromeDriver(driverService, options);

    Map<String, Object> commandParams = new HashMap<>();
    commandParams.put("cmd", "Page.setDownloadBehavior");
    Map<String, String> params = new HashMap<>();
    params.put("behavior", "allow");
    params.put("downloadPath", downloadFilepath);
    commandParams.put("params", params);
    ObjectMapper objectMapper = new ObjectMapper();
    HttpClient httpClient = HttpClientBuilder.create().build();
    String command = objectMapper.writeValueAsString(commandParams);
    String u = driverService.getUrl().toString() + "/session/" + driver.getSessionId() + "/chromium/send_command";
    HttpPost request = new HttpPost(u);
    request.addHeader("content-type", "application/json");
    request.setEntity(new StringEntity(command));
    httpClient.execute(request);




    //OPEN URL
    //Click Button

【问题讨论】:

  • 请编辑问题,以便它准确显示您尝试过的内容并说明失败的方式。另外,尝试使用常规的非无头 Chrome 运行它,并观察您是否可以自己查看问题所在。最后,请确保您的代码不会简单地等待足够长的时间来进行下载。
  • 不,它不等待。执行完成。但是文件不会被保存。
  • 我的意思是不等待可能是问题所在。
  • 它正在等待。如果我们不小心下载文件,通常不会保存文件。 (人们说它是硒的“特征”)上面的解决方法应该可以解决这个问题。不幸的是,在我的情况下它不起作用,我认为这是因为我的下载发生在我点击下载按钮后新打开的标签中。
  • 希望您使用的是最新版本的 chrome 和 chrome 驱动程序。 Chrome 77 支持无头模式下载chromedriver.chromium.org/downloads

标签: java selenium google-chrome download headless


【解决方案1】:

在无头模式下下载时我遇到了同样的问题。(但在非无头模式下工作)

我找到了解决方案(Python 中的示例):

第一步 - 点击下载按钮并切换到新标签:

download_btn.send_keys(Keys.Control + Keys.RETURN)  //click button to download
print("windows count:", len(self.driver.window_handles)) //check how many windonws(tab)
print("window:", self.driver.current_window_handle)  //check current window
download_btn.send_keys(Keys.Control + "2")  //switch window to new tab
self.driver.switch_to.window(self.driver.window_handles[-1]) // using driver switch to last created tab
print("windows count:", len(self.driver.window_handles))
print("window:", self.driver.current_window_handle)

输出(确认窗口已成功切换到新标签页):

窗口数:2

窗口:CDwindow-9D0B0A86678939EE6EA89B4627016F5A

窗口数:2

窗口:CDwindow-43ACC6E22256C42592CD34E880A08079

第二步 - 再次配置下载行为

您可以将下面的代码包装起来,并在切换到新标签后调用它。

params = {'behavior': 'allow', 'downloadPath': download_path}
print("Change default download dir to :", params['downloadPath'])
driver.execute_cdp_cmd('Page.setDownloadBehavior', params) 

第三步 - 重新加载页面(重要步骤)

它将触发下载行为。

 self.driver.refresh()

【讨论】:

  • 谢谢!这对我有用!但我所做的只是在单击下载按钮后切换到新标签。我根本不需要做第二步和第三步! (对于第三步,我认为这是因为在我的情况下,新标签链接实际上并不是下载链接。在几秒钟内打开新标签后,该页面将在文件生成后自动刷新/重定向,即下载被触发)。艰难,我不知道为什么我能够跳过第二步。
【解决方案2】:

这是适用于 Java 的解决方案:

点击下载按钮后立即切换到新标签并刷新:

    ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
    driver.switchTo().window(tabs2.get(1));
    driver.navigate().refresh();

(在我的情况下,它无需刷新即可工作。所以你也可以尝试不使用该语句)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多