【问题标题】:Downloading a file from Selenium and chromedriver从 Selenium 和 chromedriver 下载文件
【发布时间】:2017-11-27 01:09:31
【问题描述】:

我无法让 Selenium 和 Chrome (Canary) 下载文件。 我正在使用 Java 和 Chrome 59/60(因为我的测试同时适用于 Windows 和 Linux)并且我正在尝试从网页开始下载文件。

当我从 selenium 中不设置无头模式时,chrome 窗口打开并下载文件。

当我设置--headless 标志时,chrome 窗口不会打开,下载也不会开始。

    public static void chromeDownload() throws IOException, InterruptedException{
            
            ChromeOptions options = new ChromeOptions();
            String downloadFilepath = "";
            
            if (ValidateOS.isWindows()){
                System.out.println("This is a Windows system.");
                System.setProperty("webdriver.chrome.driver", "resources\\driver\\chromedriver.exe");
                options.setBinary("C:\\Users\\Juri\\AppData\\Local\\Google\\Chrome SxS\\Application\\chrome.exe");
                downloadFilepath = "C:\\";
            } else if (ValidateOS.isUnix()){
                System.out.println("This is a Unix system.");
                System.setProperty("webdriver.chrome.driver", "resources/driver/chromedriver");
                options.setBinary("/usr/bin/google-chrome");
                downloadFilepath = "/home/juri/";
            }
            
            // Manage the download
            HashMap<String, Object> chromePrefs = new HashMap<>();
            chromePrefs.put("profile.default_content_settings.popups", 0);
            chromePrefs.put("download.default_directory", downloadFilepath);
    
            // Save Chrome Options
            HashMap<String, Object> chromeOptionsMap = new HashMap<>();
            options.setExperimentalOption("prefs", chromePrefs);
            options.addArguments("--headless --disable-gpu");
            
            DesiredCapabilities cap = DesiredCapabilities.chrome();
            cap.setCapability(ChromeOptions.CAPABILITY, chromeOptionsMap);
            cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
            cap.setCapability(ChromeOptions.CAPABILITY, options);
            
            ChromeDriver driver = new ChromeDriver(cap);
                    
            driver.get("http://localhost/my-test-page.html");

            driver.findElement(By.id("download")).click(); 
            Thread.sleep(5000); // wait 5 seconds for a small file to download.. yes.. I know...
            driver.quit();
        }

点击时,在 GUI 模式下开始下载。在无头模式下,它不会。

如何解决?

OT

我正在使用 Chrome Canary,它在 v.60 中带有 --headless 功能。在没有 gui 的服务器上运行抓取器非常方便。 但是,出于同样的原因.. 我发现在没有 GUI 的服务器上下载 Chrome 毫无用处。 除了主要问题。我想知道你们,开发者,是否认为在 Linux 服务器上安装 chrome 只是为了在无头模式下启动它是可以的。

更新: 如果有人会读到这篇文章,我仍在寻找解决方案:/ 搜索结果有一些,我都试过了

【问题讨论】:

  • 最近有人问了一个类似的问题,得到了回答,stackoverflow.com/questions/45631715/…。显然,无头 chrome 会阻止下载,除非它已通过开发工具中的设置获得批准
  • @kshishoo 嗨!我很高兴有人注意到我的问题。新问题正是我现在正在寻找的几个星期。我将再次尝试处理这个项目,我的项目已经完成,但我在测试服务器上安装了一个 Ubuntu GUI 让它工作。如果无头在这个解决方法中工作,那太棒了!
  • 这个案子有更新吗?我找到了Javabugs.chromium.org/p/chromium/issues/detail?id=696481#c93的代码解决方案,我还没有测试过。无论如何,我正在寻找一个更短的解决方案。

标签: java google-chrome selenium download


【解决方案1】:

您预计会使用“Docker”吗?使用 selenium Grid 和任意数量的浏览器启动 dockerized Ubuntu。或者只是没有 Selenium 网格的浏览器。

另一方面,您无需使用无头模式,您可以使用多线程。 例如:

  1. 下载file

  2. 然后使用以下命令启动:docker-compose up -d

  3. 对每个服务器进行一些调整,以访问“localhost”上的网格服务器
    http://localhost:4444/grid/console http://localhost:4444/wd/hub

  4. 使用以下代码:

    WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub")); //处理 URL() 上的异常 构造函数。

  5. 您拥有带有浏览器的轻量级虚拟机,您的服务器可以处理任意数量的浏览器。而且不需要--headless模式

但这不是最初问题的解决方案。

【讨论】:

    【解决方案2】:

    通过修改此链接中的代码解决: Download files in Java, Selenium using ChromeDriver and headless mode

    对于那些想知道我的代码现在怎么样的人......

    public static void chromeDownload(String address, String Headless, String DownDir) throws IOException, InterruptedException{
    
        ChromeOptions options = new ChromeOptions();
        String downloadFilepath = DownDir;
    
        if (ValidateOS.isWindows()){
            System.out.println("This is a Windows system.");
            System.setProperty("webdriver.chrome.driver", "resources\\driver\\chromedriver.exe");
            //options.setBinary("C:\\Users\\Juri\\AppData\\Local\\Google\\Chrome SxS\\Application\\chrome.exe");
            // If this is commented, the grabber will use the main Chrome
        } else if (ValidateOS.isUnix()){
            System.out.println("This is a Unix system.");
            System.setProperty("webdriver.chrome.driver", "resources/driver/chromedriver");
            options.setBinary("/usr/bin/google-chrome");
        }
    
        switch (Headless.toUpperCase()){
            case "TRUE":
                options.addArguments("--headless --disable-gpu");
                break;
            case "FALSE":
            default:
                options.addArguments("--window-size=1152,768");
                break;
        }
        options.addArguments("--test-type");
        options.addArguments("--disable-extension");
    
        ChromeDriverService driverService = ChromeDriverService.createDefaultService();
        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);
        params.put("cmd", "Page.setDownloadBehavior");
    
        commandParams.put("params", params);
        ObjectMapper objectMapper = new ObjectMapper();
        CloseableHttpClient 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);
    
        driver.get(address);
    
        driver.findElement(By.id("download")).click(); 
        driver.quit();
    }
    

    【讨论】:

    • 您能否描述您的代码,而不是从其他人的帖子中复制它。您的代码不起作用
    • 这不适用于在新标签页中打开的 pdf 文件
    • @Poltu -- 确保将您的内容类型设置为支持 pdf。另请注意,chrome 试图打开 pdf 的内联,可以禁用(还有其他主题:like this stackoverflow.com/questions/31672897/…
    猜你喜欢
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2015-01-09
    • 2021-08-13
    相关资源
    最近更新 更多