在新选项卡中进行下载时,如何在Selenium(Java)中无头下载文件?

在新选项卡中进行下载时,如何在Selenium(Java)中无头下载文件?,java,selenium,google-chrome,download,headless,Java,Selenium,Google Chrome,Download,Headless,我有一个网页,当我点击一个按钮时,它会打开另一个选项卡,然后在其中,几秒钟后下载一个csv文件。我试图无头地自动化这个,但我无法做到。我正在使用下面的代码。但我认为以下解决方案适用于在同一窗口中进行下载。我如何调整它以适应我的情况 如果我通过注释掉行选项来正常运行(非headless),代码工作正常,文件得到下载 System.setProperty(“webdriver.chrome.driver”,webdriverpath); ChromeOptions选项=新的ChromeOptions

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

如果我通过注释掉行选项来正常运行(非headless),代码工作正常,文件得到下载

System.setProperty(“webdriver.chrome.driver”,webdriverpath);
ChromeOptions选项=新的ChromeOptions();
options.setExperimentalOption(“useAutomationExtension”,false);
options.addArguments(“--test type”);
选项。添加参数(“--headless”);
options.addArguments(“--disable extensions”);
ChromeDriverService driverService=ChromeDriverService.createDefaultService();
HashMap chromePrefs=新HashMap();
chromePrefs.put(“profile.default\u content\u settings.popups”,0);
chromePrefs.put(“download.default\u目录”,downloadFilepath);
选项。设置实验选项(“prefs”,chromePrefs);
ChromeDriver驱动程序=新的ChromeDriver(驱动服务,选项);
Map commandParams=new HashMap();
commandParams.put(“cmd”,“Page.setDownloadBehavior”);
Map params=新的HashMap();
参数put(“行为”、“允许”);
参数put(“downloadPath”,downloadFilepath);
commandParams.put(“params”,params);
ObjectMapper ObjectMapper=新的ObjectMapper();
HttpClient HttpClient=HttpClientBuilder.create().build();
String命令=objectMapper.writeValueAsString(commandParams);
字符串u=driverService.getUrl().toString()+“/session/”+driver.getSessionId()+“/chromiu/send_command”;
HttpPost请求=新的HttpPost(u);
addHeader(“内容类型”、“应用程序/json”);
request.setEntity(新的StringEntity(命令));
httpClient.execute(请求);
//打开URL
//点击按钮

在无头模式下下载时,我也有同样的问题。(但在无头模式下工作)

我找到了解决方案(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

第二步-配置下载行为agian

您可以将下面的代码换行以运行,并在切换到新选项卡后调用它

params = {'behavior': 'allow', 'downloadPath': download_path}
print("Change default download dir to :", params['downloadPath'])
driver.execute_cdp_cmd('Page.setDownloadBehavior', params) 
第三步-重新加载页面(重要步骤)

它将触发下载行为

 self.driver.refresh()

以下是在Java中适用的解决方案:

单击“下载”按钮后,立即切换到“新建”选项卡并刷新:

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

(在我的例子中,它在没有刷新的情况下工作。因此,您也可以在没有该语句的情况下尝试)

请编辑问题,使其准确显示您尝试的内容,并说明失败的方式。另外,试着用普通的、无头的Chrome浏览器运行它,看看你自己是否能看到问题所在。最后,要确保你的代码不会因为等待下载时间太长而失败。执行完成。但是文件无法保存。我想说的是,不等待可能是问题所在。等待就是问题所在。通常情况下,如果我们不小心下载文件,它们将无法保存。(人们说这是硒的一个‘特性’)上述解决办法应该可以解决这个问题。不幸的是,在我的情况下,它不工作,我想这是因为我的下载发生在一个新打开的标签,只要我点击下载按钮。希望你使用的是最新版本的chrome和chrome驱动程序。在Chrome 77支持的无头模式下下载谢谢!这对我有用!但我所做的只是在点击了DOWLOAD按钮后立即切换到新标签。我根本不需要做第二步和第三步!(对于第三步,我认为这是因为在我的例子中,新标签链接实际上不是下载链接。在几秒钟内打开新标签后,该页面将在文件生成后自动刷新/重定向,此时下载被触发)。我不知道为什么我能跳过第二步。
    ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
    driver.switchTo().window(tabs2.get(1));
    driver.navigate().refresh();