从内存中释放Selenium chromedriver.exe

时间:2014-01-23 22:40:48

标签: selenium selenium-webdriver selenium-chromedriver

我设置了一个python代码来运行Selenium chromedriver.exe。在运行结束时,我browser.close()关闭实例。 (browser = webdriver.Chrome())我相信它应该从内存中释放chromedriver.exe(我在Windows 7上)。但是,每次运行后,内存中仍有一个chromedriver.exe实例。我希望有一种方法可以在python中编写一些东西来杀死chromedriver.exe进程。显然browser.close()不做这项工作。感谢。

25 个答案:

答案 0 :(得分:63)

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

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

kill_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。

答案 1 :(得分:27)

browser.close()将仅关闭当前的Chrome窗口。

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

答案 2 :(得分:14)

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

然而,在我的情况下,我无法做到这一点 - 因为我并行运行多个测试,我不想进行一次测试来关闭其他人的窗口。因此,当我的测试完成运行时,仍然有许多“chromedriver.exe”进程在运行。

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

Process[] chromeDriverProcesses =  Process.GetProcessesByName("chromedriver");

foreach(var chromeDriverProcess in chromeDriverProcesses)
{
     chromeDriverProcess.Kill();
}

答案 3 :(得分:9)

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

答案 4 :(得分:7)

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


driver.close();

driver.quit();

答案 5 :(得分:5)

这有点奇怪,但对我有用。我有类似的问题,经过一些挖掘后,我发现当我点击WebDriver.Quit()时,浏览器中仍然存在UI动作(URL加载等)。

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

答案 6 :(得分:4)

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

如果您想在运行ChromeDriver you should use IWebDriver.Dispose();

之后使用“适当”机制来“整理”
  

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

我通常在处理IDisposable

的类上实现IWebDriver
public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

    public void Dispose()
    {
        this.Driver.Dispose();
    }
}

并使用它:

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

希望这能节省你一些时间

答案 7 :(得分:3)

代码c#

使用System.Diagnostics;

使用System.Management;

        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
            {

            }

答案 8 :(得分:2)

在Python中运行它时遇到了同样的问题,我不得不手动运行'killall'命令来杀死所有进程。然而,当我使用Python context management protocol实现驱动程序时,所有进程都消失了。似乎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()

答案 9 :(得分:1)

您应该在退出之前先申请

driver.close()
driver.quit()

答案 10 :(得分:1)

因此,您可以使用以下内容:

driver.close()

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

driver.quit()

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

driver.dispose()

退出浏览器(尝试关闭每个标签,然后退出)

但是,如果您 STILL 遇到挂起实例的问题(就像我以前一样),您可能还想杀死该实例。为此,您需要Chrome实例的PID。

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)

如果那之后还有一个Chrome实例,我会吃掉我的帽子。 :(

答案 11 :(得分:1)

Python代码:

try:
    # do my automated tasks
except:
    pass
finally:
    driver.close()
    driver.quit()

答案 12 :(得分:1)

从命令行杀死多个进程 您需要做的第一件事是打开命令提示符,然后使用具有以下语法的taskkill命令:

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

这些参数将强制终止与您指定的可执行文件名称匹配的所有进程。例如,要终止所有iexplore.exe进程,我们将使用:

taskkill /F /IM iexplore.exe

enter image description here

答案 13 :(得分:1)

我在afterEach挂钩中的nightwatch.js中使用了以下内容。

afterEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
        // finished async duties
        done();
        browser.closeWindow();
        browser.end();
    }, 200);
}

.closeWindow()只是简单地关闭窗口。 (但不适用于打开的多个窗口)。 .end()结束所有剩余的chrome进程。

答案 14 :(得分:1)

我知道这有点老问题,但我想我会分享对我有用的东西。我遇到了Eclipse的问题 - 它不会杀死进程,因此在使用Eclipse运行程序测试代码后,我有一堆幻像进程。

我的解决方案是以管理员身份运行Eclipse。这为我解决了这个问题。似乎Windows不允许Eclipse关闭它产生的进程。

答案 15 :(得分:0)

还有另一种方法仅适用于Windows,但现在已弃用。它适用于早期的硒版本(适用于3.11.0版本)。

import org.openqa.selenium.os.WindowsUtils;

 WindowsUtils.killByName("chromedriver.exe") // any process name you want

答案 16 :(得分:0)

我只是在每次测试中都使用如下方法tearDown(),我一点都没有问题。

@AfterTest
public void tearDown() {
    driver.quit();
    driver = null;
}

退出驱动程序实例后,通过driver = null将其从缓存中清除

希望回答问题

答案 17 :(得分:0)

所以,没有什么对我有用。我最终做的是在我的 addArguments 上设置一个唯一的 ID 来启动 chromedriver,然后当我想退出时,我会做这样的事情:

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 */ })

丑陋的 af,但这是唯一对我有用的方法。

答案 18 :(得分:0)

在3.141.0版上观察到

如果仅使用ChromeOptions初始化ChromeDriver,则quit()不会关闭chromedriver.exe。

    ChromeOptions chromeOptions = new ChromeOptions();
    ChromeDriver driver = new ChromeDriver(chromeOptions);
    // .. do stuff ..
    driver.quit()

如果您创建并传入ChromeDriverService,则quit()将正确关闭chromedriver.exe。

    ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
    ChromeOptions chromeOptions = new ChromeOptions();
    ChromeDriver driver = new ChromeDriver(driverService, chromeOptions);
    // .. do stuff ..
    driver.quit()

答案 19 :(得分:0)

我查看了所有回复并测试了所有回复。我几乎将它们全部编译为一个“安全关闭”。这在c#

请注意,您可以将参数从IModule应用更改为实际驱动程序的参数。

 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.
        }
    }

}

答案 20 :(得分:0)

  • 确保您将Driver实例获取为Singleton
  • 然后结束申请
  • driver.close()
  • driver.quit()

注意:现在,如果我们看到任务管理器,您将不会发现任何驱动程序或chrome进程仍挂起

答案 21 :(得分:0)

我正在使用带有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"]
  }
},

答案 22 :(得分:0)

对于Ubuntu / Linux用户: -  该命令可以是pkillkillall。通常建议使用pkill,因为在某些系统上,killall实际上会终止所有进程。

答案 23 :(得分:0)

我最初来到这里当然认为这肯定会得到解答/解决但是在阅读完所有答案之后我有点惊讶没有人试图将所有三种方法放在一起:

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驱动程序,只有在同时调用所有三种方法后才能清理延迟进程。

答案 24 :(得分:0)

我有这个问题。我怀疑它是由于Serenity BDD和Selenium的版本。在整个测试套件完成之前,chromedriver进程永远不会发布。只有97个测试,但有97个进程占用了服务器的内存,没有多少资源可能会对性能产生影响。

为了解决我做了两件事(这是针对Windows的)。

  1. 在每次测试之前(使用@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]));
        }
    }
    
  2. 每次测试后(使用@After注释)使用以下命令终止PID:

    Runtime.getRuntime().exec("taskkill /F /PID " + pid);