Selenium chromedriver.exe'yi bellekten serbest bırakın


104

Selenium'u çalıştırmak için bir python kodu kurdum chromedriver.exe. Çalıştırmanın sonunda browser.close()örneği kapatmam gerekiyor. ( browser = webdriver.Chrome()) chromedriver.exeBellekten çıkması gerektiğine inanıyorum (Windows 7 kullanıyorum). Ancak her çalıştırmadan sonra chromedriver.exebellekte bir örnek kalır. Umarım chromedriver.exeişlemi bitirmek için python'da bir şeyler yazmanın bir yolu vardır . Açıkçası browser.close()işi yapmıyor. Teşekkürler.


Sonuç olarak ... süreci bir şekilde öldürmek zorundasınız çünkü tasarımcılar onu inşa etmedi. Diğer tüm yollar bir süreci çalışır halde bırakabilir ve bu öldürmeyi garanti etmek için yeterlidir.
Stephen G

Yanıtlar:


74

Selenium API'ye göre, browser.quit()bu yöntem tüm pencereleri kapatacağı ve işlemi sonlandıracağı için gerçekten çağırmalısınız . Yine de kullanmalısın browser.quit().

Ancak : İş yerimde, Chromedriver.exe'nin kullanıldıktan sonra bile hala var olduğu Java platformunda krom sürücü testleri yürütmeye çalışırken büyük bir sorun fark ettikbrowser.quit() . Buna karşı koymak için, aşağıdakine benzer bir toplu iş dosyası oluşturduk, yalnızca işlemleri zorla kapattı.

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 çok büyük bir program olmadığından ve fazla bellek tüketmediğinden, bunu her seferinde çalıştırmanız gerekmez, yalnızca bir sorun oluşturduğunda bunu çalıştırmanız gerekir. Örneğin, Eclipse'de Proje-> Temizle çalıştırılırken.


3
Bu süreçlerin normal şekilde sonlandırılmasının doğru yolundan da bahsetmeden, süreçleri öldürmeyi öneren hiçbir cevaba göz yumamam. quitYöntemi doğru kullanırsanız , bu bir sorun olmamalıdır. Süreçleri zorla öldürmek yalnızca son çare olmalı ve cevabınız bunu yansıtmalıdır.
JimEvans

17
Bununla ilgili tek sorun, hata ayıkladığınızda ve yürütmeyi sonlandırdığınızda süreç hala devam ediyor. Tıklasanız bile Xhala kalır. bu , bu toplu iş dosyasının YALNIZCA nedeni. Açıkçası quit, gitmenin yolu budur, ancak benim örneğimde, hata ayıklayıp yürütmeyi durdurursanız - asla quit.
ddavison

3
i sorulardan birini cevap veriyorum: I hope there is a way I can write something to kill the chromedriver.exe process.. ve evet, bu güzel! Java bunu yapmaz
ddavison

3
Kullandığınız test çerçevesine bağlı olarak, testler "kurulum" da başarısız olursa, hayalet süreçlerin ortalıkta yatmasına neden olabilirsiniz. Örneğin, TestFixtureSetup yöntemindeki bir şey başarısız olursa NUnit TestFixtureTearDown yöntemini çağırmaz -> tarayıcıyı oluşturur, bazı şeyler yapar ve ardından testi çalıştırırsanız. "Bir şeyler yaptığınızda" bir şeyler ters giderse, o kadar, süreç orada kalmaktır.
Arran

1
DriverService arayüzünü kullanırsanız, sürücüyle işiniz bitene kadar servisi bekleyin ve DriverService.stop () 'u da arayın. Benim için driver.quit () yeterli değildi çünkü ben de DriverService kullanıyordum.
Kimball Robinson

39

browser.close() yalnızca geçerli krom penceresini kapatır.

browser.quit() tüm açık pencereleri kapatmalı, ardından webdriver'dan çıkmalıdır.


9
Teşekkürler Richard. browser.quit()tüm açık pencereleri kapattı. Ancak chromedriver.exe'den çıkılmadı. Ve 'InvalidURL: sayısal olmayan bağlantı noktası:' bağlantı noktası '' hata mesajı vardı.
KLI

5
TAMAM. Denedim browser = webdriver.Firefox(). Her ikisi browser.close()ve browser.quit()tüm pencereleri kapatır ve belleği serbest bırakır. Ancak krom sürücüsü aynı şeyi yapmaz.
KLI

Hey KLI. Burada çalıştığım yerde, krom sürücüsünde aynı şeylerin olduğunu fark ettik. Bu nedenle, yalnızca ihtiyacımız olduğunda çalıştırdığımız bir toplu iş dosyamız var. chromedriver.exe büyük bir işlem değildir, ancak Proje-> Temizle'yi çalıştırmaya çalıştığımızda bir sorun ortaya
çıkarır

17

Teorik olarak, browser.Quit'i çağırmak tüm tarayıcı sekmelerini kapatacak ve işlemi sonlandıracaktır.

Ancak benim durumumda bunu yapamadım - paralel olarak birden fazla test çalıştırdığım için, pencereleri diğerlerine kapatmak için tek bir test yapmak istemedim. Bu nedenle, testlerim çalışmayı bitirdiğinde, hala çalışan birçok "chromedriver.exe" işlemi var.

Bunun üstesinden gelmek için basit bir temizleme kodu (C #) yazdım:

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

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

Yardımcı olmadı. İşlem java altında çalıştırıldığında öldürülmüyor
Denis Koreyba

@DenisKoreyba: Uygulama dilinin davranışı değiştirmesi gerektiğini düşünmüyorum. Windows işletim sisteminde, işlem kimse tarafından tutulmadığında - onu öldürebilirsiniz (tutsa bile, onu zorlayabilir ve öldürebilirsiniz). Tarayıcı sekmeleri kapatıldıktan sonra onu öldürmeye mi çalışıyorsunuz?
Illidan

Bunu yapmak için C # kullanıyorum, java hakkında söylediğim şey, TeamCity işleminin onun altında çalıştığı. Sorunuzu yanıtlamak: evet, önce Dispose () ve ardından kodunuzu çağırıyorum.
Denis Koreyba

Bu, en azından chrome driver, version 2.21 üzerinde çalışmaz. İşlem sonlandırıldı, ancak konsol penceresi hala görüntüleniyor, çünkü muhtemelen bazı alt süreçler hala devam ediyor. aalhanane'nin aşağıdaki cevabı işe yarar.
Silent Sojourner

Yukarıda bahsedilen temizleme kodunu BaseDriverClass'ın AssemblyCleanup bölümüne ekledim. Chromedriver.exe işleminin gerçekten öldürüldüğünü nasıl doğrulayabilirim?
monkrus

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


driver.close();

driver.quit();

Bu benim için işe yaramadı. Driver.close () çağırılıyor; tarayıcıyı kapatacak ve sürücüyü null olarak ayarlayacaktır. Ve sonra driver.quit () 'i çağırmanın bir anlamı yok; null istisna atacağı için.
Priyanka

gerçeklemede mevcut selenyumda bazı değişiklikler var, eğer işlem sonlandırılırsa quit () 'e ihtiyacınız olmayabilir. Bunu yaptığınızda, görev yöneticinizin tarayıcı sürecini kapatmadığından emin olun.
Shantonu

12

Daha driver.close()önce kullanırken başarılı oldum driver.quit(). Daha önce sadece kullanıyordum driver.quit().


7

Biraz tuhaf ama benim için çalışıyor. Benzer bir sorunu yaşadım, biraz araştırma yaptıktan sonra, vurduğumda tarayıcıda hala bir UI eylemi (URL yükleniyor veya benzeri) olduğunu öğrendim.WebDriver.Quit() .

Benim için çözüm (çok kötü de olsa), Sleep()Quit () 'i çağırmadan önce 3 saniye eklemekti .


3
Teşekkürler, bu aslında benim için de çalıştı. Daha WebDriver.Quit()önce de kullanıyordum , ancak bazen bir chrome.exe işlemini canlı bırakıyordu. Ayrıca tüm işletim sistemlerinde olmuyor sanırım.
Grengas

1
Bu benim için de çalıştı! Biraz kirli hissetmenize neden olabilir, ancak bazen rastgele Thread.Sleeps, doktorun UI testleri için istediği gibi görünüyor.
Dan Csharpster

Benim için de aynısı, kendi kendine kapamak ya da kendi kendine çıkmak sürücü sürecini geride bıraktı. İkisini de güzelce temizlemek.
Mark Ball

Harika! Bu benim için de çalıştı. Task.Delay (TimeSpan.FromSeconds (3)) ekledim; driver.Quit () çağırmadan önce tüm chromedriver.exe dosyalarını kapatıyor
Priyanka

5

Bu cevap, sürücünün C # 'da doğru şekilde nasıl atılacağıdır.

Çalıştıktan sonra 'toparlamak' için kullanılması gereken 'uygun' bir mekanizma ChromeDriver kullanmak istiyorsanız, kullanmalısınız IWebDriver.Dispose();

Yönetilmeyen kaynakları serbest bırakmak, serbest bırakmak veya sıfırlamakla ilgili uygulama tanımlı görevleri gerçekleştirir. (IDisposable'dan devralındı.)

Genelde IDisposableilgilenen sınıfa uygularımIWebDriver

public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

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

ve şu şekilde kullanın:

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

Umarım bu sana biraz zaman kazandırır


6
Bu stratejiyle ilgili hala sorunlar olduğunu doğrulayabilirim! Selenium WebDriver API .NET v3.13.1.0 kullanıyorum, Chrome örneğim güncel ve Windows 10'um da öyle ... ChromeDriver'ı (kalıtım yoluyla IDisposable uygulayan) şu şekilde kullanıyorum: using (var driver = new ChromeDriver()) { //my code here } Bazen, her zaman değil, "bir şey" (ne olduğunu bilmiyorum ??) oluyor ve görev yöneticime chromedriver.exegöre hala yayınlanmamış.
Hauns TM

Evet, bu da benim için hatayı düzeltmiyor.
Pxtl

4

Komut Satırından Birden Çok İşlemi Öldür Yapmanız gereken ilk şey, bir komut istemi açmak ve ardından taskkill komutunu aşağıdaki sözdizimiyle kullanmaktır:

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

Bu parametreler, belirttiğiniz yürütülebilir dosyanın adıyla eşleşen herhangi bir işlemi zorla öldürecektir. Örneğin, tüm iexplore.exe işlemlerini öldürmek için şunu kullanırız:

taskkill /F /IM iexplore.exe

görüntü açıklamasını buraya girin


3

Kod c #

System.Diagnostics kullanarak;

System.Management kullanarak;

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

    }

ve bu işlev

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

Aranıyor

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

            }

Kodunuzu son temizlik olarak uyguladım. Şimdiye kadar işe yarıyor gibi görünüyor. Aferin!
Exzile

2

Python'da çalıştırırken de aynı sorunu yaşadım ve tüm işlemleri sonlandırmak için 'killall' komutunu manuel olarak çalıştırmam gerekti. Ancak sürücüyü Python içerik yönetimi protokolünü kullanarak uyguladığımda tüm işlemler gitti. Görünüşe göre Python yorumlayıcı bir şeyleri temizlemek için gerçekten iyi bir iş çıkarıyor.

İşte uygulama:

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

Ve kullanım:

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

2

Dolayısıyla, aşağıdakileri kullanabilirsiniz:

driver.close()

Tarayıcıyı kapatın (kapat düğmesine basıldığında öykünür)

driver.quit()

Tarayıcıdan çıkın (çıkış seçeneğini belirleyerek öykünür)

driver.dispose()

Tarayıcıdan çıkın (her sekmeyi kapatmayı ve ardından çıkmayı dener)

Bununla birlikte, HALA asılı örneklerle ilgili sorunlarla karşılaşıyorsanız (benim gibi), örneği de öldürmek isteyebilirsiniz. Bunu yapmak için, chrome örneğinin PID'sine ihtiyacınız vardır.

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)

Bundan sonra bir krom örneği kaldıysa, şapkamı yerim. :(


2

Python kodu:

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

1

Bunun biraz eski bir soru olduğunu biliyorum ama benim için işe yarayan şeyi paylaşacağımı düşündüm. Eclipse ile sorunlar yaşıyordum - bu süreçleri öldürmezdi ve bu yüzden Eclipse çalıştırıcısını kullanarak kodu test ettikten sonra ortalıkta dolaşan bir sürü hayalet işlemim vardı.

Çözümüm, Eclipse'i yönetici olarak çalıştırmaktı. Bu benim için sorunumu çözdü. Görünüşe göre Windows, Eclipse'in oluşturduğu işlemi kapatmasına izin vermiyor.


Bu çok mantıklı, ancak benim durumumda işe yaramadı, chromedriver.exeEclipse'i yönetici veya normal kullanıcı olarak başlattığım önemli değil, Görev Yöneticisi işlemleri arasında görünür durumda kalıyor. Bu benim durumumda olasıdır bu çünkü sorunun chromedriver.exe32 bit ve benim JRE 64 bit. Eclipse Neon.1a (4.6.1), Windows 8.1 Pro 64 bit, Java 1.8.0_92-b14.
SantiBailors

1

Aşağıdakini afterEach hook'larında nightwatch.js'de kullandım.

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

.closeWindow () sadece pencereyi kapatır. (Ancak birden çok pencere açıldığında çalışmayacaktır). Oysa .end (), kalan tüm krom işlemlerini sona erdirir.


0

Bu sorunu yaşıyorum. Serenity BDD ve Selenium sürümünden kaynaklandığından şüpheleniyorum. Chromedriver işlemi, tüm test paketi bitene kadar asla serbest bırakılmaz. Yalnızca 97 test vardır, ancak 97 işlemin çok kaynağı olmayan bir sunucunun belleğini tüketmesi performans üzerinde bir etkiye sahip olabilir.

Ele almak için 2 şey yaptım (bu, pencerelere özeldir).

  1. her testten önce (@Before ile açıklamalı) chromedriver işleminin işlem kimliğini (PID) şu şekilde alın:

    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. her testten sonra (@After ile açıklamalı) PID'yi şu şekilde öldürün:

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

0

Buraya başlangıçta kesinlikle bunun cevaplanacağını / çözüleceğini düşünerek geldim, ancak tüm cevapları okuduktan sonra hiç kimse üç yöntemi bir araya getirmeye çalışmadı:

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
}

Ben sadece cevaplar aramak için buradaydım ve cevap vermek niyetinde değildim. Dolayısıyla, yukarıdaki çözüm yalnızca benim deneyimime dayanmaktadır. Bir C # konsol uygulamasında krom sürücüsü kullanıyordum ve kalan işlemleri ancak üç yöntemi birlikte çağırdıktan sonra temizleyebildim.


0

Ubuntu / Linux kullanıcıları için: - komut ya pkillda killall. pkillbazı sistemlerde killallaslında tüm süreçleri öldüreceğinden genellikle önerilir .


0

DirectConnect ile Açıölçer kullanıyorum. "- no-sandbox" seçeneğinin devre dışı bırakılması sorunu benim için çözdü.

// 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
  • Driver örneğini Singleton olarak aldığınızdan emin olun
  • sonra sonunda uygula
  • driver.close ()
  • driver.quit ()

Not: Şimdi görev yöneticisini görürsek, hala asılı olan herhangi bir sürücü veya krom işlemi bulamazsınız.


0

Tüm yanıtlara baktım ve hepsini test ettim. Hemen hemen hepsini bir 'Güvenlik kapatması' olarak derledim. Bu c #

NOT parametresini IModule uygulamasından gerçek sürücününkine değiştirebilirsiniz.

 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 sürümünde gözlemlenmiştir:

ChromeDriver'ınızı yalnızca ChromeOptions ile başlatırsanız, quit (), chromedriver.exe'yi kapatmaz.

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

Bir ChromeDriverService oluşturur ve iletirseniz, quit (), chromedriver.exe'yi doğru şekilde kapatır.

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

Bu, java'daki çözüm olduğuna inanıyorum. En azından benim için çalıştı
Isabelle T.

0

Her testte aşağıdaki gibi tearDown () yöntemini kullanıyorum ve hiç sorunum yok.

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

Sürücü örneğinden çıktıktan sonra sürücü = null ile önbellekten temizleyin

Umarım sorunun cevabı


0

Yalnızca pencereler için çalışan başka bir yol var, ancak şimdi kullanımdan kaldırıldı. önceki selenyum sürümleri için çalışır (3.11.0 sürümünde çalışır).

import org.openqa.selenium.os.WindowsUtils;

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.