Chrome 关闭时自动退出 WebDriver 的完整解决方案

发布于:2025-06-30 ⋅ 阅读:(14) ⋅ 点赞:(0)

import org.openqa.selenium.*;

import org.openqa.selenium.chrome.*;

import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicBoolean;

 

public class AutoWebDriverExit {

    private static WebDriver driver;

    private static final ExecutorService monitorExecutor = Executors.newSingleThreadExecutor();

    private static final AtomicBoolean active = new AtomicBoolean(true);

    

    public static void main(String[] args) {

        // 1. Chrome 配置

        ChromeOptions options = new ChromeOptions();

        options.addArguments("--disable-gpu", "--no-sandbox", "--disable-dev-shm-usage");

        options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});

        

        // 2. 启动 WebDriver

        System.setProperty("webdriver.chrome.driver", "C:/path/to/chromedriver.exe");

        driver = new ChromeDriver(options);

        

        // 3. 启动浏览器关闭监听器

        startBrowserCloseMonitor();

        

        // 4. 注册 JVM 关闭钩子

        Runtime.getRuntime().addShutdownHook(new Thread(() -> safeQuitDriver()));

        

        try {

            // 5. 业务代码

            driver.get("https://example.com");

            // ... 页面操作代码 ...

            

            // 6. 等待浏览器关闭(示例等待)

            while (active.get()) {

                TimeUnit.SECONDS.sleep(1);

            }

            System.out.println("浏览器已被关闭,WebDriver 已退出");

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    

    private static void startBrowserCloseMonitor() {

        monitorExecutor.submit(() -> {

            try {

                // 检测浏览器是否关闭

                new WebDriverWait(driver, Duration.ofMillis(500))

                    .until(d -> {

                        try {

                            driver.getTitle(); // 尝试执行简单操作

                            return false; // 浏览器仍在运行

                        } catch (WebDriverException e) {

                            handleBrowserClosed(e);

                            return true; // 浏览器已关闭

                        }

                    });

            } catch (TimeoutException e) {

                // 浏览器仍在运行,继续监控

            }

        });

    }

    

    private static void handleBrowserClosed(WebDriverException e) {

        // 1. 设置活动状态为 false

        active.set(false);

        

        // 2. 安全退出 WebDriver

        safeQuitDriver();

        

        // 3. 记录浏览器关闭信息

        System.out.println("检测到浏览器关闭: " + e.getMessage());

        System.out.println("WebDriver 资源已成功释放");

    }

    

    private static void safeQuitDriver() {

        try {

            if (driver != null) {

                // 避免出现 "Session not created" 异常

                try {

                    driver.close(); // 尝试正常关闭

                } catch (Exception ignore) {}

                

                driver.quit(); // 重要:释放 WebDriver 资源

                driver = null;

                

                // 关闭监控线程池

                monitorExecutor.shutdownNow();

            }

        } catch (Exception e) {

            System.err.println("WebDriver 退出时出错: " + e.getMessage());

        }

    }

}

当需要自动恢复而不是退出时,可以使用以下扩展方案:

public class AutoRecoveryDriver extends EventFiringWebDriver {
    private static final int MAX_RETRIES = 3;
    private int retryCount = 0;
    
    public AutoRecoveryDriver(WebDriver driver) {
        super(driver);
    }
    
    @Override
    public void quit() {
        try {
            super.quit();
        } catch (WebDriverException e) {
            handleRecovery(e);
        }
    }
    
    private void handleRecovery(WebDriverException e) {
        if (retryCount >= MAX_RETRIES) {
            throw e;
        }
        
        System.out.println("检测到浏览器意外关闭,尝试恢复 (尝试次数: " + (retryCount+1) + ")");
        
        // 1. 重新初始化 WebDriver
        WebDriver newDriver = initNewDriver();
        setWrappedDriver(newDriver);
        
        // 2. 增加重试计数
        retryCount++;
        
        // 3. 恢复应用状态(如重新登录等)
        recoverApplicationState();
    }
    
    private WebDriver initNewDriver() {
        ChromeOptions options = new ChromeOptions();
        // ... 配置 ...
        return new ChromeDriver(options);
    }
    
    private void recoverApplicationState() {
        // 恢复到之前的页面状态
        get("https://example.com/login");
        
        // 重新登录或其他状态恢复
        // ...
        
        System.out.println("应用状态已成功恢复");
    }
}
 


网站公告

今日签到

点亮在社区的每一天
去签到