wake-up-neo.com

geben Sie Selenium chromedriver.exe aus dem Speicher frei

Ich habe einen Python-Code eingerichtet, um Selenium chromedriver.exe auszuführen. Am Ende des Laufs habe ich browser.close(), um die Instanz zu schließen. (browser = webdriver.Chrome()) Ich glaube, es sollte chromedriver.exe aus dem Speicher freigeben (ich bin unter Windows 7). Nach jedem Durchlauf verbleibt jedoch eine chromedriver.exe-Instanz im Speicher. Ich hoffe, es gibt eine Möglichkeit, etwas in Python zu schreiben, um den chromedriver.exe-Prozess zu beenden. Offensichtlich erledigt browser.close() die Arbeit nicht. Vielen Dank.

74
KLI

per Selenium-API sollten Sie wirklich browser.quit() aufrufen, da diese Methode alle Fenster schließt und den Prozess abbricht. Sie sollten weiterhin browser.quit() verwenden. 

Allerdings : An meinem Arbeitsplatz haben wir ein großes Problem festgestellt, als ich versuchte, Chromedriver-Tests auf der Java-Plattform auszuführen, wobei die chromedriver.exe auch nach der Verwendung von browser.quit() tatsächlich noch vorhanden ist. Um dem entgegenzuwirken, haben wir eine Batchdatei erstellt, die der unten stehenden ähnelt und die Prozesse zum Schließen zwingt.

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

Da chromedriver.exe kein großes Programm ist und nicht viel Speicher benötigt, sollten Sie dies nicht jedes Mal ausführen müssen, sondern nur, wenn es ein Problem darstellt. Zum Beispiel beim Ausführen von Project-> Clean in Eclipse.

59
sircapsalot

browser.close() schließt nur das aktuelle Chrome-Fenster.

browser.quit() sollte alle geöffneten Fenster schließen und dann den Web-Treiber beenden.

25
Richard

Theoretisch wird beim Aufruf von browser.Quit alle Browser-Registerkarten geschlossen und der Prozess abgebrochen.

In meinem Fall war ich dazu jedoch nicht in der Lage - da ich mehrere Tests parallel durchführte, wollte ich keinen Test, um Fenster zu anderen zu schließen. Wenn meine Tests abgeschlossen sind, werden daher immer noch viele "chromedriver.exe" -Prozesse ausgeführt.

Um das zu überwinden, habe ich einen einfachen Bereinigungscode (C #) geschrieben:

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

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

Ich hatte Erfolg bei der Verwendung von driver.close() vor driver.quit(). Ich habe vorher nur driver.quit() verwendet.

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


driver.close();

driver.quit();
6
Shantonu

Code c #

using System.Diagnostics;

using 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;
            }
        }

    }

und diese Funktion

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

Berufung

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

            }
3
aalhanane

Keine der obigen Antworten ist vollständig korrekt

Wenn Sie einen "richtigen" Mechanismus verwenden möchten, der nach dem Ausführen von ChromeDriverzum Aufräumen verwendet werden soll, sollten SieIWebDriver.Dispose(); 

Führt von der Anwendung definierte Aufgaben aus, die mit dem Freigeben, Freigeben oder Zurücksetzen nicht verwalteter Ressourcen in Verbindung stehen . (Von IDisposable geerbt.)

Normalerweise implementiere ich IDisposable in einer Klasse, die sich mit IWebDriver beschäftigt. 

public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

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

und benutze es wie:

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

Ich hoffe, das erspart Ihnen etwas Zeit

3

Es ist irgendwie seltsam, aber es funktioniert für mich. Ich hatte ein ähnliches Problem. Nach einigem Suchen fand ich heraus, dass im Browser immer noch eine UI-Aktion (URL-Ladevorgang usw.) ausgeführt wurde, als ich WebDriver.Quit() drückte.

Die Lösung für mich (obwohl sehr böse) war, eine Sleep() von 3 Sekunden vor dem Aufruf von Quit () hinzuzufügen.

3
Alpana Chauhan

Ich hatte das gleiche Problem, als ich es in Python ausführte, und ich musste den Befehl 'killall' manuell ausführen, um alle Prozesse zu beenden. Bei der Implementierung des Treibers unter Verwendung des Python context management-Protokolls waren jedoch alle Prozesse weg. Es scheint, dass Python-Interpreter wirklich gute Arbeit leistet, um die Dinge aufzuräumen. 

Hier ist die Implementierung:

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()

Und die Verwendung:

with Browser() as browser:
    browser.navigate_to_page()
2
Wizard

Sie können also Folgendes verwenden:

driver.close()

Schließen Sie den Browser (emuliert die Schaltfläche "Schließen").

driver.quit()

Beenden Sie den Browser (emuliert die Auswahl der Beendigungsoption)

driver.dispose()

Beenden Sie den Browser (versucht, jeden Tab zu schließen, und dann zu beenden)

Wenn Sie jedochNOCHProbleme mit hängenden Instanzen haben (wie ich es war), möchten Sie möglicherweise auch die Instanz beenden. Dazu benötigen Sie die PID der Chrome-Instanz.

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)

Wenn danach eine Chrominstanz übrig ist, esse ich meinen Hut. :(

1
Rue Lazzaro

Ich habe die folgenden in nightwatch.js in afterEach-Hooks verwendet.

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

.closeWindow () schließt einfach das Fenster. (Funktioniert jedoch nicht für mehrere geöffnete Fenster) . Während .end () alle verbleibenden Chromprozesse beendet.

1
Simon Correia

Python-Code:

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

Ich weiß, das ist eine ziemlich alte Frage, aber ich dachte, ich würde teilen, was für mich funktioniert. Ich hatte Probleme mit Eclipse - das würde die Prozesse nicht töten, und so hatte ich eine Reihe von Phantom-Prozessen, nachdem ich den Code mit dem Eclipse-Läufer getestet hatte.

Meine Lösung bestand darin, Eclipse als Administrator auszuführen. Das hat es für mich behoben. Es scheint, dass Windows Eclipse nicht erlaubte, den von ihm erzeugten Prozess zu beenden.

0
forresthopkinsa
  • Stellen Sie sicher, dass Sie die Treiberinstanz als Singleton erhalten
  • dann am Ende anwenden 
  • driver.close ()
  • driver.quit ()

Hinweis: Wenn wir nun den Task-Manager sehen, werden Sie keinen Treiber oder Chrome-Prozess feststellen, der immer noch hängt

0
sarath

Ich kam zuerst hierher und dachte, dass dies sicher beantwortet/gelöst worden wäre, aber nachdem ich alle Antworten gelesen hatte, war ich etwas überrascht, dass niemand versuchte, alle drei Methoden zusammen zu nennen:

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
}

Ich war nur hier, um Antworten zu suchen, und hatte nicht vor, eine Antwort zu geben. Die obige Lösung basiert also nur auf meiner Erfahrung. Ich habe den Chrome-Treiber in einer C # -Konsolen-App verwendet und konnte die veralteten Prozesse erst bereinigen, nachdem alle drei Methoden zusammen aufgerufen wurden.

0
Louie Bao

Ich habe mir alle Antworten angesehen und sie alle getestet. Ich habe sie so ziemlich alle als Sicherheitsverschluss zusammengefasst. Dies in c #

HINWEIS: Sie können den Parameter von der IModule-App in den des tatsächlichen Treibers ändern.

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

}
0
Exzile

Für Ubuntu/Linux-Benutzer: - Der Befehl ist entweder pkill oder killall. pkill wird im Allgemeinen empfohlen, da killall auf einigen Systemen tatsächlich alle Prozesse abbricht.

0
Manmohan_singh

Mehrere Prozesse über die Befehlszeile abbrechen Als erstes müssen Sie eine Eingabeaufforderung öffnen und dann den Befehl taskkill mit der folgenden Syntax verwenden:

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

Diese Parameter beenden jeden Prozess, der mit dem Namen der von Ihnen angegebenen ausführbaren Datei übereinstimmt. Um beispielsweise alle iexplore.exe-Prozesse abzubrechen, verwenden wir:

taskkill /F /IM iexplore.exe

 enter image description here

0

Ich verwende Protractor mit directConnect. Das Deaktivieren der Option "--no-sandbox" hat das Problem für mich behoben.

// 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"]
  }
},
0
Georgi Ekimov

Ich habe dieses Problem. Ich vermute, es liegt an der Version von Serenity BDD und Selenium. Der Chromedriver-Prozess wird niemals freigegeben, bis die gesamte Testsuite abgeschlossen ist. Es gibt nur 97 Tests, aber mit 97 Prozessen kann der Speicher eines Servers belastet werden, der nicht über viele Ressourcen verfügt.

Um zu adressieren, habe ich 2 Dinge getan (dies ist spezifisch für Windows).

  1. vor jedem Test (kommentiert mit @Before) die Prozess-ID (PID) des Chromedriver-Prozesses mit

    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. nach jedem Test (kommentiert mit @After) töten Sie die PID mit:

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