Selenium Java 不会使用 --headless 选项

问题描述

我正在尝试一种非常罕见的行为,尝试从特定服务中的帐户登录/退出。

具体问题与“--headless”选项有关,没有它它也能正常工作。工作流程如下:

  1. 访问登录页面,输入电子邮件和密码,然后单击“进入”按钮
  2. 等待主屏幕加载
  3. 进入主屏幕后,查找“登录”或“注销”按钮
  4. 单击上一点中找到的按钮并检查该按钮是否真的被修改(“登录”应更改为“注销”,反之亦然)。这是真正知道操作已执行的确认。

让我发疯的是我在程序执行过程中看不到任何错误,在两种情况下(有和没有 --headless 选项)我的日志显示完全相同的数据(检查底部的代码)。例如对于“注销”请求:

  • 2021-02-24 10:42:18.358 [main] 信息 - 正在加载网络...
  • 2021-02-24 10:42:20.286 [main] INFO - 网页加载
  • 2021-02-24 10:42:20.286 [main] INFO - 等待主屏幕
  • 2021-02-24 10:42:22.557 [main] INFO - 检测到进度条
  • 2021-02-24 10:42:24.585 [main] INFO - 注销请求
  • 2021-02-24 10:42:24.705 [main] INFO - 注销完成
  • 2021-02-24 10:42:25.281 [main] INFO - [END] 登录/退出请求已完成

在这两种情况下一切似乎都很顺利,但是在使用 --headless 运行此代码后,如果我手动访问我的帐户,我可以看到我没有注销。但是,如果没有 --headless,它就可以正常工作。

我在开始时使用了多个 ChromeOptions,但它们都不起作用,我检测到将“注销”按钮修改为“登录”按钮对我来说没有意义,但操作没有真的发生了。

这是我正在使用的:

  • Chromedriver 88
  • Java 1.8
  • Java 硒 3.141.59

完整代码如下:

public void run() {
    try {
        int actionToDo = -1;
        
        log.info("[START] New in/out request for user " + username);
        
        // Webdriver configuration
        Map<String,Object> prefs = new HashMap<String,Object>();
        prefs.put("geolocation",true); 
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs",prefs);
        options.addArguments("--headless");
        options.addArguments("--disable-gpu");
        options.addArguments("--disable-extensions");
        options.addArguments("--start-maximized");
        options.addArguments("--headless");
        options.addArguments("no-sandbox");
        
        System.setProperty("webdriver.chrome.driver",WoffuUtils.WEBDRIVER_PATH);
        WebDriver driver = new ChromeDriver(options);

        // Waiting times
        driver.manage().timeouts().pageLoadTimeout(GENERAL_WAITING_TIME,TimeUnit.SECONDS);
        WebDriverWait wait = new WebDriverWait(driver,GENERAL_WAITING_TIME);

        log.info("loading web...");
        driver.get(WoffuUtils.URL);
        log.info("web loaded");
        
        // Log in
        log.info("waiting for the home screen");
        WebElement emailInput = driver.findElement(By.id("tuEmail"));
        WebElement passwordInput = driver.findElement(By.id("tuPassword"));
        emailInput.sendKeys(username);
        passwordInput.sendKeys(password);
        driver.findElement(By.xpath("//*[@id=\"intro\"]/div/form/span/button")).click();
        
        // Wait until the home page is loaded
        wait.until(myDriver -> driver.findElement(By.className("progress-bar")));   
        log.info("progress bar detected");
        
        // Identify if we shoud login in or log out
        WebElement inOutButton = null;
        
        // Introduce a short sleep time because the home screen seems to show the "In" button
        // always even when you are already logged in. The "in" is properly replaced by the
        // "out" button almost immediately but without this short waiting time the action is
        // always detected as "Log in"
        Thread.sleep(HOME_SCREEN_SLEEP_TIME_MILLIS);
        
        try {
            inOutButton = driver.findElement(By.id("in"));
            actionToDo = WoffuUtils.ACTION_LOG_IN;
            log.info("Log in request");
        } catch (NoSuchElementException noElementExcIn) {
            try {
                inOutButton = driver.findElement(By.id("out"));
                actionToDo = WoffuUtils.ACTION_LOG_OUT;
                log.info("Log out request");
            } catch (NoSuchElementException noElementExcOut) { }
        }   
        
        // Perform the final click on the appropriate button
        switch (actionToDo) {
            case WoffuUtils.ACTION_LOG_IN:
                inOutButton.click();
                wait.until(myDriver -> driver.findElement(By.id("out")));
                log.info("Log in DONE");
                break;
            case WoffuUtils.ACTION_LOG_OUT:
                inOutButton.click();
                wait.until(myDriver -> driver.findElement(By.id("in")));
                log.info("Log out DONE");
                break;
            default:
                log.error("ERROR: LOG IN/OUT BUTTON NOT DETECTED !!!");
        }

        driver.quit();
        
        log.info("[END] Log in/out request finished");
    } catch (Exception e) {
        log.error("ERROR in Selenium in/out handler: " + e.getMessage());
    } finally {
        // Remove the request from the pending list
        String requestToRemove = this.username + WoffuUtils.REQUEST_SEPARATOR + this.password;
        WoffuUtils.pendingRequests.remove(requestToRemove);
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)