pythonコードを設定して、Selenium chromedriver.exe
を実行します。実行の最後に、browser.close()
を使用してインスタンスを閉じます。 (browser = webdriver.Chrome()
)メモリからchromedriver.exe
を解放する必要があると思います(Windows 7を使用しています)。ただし、各実行後に1つのchromedriver.exe
インスタンスがメモリに残ります。 pythonで何かを書いてchromedriver.exe
プロセスを強制終了する方法があることを願っています。明らかにbrowser.close()
は動作しません。ありがとう。
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を実行する場合。
browser.close()
は、現在のchromeウィンドウのみを閉じます。
browser.quit()
は、開いているウィンドウをすべて閉じてから、webdriverを終了する必要があります。
理論的には、browser.Quitを呼び出すと、すべてのブラウザータブが閉じられ、プロセスが強制終了されます。
ただし、私の場合、それを行うことができませんでした。複数のテストを並行して実行しているため、1つのテストで他のウィンドウを閉じる必要はありませんでした。したがって、テストの実行が終了しても、多くの「chromedriver.exe」プロセスが実行されたままになります。
それを克服するために、単純なクリーンアップコード(C#)を作成しました。
Process[] chromeDriverProcesses = Process.GetProcessesByName("chromedriver");
foreach(var chromeDriverProcess in chromeDriverProcesses)
{
chromeDriverProcess.Kill();
}
driver.close()
の前にdriver.quit()
を使用すると成功しました。以前はdriver.quit()
のみを使用していました。
//Calling close and then quit will kill the driver running process.
driver.close();
driver.quit();
それはちょっと奇妙ですが、私にはうまくいきます。 WebDriver.Quit()
を押したときに、ブラウザーで実行中のUIアクション(URLの読み込みなど)がまだあることがわかったので、同様の問題がありました。
私にとっての解決策は(非常に厄介ですが)、Quit()を呼び出す前に3秒のSleep()
を追加することでした。
この答えは、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
}
これで時間を節約できることを願っています
コード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
{
}
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()
これはやや古い質問であることは知っていますが、私にとっては何が効果的かを共有すると思いました。私はEclipseで問題を抱えていました-プロセスを殺すことはできませんでしたので、Eclipseランナーを使用してコードをテストした後、たくさんの幻のプロセスがぶらぶらしていました。
私の解決策は、管理者としてEclipseを実行することでした。それは私のためにそれを修正しました。 Windowsは、Eclipseが生成したプロセスを終了することを許可していないようです。
したがって、次を使用できます。
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インスタンスが残っている場合は、帽子を食べます。 :(
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プロセスを終了します。
try:
# do my automated tasks
except:
pass
finally:
driver.close()
driver.quit()
注:タスクマネージャーが表示されても、ドライバーやchromeプロセスがまだハングしていることはありません。
私は最初にここに来て、確かにこれは答えられたか解決されたと思っていましたが、すべての答えを読んだ後、誰も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つのメソッドすべてを一緒に呼び出した後にのみ、残留プロセスをクリーンアップできました。
私はすべての応答を見て、それらをすべてテストしました。私はほとんどすべてを「安全閉鎖」として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.
}
}
}
Ubuntu/Linuxユーザーの場合:-コマンドはpkill
またはkillall
です。 pkill
は一般的に推奨されます。一部のシステムでは、killall
が実際にすべてのプロセスを強制終了するためです。
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"]
}
},
この問題があります。 Serenity BDDとSeleniumのバージョンが原因だと思われます。テストスイート全体が終了するまで、chromedriverプロセスはリリースされません。テストは97個しかありませんが、97個のプロセスがあると、リソースがあまりないサーバーのメモリを使い果たし、パフォーマンスに影響する可能性があります。
対処するために、2つのことを行いました(これはWindowsに固有です)。
各テスト(@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]));
}
}
各テスト(@Afterアノテーション付き)の後に、PIDを強制終了します。
Runtime.getRuntime().exec("taskkill /F /PID " + pid);