How to download files headless in Selenium (Java) when download happens in new tab?

有些话、适合烂在心里 提交于 2020-01-24 07:20:08

问题


I have a web page where when I click a button it opens another tab and then in it, downloads a csv file after few seconds. I was trying to automate this headlessly but I am unable to do so. I am using the below code. But I think the below solutions is for download happening in same window. How can I tweak it to work in my situation?

The code works fine and the file gets download if i run this normally (non headless) by commenting out the line 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

回答1:


I have the same issue when download in headless mode.(But working in non-headless mode)

And I found the solution (example in Python):

First step - click Download button and switch to new tab:

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)

Output (to confirm that window has switched to new tab successful):

windows count: 2

window: CDwindow-9D0B0A86678939EE6EA89B4627016F5A

windows count: 2

window: CDwindow-43ACC6E22256C42592CD34E880A08079

Second step - Config download behavior agian

You can wrap below code to function and call it after switched to new tab.

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

Third step - Reload the page (Important step)

It will trigger download behavior.

 self.driver.refresh()



回答2:


Here is the solution that worked for in Java :

Right after clicking the download button switch to new tab and also do a refresh :

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

(In my case it worked without the refresh. So you mey try without that statement aswell)



来源:https://stackoverflow.com/questions/59214185/how-to-download-files-headless-in-selenium-java-when-download-happens-in-new-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!