从内存中释放Selenium chromedriver.exe

从内存中释放Selenium chromedriver.exe,selenium,selenium-webdriver,selenium-chromedriver,Selenium,Selenium Webdriver,Selenium Chromedriver,我设置了一个python代码来运行Seleniumchromedriver.exe。在运行结束时,我使用browser.close()关闭实例。(browser=webdriver.Chrome())我认为它应该从内存中释放chromedriver.exe(我在Windows 7上)。但是,每次运行后,内存中都会保留一个chromedriver.exe实例。我希望有一种方法可以用python编写一些东西来终止chromedriver.exe进程。显然,browser.close()不起作用。谢谢

我设置了一个python代码来运行Selenium
chromedriver.exe
。在运行结束时,我使用
browser.close()
关闭实例。(
browser=webdriver.Chrome()
)我认为它应该从内存中释放
chromedriver.exe
(我在Windows 7上)。但是,每次运行后,内存中都会保留一个
chromedriver.exe
实例。我希望有一种方法可以用python编写一些东西来终止
chromedriver.exe
进程。显然,
browser.close()
不起作用。谢谢。

浏览器。关闭()将只关闭当前的chrome窗口


browser.quit()
应该关闭所有打开的窗口,然后退出webdriver。

根据Selenium API,您确实应该调用
browser.quit()
,因为此方法将关闭所有窗口并终止进程。您仍应使用
browser.quit()

然而:在我的工作场所,我们注意到在Java平台上执行chromedriver测试时出现了一个巨大的问题,在Java平台上,chromedriver.exe实际上仍然存在,即使在使用
browser.quit()
。为了解决这个问题,我们创建了一个类似于下面这个文件的批处理文件,它只是强制关闭进程

杀死chromedriver.bat

@echo off
rem   just kills stray local chromedriver.exe instances.
rem   useful if you are trying to clean your project, and your ide is complaining.

taskkill /im chromedriver.exe /f

由于chromedriver.exe不是一个庞大的程序,也不会消耗太多内存,所以您不必每次都运行它,但只有当它出现问题时才运行。例如,在Eclipse中运行Project->Clean时。

这有点奇怪,但对我来说很有效。我也遇到了类似的问题,在深入挖掘之后,当我点击
WebDriver.Quit()
时,我发现浏览器中仍有一个UI操作(URL加载等)


我的解决方案(尽管非常讨厌)是在调用Quit()之前添加一个3秒的
Sleep()

理论上,调用browser.Quit将关闭所有浏览器选项卡并终止进程

然而,在我的例子中,我无法做到这一点——因为我并行运行多个测试,所以我不想通过一个测试关闭其他窗口。因此,当我的测试完成运行时,仍有许多“chromedriver.exe”进程在运行

为了克服这个问题,我编写了一个简单的清理代码(C#):


我知道这是一个老生常谈的问题,但我想我应该分享一下对我有用的东西。我在使用Eclipse时遇到了问题——它不会杀死进程,因此在使用Eclipse runner测试代码之后,我有一堆虚拟进程

我的解决方案是以管理员身份运行Eclipse。那帮我修好了。Windows似乎不允许Eclipse关闭它产生的进程。

代码c#

//Calling close and then quit will kill the driver running process.


driver.close();

driver.quit();
使用系统诊断

使用制度管理

        public void KillProcessAndChildren(string p_name)
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher
          ("Select * From Win32_Process Where Name = '"+ p_name +"'");

        ManagementObjectCollection moc = searcher.Get();
        foreach (ManagementObject mo in moc)
        {

            try
            {
                KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
            }
            catch (ArgumentException)
            {
                break;
            }
        }

    }
这个函数呢

        public void KillProcessAndChildren(int pid)
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher
         ("Select * From Win32_Process Where ParentProcessID=" + pid);
        ManagementObjectCollection moc = searcher.Get();
        foreach (ManagementObject mo in moc)
        {

            try
            {
                KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
            }
            catch
            {
                break;
            }
        }

        try
        {
            Process proc = Process.GetProcessById(pid);

            proc.Kill();
        }
        catch (ArgumentException)
        {
            // Process already exited.
        }
    }
召唤

                try
            {
                 KillProcessAndChildren("chromedriver.exe");
            }
            catch
            {

            }

driver.quit()
之前使用
driver.close()
成功。我以前只使用了
driver.quit()

这个答案是如何在C中正确处理驱动程序#

如果您想在运行
ChromeDriver
IWebDriver.Dispose()后使用“适当”机制来“整理”

执行与释放、释放或重置非托管资源相关的应用程序定义的任务。 (继承自IDisposable。)

我通常在处理
IWebDriver

public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

    public void Dispose()
    {
        this.Driver.Dispose();
    }
}
然后像这样使用它:

using (var controller = new WebDriverController())
{
  //code goes here
}

希望这能为您节省一些时间

我有这个问题。我怀疑这是因为Serenity BDD和Selenium的版本。chromedriver进程在整个测试套件完成之前不会发布。只有97个测试,但如果97个进程占用了资源不多的服务器的内存,则可能会影响性能

为了解决这个问题,我做了两件事(这是针对windows的)

  • 在每次测试(用@before注释)之前,使用以下命令获取chromedriver进程的进程id(PID):

    List<Integer> pids = new ArrayList<Integer>();
    String out;
    Process p = Runtime.getRuntime().exec("tasklist /FI \"IMAGENAME eq chromedriver.exe*\"");
    BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((out = input.readLine()) != null) {
        String[] items = StringUtils.split(out, " ");
        if (items.length > 1 && StringUtils.isNumeric(items[1])) {
            pids.add(NumberUtils.toInt(items[1]));
        }
    }
    

  • 我来到这里最初认为这肯定会得到回答/解决,但在阅读了所有答案后,我有点惊讶,没有人试图将这三种方法结合起来:

    try
    {
        blah
    }
    catch
    {
        blah
    }
    finally
    {
        driver.Close(); // Close the chrome window
        driver.Quit(); // Close the console app that was used to kick off the chrome window
        driver.Dispose(); // Close the chromedriver.exe
    }
    

    我只是在这里寻找答案,并不打算提供答案。因此,上述解决方案仅基于我的经验。我在一个C#控制台应用程序中使用chrome驱动程序,只有在同时调用了所有三个方法之后,我才能清理延迟的进程。

    在Python中运行它时,我遇到了同样的问题,我必须手动运行“killall”命令来杀死所有进程。然而,当我使用Python实现驱动程序时,所有进程都消失了。Python解释器似乎在清理方面做得非常好

    以下是实施方案:

    class Browser:
        def __enter__(self):
            self.options = webdriver.ChromeOptions()
            self.options.add_argument('headless')
            self.driver = webdriver.Chrome(chrome_options=self.options)
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            self.driver.close()
            self.driver.quit()
    
    以及用法:

    with Browser() as browser:
        browser.navigate_to_page()
    
    对于Ubuntu/Linux用户:
    该命令是
    pkill
    killall
    <通常建议使用code>pkill
    ,因为在某些系统上,
    killall
    实际上会杀死所有进程。

    我在afterEach hooks的nightwatch.js中使用了以下内容

    afterEach: function(browser, done) {
        // performing an async operation
        setTimeout(function() {
            // finished async duties
            done();
            browser.closeWindow();
            browser.end();
        }, 200);
    }
    
    .closeWindow()只是简单地关闭窗口。(但不适用于打开的多个窗口)。
    而.end()结束所有剩余的chrome进程。

    从命令行杀死多个进程 首先需要打开命令提示符,然后使用具有以下语法的taskkill命令:

    taskkill /F /IM <processname.exe> /T
    

    我正在将量角器与directConnect一起使用。禁用“-no sandbox”选项为我解决了这个问题

    // Capabilities to be passed to the webdriver instance.
    capabilities: {
      'directConnect': true,
      'browserName': 'chrome',
      chromeOptions: {
          args: [
            //"--headless",
            //"--hide-scrollbars",
            "--disable-software-rasterizer",
            '--disable-dev-shm-usage',
            //"--no-sandbox",
            "incognito",
            "--disable-gpu",
            "--window-size=1920x1080"]
      }
    },
    
    Python代码:
    因此,您可以使用以下选项:

    driver.close()
    
    关闭浏览器(模拟点击关闭按钮)

    退出浏览器(模拟选择退出选项)

    退出浏览器(尝试关闭每个选项卡,然后退出)

    但是,如果您仍然遇到挂起实例的问题(就像我一样),那么您可能还想杀死该实例。为了做到这一点,您需要chrome的PID
    taskkill /F /IM iexplore.exe
    
    // Capabilities to be passed to the webdriver instance.
    capabilities: {
      'directConnect': true,
      'browserName': 'chrome',
      chromeOptions: {
          args: [
            //"--headless",
            //"--hide-scrollbars",
            "--disable-software-rasterizer",
            '--disable-dev-shm-usage',
            //"--no-sandbox",
            "incognito",
            "--disable-gpu",
            "--window-size=1920x1080"]
      }
    },
    
    try:
        # do my automated tasks
    except:
        pass
    finally:
        driver.close()
        driver.quit()
    
    driver.close()
    
    driver.quit()
    
    driver.dispose()
    
    import os
    import signal 
    driver = webdriver.Chrome()
    driver.get(('http://stackoverflow.com'))
    
    def get_pid(passdriver):
        chromepid = int(driver.service.process.pid)
        return (chromepid)
    
    def kill_chrome(thepid)
        try:
            os.kill(pid, signal.SIGTERM)
            return 1
        except:
            return 0
    
    print ("Loaded thing, now I'mah kill it!")
    try:
        driver.close()
        driver.quit()
        driver.dispose()
    except:
        pass
    
    kill_chrome(chromepid)
    
     public class WebDriverCleaner
    {
    
        public static void CloseWebDriver(IModule app)
        {
            try
            {
                if (app?.GetDriver() != null)
                {
                    app.GetDriver().Close();
                    Thread.Sleep(3000); // Gives time for everything to close before quiting
                    app.GetDriver().Quit();
                    app.GetDriver().Dispose();
                    KillProcessAndChildren("chromedriver.exe"); // One more to make sure we get rid of them chromedrivers.
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
    
        public static void KillProcessAndChildren(string p_name)
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher
                ("Select * From Win32_Process Where Name = '" + p_name + "'");
    
            ManagementObjectCollection moc = searcher.Get();
            foreach (ManagementObject mo in moc)
            {
                try
                {
                    KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
                }
                catch (ArgumentException)
                {
                    break;
                }
            }
    
        }
    
    
        public static void KillProcessAndChildren(int pid)
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
            ManagementObjectCollection moc = searcher.Get();
    
            foreach (ManagementObject mo in moc)
            {
                try
                {
                    KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
                }
                catch
                {
                    break;
                }
            }
    
            try
            {
                Process proc = Process.GetProcessById(pid);
                proc.Kill();
            }
            catch (ArgumentException)
            {
                // Process already exited.
            }
        }
    
    }
    
        ChromeOptions chromeOptions = new ChromeOptions();
        ChromeDriver driver = new ChromeDriver(chromeOptions);
        // .. do stuff ..
        driver.quit()
    
        ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
        ChromeOptions chromeOptions = new ChromeOptions();
        ChromeDriver driver = new ChromeDriver(driverService, chromeOptions);
        // .. do stuff ..
        driver.quit()
    
    @AfterTest
    public void tearDown() {
        driver.quit();
        driver = null;
    }
    
    import org.openqa.selenium.os.WindowsUtils;
    
     WindowsUtils.killByName("chromedriver.exe") // any process name you want
    
    driver.close()
    driver.quit()
    
    opts.addArguments(...args, 'custompid' + randomId());
    
    await this.driver.close()
    await this.driver.quit()
    
    spawn(`kill $(ps aux | grep ${RANDOM_PID_HERE} | grep -v "grep" | awk '{print $2}')`).on('error', e => { /* ignores when grep returns empty */ })