випустити Selenium chromedriver.exe з пам'яті


102

Я встановив код python для запуску Selenium chromedriver.exe. Наприкінці запуску я маю browser.close()закрити екземпляр. ( browser = webdriver.Chrome()) Я вважаю, що це повинно звільнитися chromedriver.exeз пам'яті (я в Windows 7). Однак після кожного запуску chromedriver.exeв пам’яті залишається один екземпляр. Я сподіваюся, що є спосіб я написати щось у python, щоб вбити chromedriver.exeпроцес. Очевидно, browser.close()це не спрацьовує. Дякую.


Підсумок ... вам доведеться якось вбивати процес, тому що дизайнери не створили його. Усі інші способи можуть залишити процес запущеним, і цього достатньо, щоб гарантувати вбивство.
Stephen G

Відповіді:


73

на API Selenium, ви дійсно повинні зателефонувати, browser.quit()оскільки цей метод закриє всі вікна та вбиває процес. Ви все одно повинні використовувати browser.quit().

Однак : На моєму робочому місці ми помітили величезну проблему при спробі виконання тестів Chromeedriver на платформі Java, де Chromeedriver.exe насправді існує навіть після використання browser.quit(). Щоб протистояти цьому, ми створили пакетний файл, подібний до цього нижче, що просто змушує закрити процеси.

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 не є величезною програмою і не займає багато пам’яті, вам не слід це запускати кожен раз, а лише тоді, коли це представляє проблему. Наприклад, при запуску Project-> Clean in Eclipse.


3
Я не можу одержати жодної відповіді, яка рекомендує вбивати процеси, не зазначивши також правильного способу нормального завершення цих процесів. Якщо ви правильно використовуєте quitметод, це не повинно бути проблемою. Насильницькі процеси вбивства повинні бути лише в крайньому випадку, і ваша відповідь повинна відображати це.
JimEvans

17
Дивіться єдину проблему з цим, це те, що коли ви налагоджуєте і вбиваєте виконання - процес все ще залишається. Навіть якщо натиснути його, Xвін все одно залишається. це ТІЛЬКА причина цього пакетного файлу. Очевидно quit, в цьому моєму прикладі є шлях, якщо ви налагодите і зупините виконання - це ніколи не досягне quit.
ddavison

3
Я відповідаю на одне із запитань: I hope there is a way I can write something to kill the chromedriver.exe process.. і так, це приємно! Java не робить цього
ddavison

3
Залежно від тестової рамки, яку ви використовуєте, ви також можете закінчити фантомні процеси, якщо тести не вдаються до її "налаштування". NUnit, наприклад, не буде дзвонити , якщо що - то метод TestFixtureTearDown знаходиться в TestFixtureSetup методи зазнають невдачі -> створити браузер, зробити деякі речі, а потім запустити тест. Якщо щось піде не так, коли "робиш якісь речі", це все, процес залишається там.
Арран

1
Якщо ви використовуєте інтерфейс DriverService, затримайтеся на сервісі, поки не закінчите роботу з драйвером, і зателефонуйте також DriverService.stop (). Для мене driver.quit () було недостатньо, тому що я також використовував DriverService.
Кімбол Робінсон

38

browser.close() закриє лише поточне хромоване вікно.

browser.quit() слід закрити всі відкриті вікна, а потім вийти з веб-драйвера.


9
Дякую Річард. browser.quit()закрив усі відкриті вікна. Але Chromeedriver.exe не вийшов. І з'явилося повідомлення про помилку 'InvalidURL: nonnumeric port:' port ''.
KLI

5
ГАРАЗД. Я спробував browser = webdriver.Firefox(). І те, browser.close()і browser.quit()закрили б усі вікна та звільнили пам'ять. Однак Chromeedriver не зробив би цього.
KLI

Гей, KLI. Тут, де я працюю, ми помітили такі самі точні речі, що відбуваються з хромодаром. Ось чому у нас є пакетний файл, який ми запускаємо лише тоді, коли нам потрібно. chromedriver.exe - це не великий процес, але він створює проблему, коли ми намагаємося запустити Project-> Clean, наприклад
ddavison

17

Теоретично, виклик браузера. Цитата закриє всі вкладки браузера і знищить процес.

Однак у моєму випадку я не зміг цього зробити - оскільки я паралельно працював з декількома тестами, я не хотів одного тесту закривати вікна для інших. Тому, коли мої тести закінчуються, залишається багато процесів "chromedriver.exe".

Щоб подолати це, я написав простий код очищення (C #):

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

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

Це не допомогло. Процес не вбивається, коли він працює під Java
Денис Корейба

@DenisKoreyba: Я не думаю, що мова реалізації повинна змінити поведінку. В ОС Windows, коли процес не утримується ніким - ви можете вбити його (навіть якщо він відбувся, ви можете примусити і вбити). Ви намагаєтесь вбити його після закриття вкладки (-ів) браузера?
Іллідан

Для цього я використовую C #, що я сказав bout java, що процес TeamCity запускається під ним. Відповідаючи на ваше запитання: так, спочатку я викликаю Dispose (), а потім ваш код.
Денис Корейба

Це не працює на драйвері Chrome, принаймні версія 2.21. Процес вбивається, але вікно консолі все ще відображається, ймовірно, тому, що деякий дочірній процес зберігається. відповідь альханана нижче працює.
Мовчазний прикордонник

Я вставив вищезгаданий код очищення в розділ AssemblyCleanup BaseDriverClass. Як я можу переконатися, що процес chromedriver.exe був фактично вбитий?
monkrus

12

Я мав успіх при використанні driver.close()раніше driver.quit(). Раніше я лише використовував driver.quit().


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


driver.close();

driver.quit();

Це не спрацювало для мене. Виклик драйвера.close (); закриє браузер і встановить драйвер на нуль. І тоді немає сенсу викликати driver.quit (); як це викине нульовий виняток.
Приянка

реалізація має деякі зміни в поточному селені, можливо, вам не знадобиться quit (), якщо процес знищено. Переконайтесь, що коли ви це зробите, у вашого менеджера завдань не повинно бути вбито браузерний процес.
Шантону

7

Це якось дивно, але це працює для мене. У мене була подібна проблема, після деякого копання я виявив, що в браузері все ще відбувається дія інтерфейсу (завантаження URL-адреси чи так), коли я натиснув WebDriver.Quit().

Для мене (хоч і дуже неприємно) було рішення додати Sleep()3 секунди до виклику Quit ().


3
Дякую, це насправді спрацювало і для мене. Я використовував WebDriver.Quit()і раніше, але іноді це залишало один процес chrome.exe живим. Також я думаю, що це відбувається не у всіх операційних системах.
Гренгас

1
Це працювало і для мене! Це може змусити вас відчути себе трохи брудною, але іноді випадковою ниткою. Сон, здається, те, що лікар призначив для тестів на інтерфейс користувача.
Ден Чшарпстер

Те саме для мене, закрити самостійно або вийти самостійно, залишивши процес водія позаду. Робимо обидва добре прибрані.
бал

Чудово! Це працювало і для мене. Я додав Task.Delay (TimeSpan.FromSeconds (3)); перед викликом driver.Quit () , і це закриває всі файли chromedriver.exe
Приянка

5

Ця відповідь - як правильно утилізувати водій у C #

Якщо ви хочете використовувати "належний" механізм, який слід використовувати для "прибирання" після запуску, ChromeDriver ви повинні використовувати 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
}

Сподіваюсь, це заощадить певний час


6
Я можу підтвердити, що проблеми з цією стратегією ще є! Я використовую API WebDriver Selenium .NET v3.13.1.0, мій екземпляр Chrome оновлюється, як і моя Windows 10 ... Я використовую ChromeDriver (який реалізовує IDisposable за спадщиною) так: using (var driver = new ChromeDriver()) { //my code here } Іноді, не завжди, "щось" (не знаю, що ??) відбувається, і chromedriver.exeвсе ще не видається за словами мого менеджера завдань.
Hauns TM

Так, це не усуває помилок і для мене.
Pxtl

4

Вбивство декількох процесів з командного рядка Перше, що вам потрібно буде зробити, це відкрити командний рядок, а потім використовувати команду taskkill із таким синтаксисом:

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

Ці параметри насильно вбивають будь-який процес, що відповідає імені виконуваного файлу, який ви вказуєте. Наприклад, щоб знищити всі процеси iexplore.exe, ми використовуємо:

taskkill /F /IM iexplore.exe

введіть тут опис зображення


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
            {

            }

Я застосував ваш код як остаточне очищення. Поки це, здається, працює. Хороша робота!
Exzile

2

У мене була така ж проблема, коли я запускав її в 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()

2

Отже, ви можете використовувати наступне:

driver.close()

Закрийте веб-переглядач (емуляція натискання кнопки "Закрити")

driver.quit()

Закрийте веб-переглядач (емулює вибір параметра "Вийти")

driver.dispose()

Вийдіть із браузера (намагається закрити кожну вкладку, а потім вийдіть)

Однак якщо ви все ще стикаєтеся з проблемами з висячими екземплярами (як я), ви також можете вбити екземпляр. Для цього вам потрібен 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)

Якщо після цього залишиться хромований екземпляр, я з'їм свою шапку. :(



1

Я знаю, що це дещо старе питання, але я думав, що поділюсь тим, що працювало на мене. У мене виникли проблеми з Eclipse - це не знищило б процеси, і тому у мене з'явилася купа фантомних процесів, які висіли навколо після тестування коду за допомогою бігуна Eclipse.

Моє рішення було запустити Eclipse як адміністратор. Це зафіксувало це для мене. Здається, що Windows не дозволила Eclipse закрити процес, який він породив.


Це має багато сенсу, але в моєму випадку воно не спрацювало, chromedriver.exeзалишається видимим серед процесів диспетчера завдань незалежно від того, я запускаю Eclipse як адміністратор або звичайний користувач. Можливо, що в моєму випадку це проблема, оскільки chromedriver.exeце 32 біт, а мій JRE - 64 біт. Eclipse Neon.1a (4.6.1), Windows 8.1 Pro 64 біт, Java 1.8.0_92-b14.
SantiBailors

1

Я використовував нижче в nightwatch.js в гачках AfterEach.

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

.closeWindow () просто закриває вікно. (Але робота над кількома вікнами відкрита). Тоді як .end () закінчує всі хромовані процеси, що залишилися.


0

У мене це питання. Я підозрюю, що це пов'язано з версіями Serenity BDD і Selenium. Процес Chromeedriver ніколи не випускається, поки не закінчиться весь тестовий набір. Існує лише 97 тестів, але 97 процесів з'їдають пам'ять сервера, який не має великих ресурсів, може впливати на продуктивність.

Для звернення я зробив 2 речі (це характерно для Windows).

  1. перед кожним тестом (з анотацією на @Before) отримують ідентифікатор процесу (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);
    

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 #, і я міг очистити тривалі процеси лише після виклику всіх трьох методів разом.


0

Для користувачів Ubuntu / Linux: - команда є pkillабо killall. pkillзагалом рекомендується, оскільки в деяких системах killallфактично вбиваються всі процеси.


0

Я використовую Protractor з 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"]
  }
},

0
  • Переконайтесь, що ви отримуєте екземпляр драйвера як Singleton
  • потім застосувати в кінці
  • driver.close ()
  • driver.quit ()

Примітка. Тепер, якщо ми побачимо диспетчер завдань, ви не знайдете жодного драйвера чи хромованого процесу, який все ще висить


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

}

0

Спостерігається у версії 3.141.0:

Якщо ви ініціалізуєте ChromeDriver лише з ChromeOptions, quit () не закриє Chromeedriver.exe.

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

Якщо ви створюєте та передаєте в ChromeDriverService, quit () закриє Chromeedriver.exe правильно.

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

Це рішення в Java, я вважаю. Принаймні, це спрацювало для мене
Ізабель Т.

0

Я просто використовую у кожному тесті метод tearDown () як наступний, і у мене зовсім немає проблем.

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

Після виходу з екземпляра драйвера очистіть його з кеша за допомогою драйвера = null

Сподіваюсь на відповідь на запитання


0

Є ще один спосіб, який працює лише для Windows, але зараз він застарілий. він працює для попередніх випусків селену (працює на версії 3.11.0).

import org.openqa.selenium.os.WindowsUtils;

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

0

Ви повинні подати заявку раніше, ніж вийти

driver.close()
driver.quit()

Не працює, chromedriver.exe все ще відкритий
Pedro Joaquín

1
--Edit -> Видалено "driver.close ()", і воно спрацювало
Pedro Joaquín
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.