lepaskan Selenium chromedriver.exe dari memori


102

Saya menyiapkan kode python untuk menjalankan Selenium chromedriver.exe. Di akhir proses, saya harus browser.close()menutup instance. ( browser = webdriver.Chrome()) Saya yakin itu harus dilepaskan chromedriver.exedari memori (saya menggunakan Windows 7). Namun setelah setiap proses dijalankan, ada satu chromedriver.execontoh yang tersisa di memori. Saya harap ada cara saya bisa menulis sesuatu dengan python untuk menghentikan chromedriver.exeproses. Jelas browser.close()tidak berhasil. Terima kasih.


Intinya ... Anda harus menghentikan proses entah bagaimana karena desainer tidak membangunnya. Semua cara lain mungkin membuat proses berjalan dan itu cukup untuk menjamin pembunuhan.
Stephen G

Jawaban:


73

per API Selenium, Anda benar-benar harus memanggil browser.quit()karena metode ini akan menutup semua jendela dan menghentikan proses. Anda tetap harus menggunakan browser.quit().

Namun : Di tempat kerja saya, kami menemukan masalah besar saat mencoba menjalankan pengujian chromedriver di platform Java, di mana chromedriver.exe sebenarnya masih ada bahkan setelah digunakan browser.quit(). Untuk mengatasi ini, kami membuat file batch yang mirip dengan yang di bawah ini, yang hanya memaksa proses ditutup.

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

Karena chromedriver.exe bukanlah program besar dan tidak menghabiskan banyak memori, Anda tidak perlu menjalankan ini setiap saat, tetapi hanya jika ada masalah. Misalnya saat menjalankan Project-> Clean in Eclipse.


3
Saya tidak dapat memaafkan jawaban apa pun yang merekomendasikan proses pembunuhan tanpa juga menyebutkan cara yang benar agar proses tersebut berakhir secara normal. Jika Anda menggunakan quitmetode ini dengan benar , ini seharusnya tidak menjadi masalah. Membunuh paksa proses seharusnya hanya menjadi pilihan terakhir, dan jawaban Anda harus mencerminkan hal itu.
JimEvans

17
Lihat satu-satunya masalah dengan ini, adalah ketika Anda men-debug, dan menghentikan eksekusi - prosesnya masih tetap. Bahkan jika Anda mengkliknya Xmasih tetap ada. itulah satu- satunya alasan untuk file batch ini. Jelas quitadalah cara untuk pergi, namun dalam contoh saya, jika Anda men-debug dan menghentikan eksekusi - itu tidak pernah mencapai quit.
ddavison

3
aku menjawab salah satu pertanyaan: I hope there is a way I can write something to kill the chromedriver.exe process.. dan ya, itu bagus! Java tidak melakukan itu
ddavison

3
Bergantung pada kerangka pengujian yang Anda gunakan, Anda mungkin juga akan berakhir dengan proses hantu yang tergeletak jika pengujian gagal dalam "penyiapan" -nya. NUnit, misalnya, tidak akan memanggil metode TestFixtureTearDown jika sesuatu dalam metode TestFixtureSetup gagal -> Anda membuat browser, melakukan beberapa hal, dan kemudian menjalankan pengujian. Jika ada yang tidak beres saat "Anda melakukan beberapa hal", itu saja, prosesnya tetap di sana.
Arran

1
Jika Anda menggunakan antarmuka DriverService, pertahankan layanan sampai Anda selesai dengan driver, dan panggil DriverService.stop () juga. Bagi saya, driver.quit () tidak cukup karena saya juga menggunakan DriverService.
Kimball Robinson

38

browser.close() hanya akan menutup jendela chrome saat ini.

browser.quit() harus menutup semua jendela yang terbuka, lalu keluar dari webdriver.


9
Terima kasih Richard. browser.quit()menutup semua jendela yang terbuka. Tapi chromedriver.exe tidak keluar. Dan ada pesan error 'InvalidURL: nonnumeric port:' port ''.
KLI

5
BAIK. Saya sudah mencoba browser = webdriver.Firefox(). Keduanya browser.close()dan browser.quit()akan menutup semua jendela dan melepaskan memori. Namun chromedriver tidak akan melakukan hal yang sama.
KLI

Hai KLI. Di sini tempat saya bekerja, kami memperhatikan hal yang persis sama terjadi dengan chromedriver. Inilah mengapa kami memiliki file batch yang hanya dijalankan saat kami membutuhkannya. chromedriver.exe bukanlah proses besar, tetapi ini menimbulkan masalah ketika kami mencoba menjalankan Project-> Clean misalnya
ddavison

17

Secara teoritis, memanggil browser.Quit akan menutup semua tab browser dan menghentikan proses.

Namun, dalam kasus saya, saya tidak dapat melakukan itu - karena saya menjalankan beberapa tes secara paralel, saya tidak ingin melakukan satu tes untuk menutup jendela ke yang lain. Oleh karena itu, ketika pengujian saya selesai berjalan, masih banyak proses "chromedriver.exe" yang masih berjalan.

Untuk mengatasinya, saya menulis kode pembersihan sederhana (C #):

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

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

Itu tidak membantu. Prosesnya tidak mati ketika dijalankan di bawah java
Denis Koreyba

@DenisKoreyba: Saya tidak berpikir bahwa bahasa implementasi harus mengubah perilaku. Pada OS Windows, ketika proses tidak dipegang oleh siapa pun - Anda dapat membunuhnya (bahkan jika ditahan, Anda dapat memaksa dan mematikannya). Apakah Anda mencoba mematikannya setelah tab browser ditutup?
Illidan

Saya menggunakan C # untuk melakukan ini, apa yang saya katakan tentang java adalah bahwa proses TeamCity dijalankan di bawahnya. Menjawab pertanyaan Anda: ya, pertama saya memanggil Dispose () dan kemudian kode Anda.
Denis Koreyba

Ini tidak berfungsi pada driver chrome, setidaknya versi 2.21. Proses dimatikan tetapi jendela konsol masih ditampilkan, mungkin karena beberapa proses anak masih berlanjut. jawaban aalhanane di bawah ini bekerja.
Silent Sojourner

Saya memasukkan kode pembersihan yang disebutkan di atas ke dalam bagian AssemblyCleanup dari BaseDriverClass. Bagaimana cara memverifikasi proses chromedriver.exe benar-benar mati?
monkrus

12

Saya sukses saat menggunakan driver.close()sebelumnya driver.quit(). Saya sebelumnya hanya menggunakan driver.quit().


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


driver.close();

driver.quit();

Ini tidak berhasil untuk saya. Memanggil driver.close (); akan menutup browser dan mengatur driver ke null. Dan kemudian tidak ada gunanya memanggil driver.quit (); karena akan memunculkan pengecualian nol.
Priyanka

implementasi memiliki beberapa perubahan pada selenium saat ini, Anda mungkin tidak perlu keluar () jika proses dimatikan. Pastikan ketika Anda melakukan itu, pengelola tugas Anda seharusnya tidak mematikan proses browser.
Shantonu

7

Agak aneh tapi berhasil untuk saya. Saya mengalami masalah serupa, setelah beberapa penggalian saya menemukan bahwa masih ada tindakan UI yang terjadi di browser (memuat URL atau lebih), ketika saya menekan WebDriver.Quit().

Solusi bagi saya (walaupun sangat buruk) adalah menambahkan Sleep()3 detik sebelum memanggil Quit ().


3
Terima kasih, ini benar-benar berhasil untuk saya juga. Saya juga pernah menggunakan WebDriver.Quit()sebelumnya, tetapi terkadang itu membiarkan satu proses chrome.exe hidup. Juga saya kira ini terjadi tidak pada semua sistem operasi.
Grengas

1
Ini berhasil juga untuk saya! Ini mungkin membuat Anda merasa sedikit kotor tetapi terkadang Thread acak. Tidur tampaknya seperti yang diperintahkan dokter untuk tes UI.
Dan Csharpster

Sama untuk saya, tutup sendiri atau keluar sendiri meninggalkan proses driver di belakang. Melakukan keduanya bersih-bersih dengan baik.
Mark Ball

Bagus! Ini berhasil juga untuk saya. Saya menambahkan Task.Delay (TimeSpan.FromSeconds (3)); sebelum memanggil driver.Quit () dan itu menutup semua file chromedriver.exe
Priyanka

5

Jawaban ini adalah cara membuang driver dengan benar di C #

Jika Anda ingin menggunakan mekanisme 'yang tepat' yang harus digunakan untuk 'merapikan' setelah berjalan, ChromeDriver Anda harus menggunakan IWebDriver.Dispose();

Melakukan tugas yang ditentukan aplikasi yang terkait dengan membebaskan, melepaskan, atau menyetel ulang sumber daya yang tidak dikelola. (Diwarisi dari IDisposable.)

Saya biasanya menerapkan IDisposablepada kelas yang berhubungan denganIWebDriver

public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

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

dan gunakan seperti:

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

Semoga ini menghemat waktu Anda


6
Saya dapat memastikan bahwa masih ada masalah dengan strategi ini! Saya menggunakan Selenium WebDriver API .NET v3.13.1.0, instance Chrome saya sudah yang terbaru, dan begitu juga Windows 10 saya ... Saya menggunakan ChromeDriver (yang mengimplementasikan IDisposable by inheritance) seperti ini: using (var driver = new ChromeDriver()) { //my code here } Terkadang, tidak selalu, "Sesuatu" (tidak tahu apa ??) terjadi dan chromedriver.exemasih belum dirilis menurut manajer tugas saya.
Hauns TM

Ya, ini juga tidak memperbaiki bug untuk saya.
Pxtl

4

Bunuh Banyak Proses Dari Baris Perintah Hal pertama yang perlu Anda lakukan adalah membuka prompt perintah, lalu gunakan perintah taskkill dengan sintaks berikut:

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

Parameter ini akan secara paksa menghentikan proses apa pun yang cocok dengan nama yang dapat dieksekusi yang Anda tentukan. Misalnya, untuk mematikan semua proses iexplore.exe, kami akan menggunakan:

taskkill /F /IM iexplore.exe

masukkan deskripsi gambar di sini


3

Kode c #

menggunakan System.Diagnostics;

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

    }

dan fungsi ini

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

Panggilan

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

            }

Saya telah menerapkan kode Anda sebagai pembersihan akhir. Sejauh ini tampaknya berhasil. Kerja bagus!
Exzile

2

Saya memiliki masalah yang sama saat menjalankannya dengan Python dan saya harus menjalankan perintah 'killall' secara manual untuk mematikan semua proses. Namun ketika saya mengimplementasikan driver menggunakan protokol manajemen konteks Python , semua proses hilang. Tampaknya penerjemah Python melakukan pekerjaan yang sangat baik untuk membersihkan semuanya.

Berikut implementasinya:

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

Dan penggunaannya:

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

2

Jadi, Anda dapat menggunakan yang berikut ini:

driver.close()

Tutup browser (meniru menekan tombol tutup)

driver.quit()

Keluar dari browser (meniru pemilihan opsi keluar)

driver.dispose()

Keluar dari browser (mencoba menutup setiap tab, lalu keluar)

Namun, jika Anda MASIH mengalami masalah dengan instans gantung (seperti sebelumnya), Anda mungkin juga ingin menghentikan instans tersebut. Untuk melakukannya, Anda memerlukan PID dari instance 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)

Jika ada contoh krom tersisa setelah itu, saya akan makan topi saya. :(


2

Kode Python:

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

1

Saya tahu ini adalah pertanyaan lama, tetapi saya pikir saya akan membagikan apa yang berhasil untuk saya. Saya mengalami masalah dengan Eclipse - itu tidak akan mematikan proses, jadi saya memiliki banyak proses hantu berkeliaran setelah menguji kode menggunakan pelari Eclipse.

Solusi saya adalah menjalankan Eclipse sebagai administrator. Itu memperbaikinya untuk saya. Tampaknya Windows tidak mengizinkan Eclipse untuk menutup proses yang dimunculkannya.


Ini sangat masuk akal, tetapi dalam kasus saya itu tidak berhasil, chromedriver.exetetap terlihat di antara proses Task Manager tidak peduli saya memulai Eclipse sebagai administrator atau pengguna normal. Ada kemungkinan bahwa dalam kasus saya inilah masalahnya, karena chromedriver.exe32 bit dan JRE saya 64 bit. Eclipse Neon.1a (4.6.1), Windows 8.1 Pro 64 bit, Java 1.8.0_92-b14.
SantiBailors

1

Saya telah menggunakan di bawah ini di nightwatch.js di hook afterEach.

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

.closeWindow () cukup menutup jendela. (Tapi tidak akan berfungsi untuk beberapa jendela yang dibuka). Sedangkan .end () mengakhiri semua proses chrome yang tersisa.


0

Saya memiliki masalah ini. Saya menduga ini karena versi Serenity BDD dan Selenium. Proses chromedriver tidak pernah dirilis hingga seluruh rangkaian pengujian selesai. Hanya ada 97 tes, tetapi memiliki 97 proses yang memakan memori server yang tidak memiliki banyak sumber daya dapat mempengaruhi kinerja.

Untuk mengatasi saya melakukan 2 hal (ini khusus untuk windows).

  1. sebelum setiap pengujian (dianotasi dengan @Before) dapatkan id proses (PID) dari proses chromedriver dengan:

    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. setelah setiap pengujian (dianotasi dengan @After), bunuh PID dengan:

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

0

Saya datang ke sini awalnya berpikir pasti ini akan dijawab / diselesaikan tetapi setelah membaca semua jawaban saya agak terkejut tidak ada yang mencoba memanggil ketiga metode bersama-sama:

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
}

Saya di sini hanya untuk mencari jawaban dan tidak bermaksud untuk memberikan jawaban. Jadi solusi di atas hanya berdasarkan pengalaman saya. Saya menggunakan driver chrome di aplikasi konsol C # dan saya dapat membersihkan proses yang tersisa hanya setelah memanggil ketiga metode secara bersamaan.


0

Untuk pengguna Ubuntu / Linux: - perintahnya adalah pkillatau killall. pkillumumnya direkomendasikan, karena pada beberapa sistem, killallsebenarnya akan mematikan semua proses.


0

Saya menggunakan Protractor dengan directConnect. Menonaktifkan opsi "--tidak ada kotak pasir" memperbaiki masalah saya.

// 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
  • Pastikan Anda mendapatkan instance Driver sebagai Singleton
  • lalu Terapkan di bagian akhir
  • driver.close ()
  • driver.quit ()

Catatan: Sekarang jika kami melihat pengelola tugas Anda tidak akan menemukan driver atau proses chrome yang masih menggantung


0

Saya telah melihat semua tanggapan dan menguji semuanya. Saya cukup banyak mengumpulkan semuanya menjadi satu sebagai 'Penutupan keamanan'. Ini di c #

CATATAN Anda dapat mengubah parameter dari aplikasi IModule ke yang dari driver sebenarnya.

 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

Teramati pada versi 3.141.0:

Jika Anda menginisialisasi ChromeDriver hanya dengan ChromeOptions, berhenti () tidak akan menutup chromedriver.exe.

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

Jika Anda membuat dan meneruskan ChromeDriverService, berhenti () akan menutup chromedriver.exe dengan benar.

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

Ini adalah solusi di java saya percaya. Setidaknya, itu berhasil untuk saya
Isabelle T.

0

Saya hanya menggunakan dalam setiap tes metode tearDown () sebagai berikut dan saya tidak punya masalah sama sekali.

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

Setelah keluar dari instance driver, hapus dari cache oleh driver = null

Semoga jawaban pertanyaannya


0

Ada cara lain yang hanya berfungsi untuk windows, tetapi sekarang sudah usang. ini berfungsi untuk rilis selenium sebelumnya (berfungsi pada versi 3.11.0).

import org.openqa.selenium.os.WindowsUtils;

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.