web-dev-qa-db-ja.com

メモリからSelenium chromedriver.exeを解放します

pythonコードを設定して、Selenium chromedriver.exeを実行します。実行の最後に、browser.close()を使用してインスタンスを閉じます。 (browser = webdriver.Chrome())メモリからchromedriver.exeを解放する必要があると思います(Windows 7を使用しています)。ただし、各実行後に1つのchromedriver.exeインスタンスがメモリに残ります。 pythonで何かを書いてchromedriver.exeプロセスを強制終了する方法があることを願っています。明らかにbrowser.close()は動作しません。ありがとう。

87
KLI

selenium APIごとに、このメソッドはすべてのウィンドウを閉じてプロセスを強制終了するため、browser.quit()を実際に呼び出す必要があります。それでもbrowser.quit()を使用する必要があります。

ただし:私の職場では、Javaプラットフォームでchromedriverテストを実行しようとすると、browser.quit()を使用した後でもchromedriver.exeが実際に存在するという大きな問題に気付きました。これに対抗するために、以下のようなバッチファイルを作成しました。これはプロセスを強制的に閉じます。

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は巨大なプログラムではなく、多くのメモリを消費しないため、毎回実行する必要はありませんが、問題が発生した場合にのみ実行してください。たとえば、EclipseでProject-> Cleanを実行する場合。

64
ddavison

browser.close()は、現在のchromeウィンドウのみを閉じます。

browser.quit()は、開いているウィンドウをすべて閉じてから、webdriverを終了する必要があります。

29
Richard

理論的には、browser.Quitを呼び出すと、すべてのブラウザータブが閉じられ、プロセスが強制終了されます。

ただし、私の場合、それを行うことができませんでした。複数のテストを並行して実行しているため、1つのテストで他のウィンドウを閉じる必要はありませんでした。したがって、テストの実行が終了しても、多くの「chromedriver.exe」プロセスが実行されたままになります。

それを克服するために、単純なクリーンアップコード(C#)を作成しました。

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

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

driver.close()の前にdriver.quit()を使用すると成功しました。以前はdriver.quit()のみを使用していました。

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


driver.close();

driver.quit();
8
Shantonu

それはちょっと奇妙ですが、私にはうまくいきます。 WebDriver.Quit()を押したときに、ブラウザーで実行中のUIアクション(URLの読み込みなど)がまだあることがわかったので、同様の問題がありました。

私にとっての解決策は(非常に厄介ですが)、Quit()を呼び出す前に3秒のSleep()を追加することでした。

5
Alpana Chauhan

この答えは、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
}

これで時間を節約できることを願っています

4

コード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
            {

            }
3
aalhanane

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
Wizard

これはやや古い質問であることは知っていますが、私にとっては何が効果的かを共有すると思いました。私はEclipseで問題を抱えていました-プロセスを殺すことはできませんでしたので、Eclipseランナーを使用してコードをテストした後、たくさんの幻のプロセスがぶらぶらしていました。

私の解決策は、管理者としてEclipseを実行することでした。それは私のためにそれを修正しました。 Windowsは、Eclipseが生成したプロセスを終了することを許可していないようです。

1
forresthopkinsa

したがって、次を使用できます。

driver.close()

ブラウザを閉じます(閉じるボタンを押すことをエミュレートします)

driver.quit()

ブラウザを終了します(終了オプションの選択をエミュレートします)

driver.dispose()

ブラウザを終了します(すべてのタブを閉じてから終了します)

ただし、STILLインスタンスがハングしている(私がそうであったように)問題が発生している場合は、インスタンスを強制終了することもできます。そのためには、chromeインスタンスの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)

その後chromeインスタンスが残っている場合は、帽子を食べます。 :(

1
Rue Lazzaro

コマンドラインから複数のプロセスを強制終了する最初に必要なことは、コマンドプロンプトを開き、次の構文でtaskkillコマンドを使用することです。

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

これらのパラメーターは、指定した実行可能ファイルの名前に一致するプロセスを強制的に強制終了します。たとえば、すべてのiexplore.exeプロセスを強制終了するには、次を使用します。

taskkill /F /IM iexplore.exe

enter image description here

1

AfterEachフックのnightwatch.jsで以下を使用しました。

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

.closeWindow()は、単にウィンドウを閉じるだけです。 (ただし、開いている複数のウィンドウでは機能しません)。一方、.end()は残りのすべてのchromeプロセスを終了します。

1
Simon Correia

Pythonコード:

try:
    # do my automated tasks
except:
    pass
finally:
    driver.close()
    driver.quit()
1
Moshe Slavin
  • ドライバーインスタンスをシングルトンとして取得することを確認する
  • 最後に適用する
  • driver.close()
  • driver.quit()

注:タスクマネージャーが表示されても、ドライバーやchromeプロセスがまだハングしていることはありません。

0
sarath

私は最初にここに来て、確かにこれは答えられたか解決されたと思っていましたが、すべての答えを読んだ後、誰も3つのメソッドすべてを一緒に呼び出そうとしなかったことに少し驚いていました:

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#コンソールアプリでchromeドライバーを使用していましたが、3つのメソッドすべてを一緒に呼び出した後にのみ、残留プロセスをクリーンアップできました。

0
Louie Bao

私はすべての応答を見て、それらをすべてテストしました。私はほとんどすべてを「安全閉鎖」として1つにまとめました。これは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
Exzile

Ubuntu/Linuxユーザーの場合:-コマンドはpkillまたはkillallです。 pkillは一般的に推奨されます。一部のシステムでは、killallが実際にすべてのプロセスを強制終了するためです。

0
Manmohan_singh

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
Georgi Ekimov

この問題があります。 Serenity BDDとSeleniumのバージョンが原因だと思われます。テストスイート全体が終了するまで、chromedriverプロセスはリリースされません。テストは97個しかありませんが、97個のプロセスがあると、リソースがあまりないサーバーのメモリを使い果たし、パフォーマンスに影響する可能性があります。

対処するために、2つのことを行いました(これはWindowsに固有です)。

  1. 各テスト(@Beforeアノテーション)の前に、次を使用してchromedriverプロセスのプロセスID(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
Dean McNabb