【问题标题】:How to set default download directory in selenium Chrome Capabilities?如何在 selenium Chrome 功能中设置默认下载目录?
【发布时间】:2016-04-03 14:09:41
【问题描述】:

请找到以下具有 chrome 功能的代码。实际上浏览器并没有将文件下载到指定路径。

private static DesiredCapabilities getChromeCapabilities() throws Exception {

    String chromePath = BrowserUtil.class.getResource("/Browserdrivers/chromedriver.exe").getPath();
    System.setProperty("webdriver.chrome.driver", chromePath);
    String downloadFilepath = "C:\\TestDownloads";
    ChromeOptions options = new ChromeOptions();
    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);
    options.addArguments("--test-type");
    options.addArguments("start-maximized", "disable-popup-blocking");

    DesiredCapabilities chromeCapabilities = DesiredCapabilities.chrome();
    setProxy(chromeCapabilities);
    chromeCapabilities.setPlatform(Platform.WINDOWS);
    chromeCapabilities.setCapability("name", MDC.get("testname"));
    chromeCapabilities.setCapability(ChromeOptions.CAPABILITY, options);
    return chromeCapabilities;
}

【问题讨论】:

    标签: java selenium selenium-webdriver selenium-chromedriver


    【解决方案1】:

    对于 Chromedriver 试用:

    String downloadFilepath = "/path/to/download";
    HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
    chromePrefs.put("profile.default_content_settings.popups", 0);
    chromePrefs.put("download.default_directory", downloadFilepath);
    ChromeOptions options = new ChromeOptions();
    options.setExperimentalOption("prefs", chromePrefs);
    DesiredCapabilities cap = DesiredCapabilities.chrome();
    cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
    cap.setCapability(ChromeOptions.CAPABILITY, options);
    WebDriver driver = new ChromeDriver(cap);
    

    注意:- 在 windows 中,您需要使用 \\ 作为路径,而如果您使用的是 linux 或 mac,则使用 //

    希望这会有所帮助。 :)

    【讨论】:

    • 或者您将只使用 File.separator 而不是斜杠
    • 如果我需要在运行时更改下载路径怎么办?我的意思是为每个测试设置自己的路径。
    • 或者您可以使用 System.IO.Path.Combine 它将根据操作系统添加适当的分隔符
    • @ShubhamJain 当我在 chrome 中尝试使用无头浏览器时。我没有看到它正在工作。有什么线索吗?
    • 有没有办法在 当前会话 上更改下载路径,类似于单击 Chrome 设置->下载的方式?我看到的答案总是导致 build new option + new driver + get a whole new session 。我不希望关闭当前会话,因为我的文件夹分隔基于下拉列表中的每个项目,并且无需重新加载新页面。
    【解决方案2】:

    帮助我在 Windows 上解决此问题的答案:(https://bugs.chromium.org/p/chromedriver/issues/detail?id=783)。

    Map<String, Object> prefs = new HashMap<String, Object>();
    prefs.put("download.default_directory",  System.getProperty("user.dir")+ File.separator + "externalFiles" + File.separator + "downloadFiles");
    ChromeOptions options = new ChromeOptions();
    options.setExperimentalOption("prefs", prefs);
    ChromeDriver driver = new ChromeDriver(options);
    

    【讨论】:

    • 使用 Windows 的注意事项:“download.default_directory”字符串必须使用反斜杠 (\),而不是正斜杠 (/)。
    【解决方案3】:

    为了让它更干净和简单,我开发了一个library,它可以让你生成一个 ChromeOptions 对象,其中包含你的下载文件夹。例如,要定义“/tmp/downloads”,请使用:

    private SeleniumDownloadKPI seleniumDownloadKPI;
    
    @BeforeEach
    void setUpTest() {
    
        // New instance of SeleniumDownloadKPI with given download folder.
        seleniumDownloadKPI =
             new SeleniumDownloadKPI("/tmp/downloads");
        ChromeOptions chromeOptions =
                seleniumDownloadKPI.generateDownloadFolderCapability();
        driver = new ChromeDriver(chromeOptions);
    

    library 还包含允许接收下载 KPI 并执行断言的方法。

    【讨论】:

      【解决方案4】:

      对于 Chrome 驱动程序,以下代码适用于我

      String downloadFilepath = "/path/to/download";
      HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
      chromePrefs.put("profile.default_content_settings.popups", 0);
      chromePrefs.put("download.default_directory", downloadFilepath);
      ChromeOptions options = new ChromeOptions();
      options.setExperimentalOption("prefs", chromePrefs);
      WebDriver driver = new ChromeDriver(options);
      

      【讨论】:

        【解决方案5】:

        对于看到此页面的 Python 用户——这是我在 Python Selenium 中设置下载目录的方式(这只是 Shubham 接受的答案的 Python 版本):

        def newChromeBrowser(headless=True, downloadPath=None):
            """ Helper function that creates a new Selenium browser """
            options = webdriver.ChromeOptions()
            if headless:
                options.add_argument('headless')
            if downloadPath is not None:
                prefs = {}
                os.makedirs(downloadPath)
                prefs["profile.default_content_settings.popups"]=0
                prefs["download.default_directory"]=downloadPath
                options.add_experimental_option("prefs", prefs)
            browser = webdriver.Chrome(options=options, executable_path=CHROMEDRIVER_PATH)
            return browser
        

        【讨论】:

        • 我将此作为我 Python 代码的灵感来源,并且运行良好。最后,它看起来像这样: path_dest = '//path/to/download/' prefs = {} prefs['profile.default_content_settings.popups']=0 prefs['download.default_directory']=path_dest options = Options () options.add_experimental_option('prefs',prefs)
        • 非常感谢。这应该是公认的答案(对于 python)。
        • 如果目标目录已经存在,os.makedirs 命令会失败,解决方法是:os.makedirs(downloadPath, exist_ok=True)
        【解决方案6】:

        2020 年更新:

        Chrome:v84

        Chrome 驱动程序:v83

        JDK:OpenJDK 11 (LTS)

        使用Paths 类作为独立于平台的文件分隔符。

        @Test
        public void doFileDownload() throws Throwable {
            // Since Java 7: Relative path from project root dir
            // Put in target dir to avoid committing downloaded files
            var downloadDir = Paths.get("target").toAbsolutePath().toString();
        
            var prefs = new HashMap<String, Object>();
            prefs.put("download.default_directory", downloadDir); // Bypass default download directory in Chrome
            prefs.put("safebrowsing.enabled", "false"); // Bypass warning message, keep file anyway (for .exe, .jar, etc.)
            var opts = new ChromeOptions();
            opts.setHeadless(true);
            opts.setExperimentalOption("prefs", prefs);
        
            var driver = new ChromeDriver(opts); // ChromeDriver binary is added to PATH env var
            driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
            driver.manage().window().maximize();
            driver.get("https://the-internet.herokuapp.com/download");
        
            var downloadLink = driver.findElement(By.cssSelector("a[href*='some-file.txt']"));
            var downloadHref = downloadLink.getAttribute("href").replace(":", "");
            var downloadFileName = Paths.get(downloadHref).getFileName().toString();
            downloadLink.click();
        
            // Wait download to finish for 60s
            var downloadFilePath = Paths.get(downloadDir, downloadFileName);
            new WebDriverWait(driver, 60).until(d -> downloadFilePath.toFile().exists());
        
            // Since Java 11: Read content of downloaded file
            var content = Files.readString(downloadFilePath);
        
            // Do tests with string content...
            log.info("Content={}", content);
        
            driver.quit();
        }
        

        输出:

        在任何运行之前执行mvn clean 还需要注意必须覆盖现有文件。

        pom.xml:

        <properties>
            <!-- Remove encoding warnings -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        </properties>
        
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server -->
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-server</artifactId>
                <version>3.141.59</version>
                <scope>test</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>5.6.2</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
        
        <build>
            <plugins>
                <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <release>11</release>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.2</version>
                </plugin>
            </plugins>
        </build>
        

        【讨论】:

        • 一个很好的解决方案和答案。我不喜欢你如何坚持一些专门的“新”java特性——本可以为我们那些不允许更新的公司僵尸做一些事情:)但我想明确一点:你给我和社区做了一个很棒的服务!谢谢!
        • Java 7 是 10 年前的事了。它不是“新的”。解决您的问题的方法很简单 - 转到一家在过去 10 年内使用过某些东西的公司。不客气!
        • 啊,抱歉,我只查看了“首选项”部分(因为我已经有自己的系统将文件传送到需要的位置)并错过了“自 java 7 以来”的评论。 ……在某些方面,做一个平庸的群体中最聪明的人,还不如和你这样的鲨鱼一起在深水里游泳! :D
        • 我很欣赏这种诚实。 :)) 在某些方面我也做了同样的事情,我的技能更接近开发人员的水平(我很确定我可以做到),但我走的是人迹罕至的道路以在竞争中领先。现在,“摇滚明星”开发人员被困在我的祖国,而我在澳大利亚得到了一份工作。
        猜你喜欢
        • 2020-01-28
        • 2016-05-28
        • 2018-07-26
        • 1970-01-01
        • 2022-11-11
        • 1970-01-01
        • 2021-03-31
        • 2021-09-03
        相关资源
        最近更新 更多