web-dev-qa-db-fra.com

libérer Selenium chromedriver.exe de la mémoire

J'ai configuré un code python pour exécuter Selenium chromedriver.exe. À la fin de l'exécution, j'ai browser.close() pour fermer l'instance. (browser = webdriver.Chrome()) Je crois qu'il devrait libérer chromedriver.exe de la mémoire (je suis sous Windows 7). Cependant, après chaque exécution, il reste une instance chromedriver.exe en mémoire. J'espère qu'il est possible d'écrire quelque chose en python pour tuer le processus chromedriver.exe. De toute évidence, browser.close() ne fait pas le travail. Merci.

74
KLI

selon l’API Selenium, vous devez vraiment appeler browser.quit() car cette méthode ferme toutes les fenêtres et tue le processus. Vous devriez toujours utiliser browser.quit()

Cependant : Sur mon lieu de travail, nous avons constaté un énorme problème lorsque nous essayons d'exécuter des tests chromedriver sur la plate-forme Java, où chromedriver.exe existe toujours même après l'utilisation de browser.quit(). Pour contrer cela, nous avons créé un fichier de commandes similaire à celui ci-dessous, qui oblige simplement à fermer les processus.

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 n'étant pas un programme énorme et ne consommant pas beaucoup de mémoire, vous ne devriez pas avoir à l'exécuter à chaque fois, mais seulement quand cela pose un problème. Par exemple, lorsque vous exécutez Project-> Clean dans Eclipse.

59
sircapsalot

browser.close() ne ferme que la fenêtre chromée actuelle.

browser.quit() devrait fermer toutes les fenêtres ouvertes, puis quitter WebDriver.

25
Richard

Théoriquement, appeler browser.Quit ferme tous les onglets du navigateur et met fin au processus.

Cependant, dans mon cas, je n’étais pas capable de le faire - étant donné que j’exécutais plusieurs tests en parallèle, je ne voulais pas faire un test pour fermer les fenêtres aux autres. Par conséquent, lorsque mes tests sont terminés, il reste encore de nombreux processus "chromedriver.exe" en cours d'exécution.

Afin de surmonter cela, j'ai écrit un code de nettoyage simple (C #):

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

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

J'ai eu du succès en utilisant driver.close() avant driver.quit(). J'utilisais auparavant uniquement driver.quit().

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

    }

et cette fonction

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

Appel

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

            }
3
aalhanane

Aucune des réponses ci-dessus n'est totalement correcte

Si vous souhaitez utiliser un mécanisme «approprié» qui devrait être utilisé pour «ranger» après l'exécution de ChromeDriver, vous devez utiliserIWebDriver.Dispose(); 

Exécute des tâches définies par l'application associées à la libération, à la libération ou à la réinitialisation de ressources non gérées . (Hérité de IDisposable.)

J'implémente généralement IDisposable sur un cours traitant de IWebDriver 

public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

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

et l'utiliser comme:

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

J'espère que cela vous fait gagner du temps

3

C'est un peu étrange mais ça marche pour moi. J'ai eu le même problème. Après quelques recherches, j'ai constaté qu'il restait une action d'interface utilisateur dans le navigateur (chargement de l'URL ou autre), lorsque j'ai appuyé sur WebDriver.Quit().

La solution pour moi (bien que très méchant) a été d’ajouter un Sleep() de 3 secondes avant d’appeler Quit ().

3
Alpana Chauhan

J'avais le même problème lors de son exécution en Python et je devais exécuter manuellement la commande "killall" pour tuer tous les processus. Cependant, lorsque j'ai implémenté le pilote à l'aide du protocole de gestion de contexte Python , tous les processus avaient disparu. Il semble que l'interprète Python fait un très bon travail de nettoyage. 

Voici l'implémentation:

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

Et l'usage:

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

Donc, vous pouvez utiliser les éléments suivants:

driver.close()

Ferme le navigateur (émule en appuyant sur le bouton de fermeture)

driver.quit()

Quitter le navigateur (émule en sélectionnant l'option quitter)

driver.dispose()

Quitter le navigateur (tente de fermer chaque onglet, puis quitte)

Cependant, si vous rencontrezTOUJOURSdes problèmes avec les instances suspendues (comme ce fut mon cas), vous voudrez peut-être également supprimer l'instance. Pour ce faire, vous avez besoin du PID de l'instance de chrome.

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)

S'il reste une instance chromée après cela, je mangerai mon chapeau. :(

1
Rue Lazzaro

J'ai utilisé le ci-dessous dans nightwatch.js dans les crochets afterEach.

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

.closeWindow () ferme simplement la fenêtre. (Mais ne fonctionnera pas pendant plusieurs fenêtres ouvertes) . Considérant que .end () termine tous les processus chrome restants.

1
Simon Correia

Code python:

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

Je sais que la question est un peu ancienne, mais je pensais partager ce qui a fonctionné pour moi. J'avais des problèmes avec Eclipse - cela ne tuerait pas les processus. J'ai donc eu un tas de processus fantômes qui traînaient après avoir testé le code à l'aide du programme d'exécution Eclipse.

Ma solution consistait à exécuter Eclipse en tant qu'administrateur. Cela a réglé le problème pour moi. Il semble que Windows n'autorisait pas Eclipse à fermer le processus généré.

0
forresthopkinsa
  • Assurez-vous que vous obtenez l'instance de pilote en tant que Singleton
  • puis appliquer à la fin 
  • driver.close ()
  • driver.quit ()

Remarque: Maintenant, si nous voyons le gestionnaire de tâches, vous ne trouverez aucun pilote ou processus chrome toujours suspendu.

0
sarath

Je suis arrivé ici au début en pensant sûrement que cela aurait été résolu/résolu, mais après avoir lu toutes les réponses, j'ai été un peu surpris que personne n'ait essayé de réunir les trois méthodes:

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
}

J'étais seulement ici pour chercher des réponses et je n'avais pas l'intention d'en fournir une. Donc, la solution ci-dessus est basée sur mon expérience uniquement. J'utilisais le pilote chrome dans une application pour console C # et je n'ai pu nettoyer les processus en cours qu'après avoir appelé les trois méthodes ensemble.

0
Louie Bao

J'ai examiné toutes les réponses et les ai toutes testées. Je les ai presque toutes compilées en une "fermeture de sécurité". Ceci en c #

REMARQUE: vous pouvez modifier le paramètre de l'application IModule par celui du pilote actuel.

 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

Pour les utilisateurs Ubuntu/Linux: - la commande est soit pkill, soit killall. pkill est généralement recommandé, car sur certains systèmes, killall va tuer tous les processus.

0
Manmohan_singh

Supprimer plusieurs processus à partir de la ligne de commande La première chose à faire est d’ouvrir une invite de commande, puis d’utiliser la commande taskkill avec la syntaxe suivante:

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

Ces paramètres vont forcer la mort de tout processus correspondant au nom de l'exécutable que vous spécifiez. Par exemple, pour tuer tous les processus iexplore.exe, nous utiliserions:

taskkill /F /IM iexplore.exe

 enter image description here

0
sumit kumar pradhan

J'utilise Protractor avec directConnect. La désactivation de l'option "--no-sandbox" a résolu le problème pour moi.

// 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

J'ai ce problème. Je soupçonne que cela est dû à la version de Serenity BDD et Selenium. Le processus chromedriver n'est jamais libéré avant la fin de la suite de tests. Il n'y a que 97 tests, mais le fait d'avoir 97 processus consomme de la mémoire sur un serveur disposant de peu de ressources et pouvant affecter les performances.

Pour aborder j'ai fait 2 choses (cela est spécifique à Windows).

  1. avant chaque test (annoté avec @Before), obtenez l'ID de processus (PID) du processus chromedriver avec:

    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. après chaque test (annoté avec @After), supprimez le PID avec:

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