在新选项卡中下载时如何在 Selenium (Java) 中无头下载文件?
How to download files headless in Selenium (Java) when download happens in new tab?
我有一个网页,当我单击一个按钮时,它会打开另一个选项卡,然后在其中几秒钟后下载一个 csv 文件。我试图无头地自动执行此操作,但我无法这样做。我正在使用下面的代码。但我认为以下解决方案适用于在同一 window 中进行的下载。我该如何调整它以适应我的情况?
如果我 运行 通过注释掉行 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
我在无头模式下下载时遇到同样的问题。(但在非无头模式下工作)
我找到了解决方案(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)
输出(确认window已成功切换到新标签页):
windows count: 2
window: CDwindow-9D0B0A86678939EE6EA89B4627016F5A
windows count: 2
window: 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();
(在我的例子中,它在没有刷新的情况下工作。所以你也可以尝试不使用该语句)
我有一个网页,当我单击一个按钮时,它会打开另一个选项卡,然后在其中几秒钟后下载一个 csv 文件。我试图无头地自动执行此操作,但我无法这样做。我正在使用下面的代码。但我认为以下解决方案适用于在同一 window 中进行的下载。我该如何调整它以适应我的情况?
如果我 运行 通过注释掉行 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
我在无头模式下下载时遇到同样的问题。(但在非无头模式下工作)
我找到了解决方案(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)
输出(确认window已成功切换到新标签页):
windows count: 2
window: CDwindow-9D0B0A86678939EE6EA89B4627016F5A
windows count: 2
window: 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();
(在我的例子中,它在没有刷新的情况下工作。所以你也可以尝试不使用该语句)