giải phóng Selenium chromedriver.exe khỏi bộ nhớ


102

Tôi đã thiết lập mã python để chạy Selenium chromedriver.exe. Vào cuối quá trình chạy, tôi phải browser.close()đóng phiên bản. ( browser = webdriver.Chrome()) Tôi tin rằng nó sẽ giải phóng chromedriver.exekhỏi bộ nhớ (tôi đang sử dụng Windows 7). Tuy nhiên, sau mỗi lần chạy, chromedriver.exevẫn còn một phiên bản trong bộ nhớ. Tôi hy vọng có một cách để tôi có thể viết một cái gì đó trong python để giết chromedriver.exequá trình này. Rõ ràng là browser.close()không làm được việc. Cảm ơn.


Điểm mấu chốt ... bạn phải giết tiến trình bằng cách nào đó bởi vì các nhà thiết kế đã không xây dựng nó. Tất cả các cách khác có thể khiến một tiến trình chạy và điều đó đủ để đảm bảo việc giết chết.
Stephen G,

Câu trả lời:


73

theo API Selenium, bạn thực sự nên gọi browser.quit()vì phương thức này sẽ đóng tất cả các cửa sổ và giết quá trình. Bạn vẫn nên sử dụng browser.quit().

Tuy nhiên : Tại nơi làm việc của tôi, chúng tôi đã nhận thấy một vấn đề lớn khi cố gắng thực hiện các bài kiểm tra chromedriver trong nền tảng Java, nơi chromedriver.exe thực sự vẫn tồn tại ngay cả sau khi sử dụng browser.quit(). Để chống lại điều này, chúng tôi đã tạo một tệp hàng loạt tương tự như tệp này bên dưới, tệp này chỉ buộc đóng các quy trình.

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

Vì chromedriver.exe không phải là một chương trình lớn và không tiêu tốn nhiều bộ nhớ, bạn không cần phải chạy chương trình này mọi lúc, nhưng chỉ khi nó xuất hiện vấn đề. Ví dụ khi chạy Project-> Clean trong Eclipse.


3
Tôi không thể chấp nhận bất kỳ câu trả lời nào đề xuất các quy trình giết chết mà không đề cập đến cách chính xác để các quy trình đó kết thúc bình thường. Nếu bạn sử dụng đúng quitphương pháp này, điều này sẽ không thành vấn đề. Buộc giết các quy trình chỉ nên là phương sách cuối cùng và câu trả lời của bạn phải phản ánh điều đó.
JimEvans

17
Xem vấn đề duy nhất với điều này, là khi bạn gỡ lỗi và hủy quá trình thực thi - quá trình này vẫn còn. Ngay cả khi bạn nhấp vào Xnó vẫn còn. đó là lý do DUY NHẤT cho tệp hàng loạt này. Rõ ràng quitlà cách để đi, tuy nhiên trong ví dụ của tôi, nếu bạn gỡ lỗi và dừng thực thi - nó không bao giờ đạt được quit.
ddavison

3
Tôi đang trả lời một trong những câu hỏi sau: I hope there is a way I can write something to kill the chromedriver.exe process.. và vâng, điều đó thật tuyệt! Java không làm điều đó
ddavison

3
Tùy thuộc vào khuôn khổ thử nghiệm bạn sử dụng, bạn cũng có thể kết thúc với các quy trình ảo nằm xung quanh nếu các thử nghiệm không thành công trong quá trình "thiết lập" của nó. Ví dụ, NUnit sẽ không gọi phương thức TestFixtureTearDown nếu một thứ gì đó trong phương thức TestFixtureSetup bị lỗi -> bạn tạo trình duyệt, thực hiện một số thứ, rồi chạy thử nghiệm. Nếu có gì đó không ổn khi "bạn làm một số thứ", thì đó là nó, quá trình vẫn ở đó.
Arran

1
Nếu bạn sử dụng giao diện DriverService, hãy giữ dịch vụ cho đến khi bạn hoàn tất việc cài đặt trình điều khiển và gọi DriverService.stop (). Đối với tôi, driver.quit () là không đủ vì tôi cũng đang sử dụng DriverService.
Kimball Robinson,

38

browser.close() sẽ chỉ đóng cửa sổ chrome hiện tại.

browser.quit() nên đóng tất cả các cửa sổ đang mở, sau đó thoát khỏi webdriver.


9
Cảm ơn Richard. browser.quit()đã đóng tất cả các cửa sổ đang mở. Nhưng chromedriver.exe không được thoát. Và có một thông báo lỗi 'InvalidURL: nonnumeric port:' port ''.
KLI

5
ĐỒNG Ý. Tôi đã thử browser = webdriver.Firefox(). Cả hai browser.close()browser.quit()sẽ đóng tất cả các cửa sổ và giải phóng bộ nhớ. Tuy nhiên chromedriver sẽ không làm như vậy.
KLI

Này KLI. Tại nơi tôi làm việc, chúng tôi đã nhận thấy những điều tương tự xảy ra với chromedriver. Đây là lý do tại sao chúng tôi có một tệp hàng loạt mà chúng tôi chỉ chạy khi cần. chromedriver.exe không phải là một quá trình lớn, nhưng nó là một vấn đề hiện nay khi chúng ta cố gắng chạy dự án-> sạch ví dụ
ddavison

17

Về mặt lý thuyết, việc gọi browser.Quit sẽ đóng tất cả các tab của trình duyệt và giết quá trình.

Tuy nhiên, trong trường hợp của tôi, tôi đã không thể làm điều đó - vì tôi chạy nhiều bài kiểm tra song song, tôi không muốn một bài kiểm tra đóng cửa sổ cho người khác. Do đó, khi các bài kiểm tra của tôi chạy xong, vẫn còn nhiều quy trình "chromedriver.exe" đang chạy.

Để khắc phục điều đó, tôi đã viết một mã dọn dẹp đơn giản (C #):

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

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

Nó không giúp được gì. Quá trình không bị giết khi nó chạy dưới java
Denis Koreyba

@DenisKoreyba: Tôi không nghĩ rằng ngôn ngữ triển khai sẽ thay đổi hành vi. Trên hệ điều hành Windows, khi quá trình không do ai nắm giữ - bạn có thể giết nó (ngay cả khi nó bị giữ, bạn có thể buộc và giết nó). Bạn đang cố gắng loại bỏ nó sau khi (các) tab trình duyệt đóng?
Illidan

Tôi đang sử dụng C # để làm điều này, những gì tôi đã nói với java là quá trình của TeamCity được chạy dưới nó. Trả lời câu hỏi của bạn: có, đầu tiên tôi gọi Dispose () và sau đó là mã của bạn.
Denis Koreyba

Điều này không hoạt động trên trình điều khiển chrome, ít nhất là phiên bản 2.21. Tiến trình bị giết nhưng cửa sổ giao diện điều khiển vẫn hiển thị, có thể do một số tiến trình con vẫn tồn tại. câu trả lời của aalhanane dưới đây hoạt động.
Silent Sojourner

Tôi đã chèn mã dọn dẹp nói trên vào phần AssemblyCleanup của BaseDriverClass. Làm cách nào để xác minh quá trình chromedriver.exe đã thực sự bị giết?
Monrus 23-07-19

12

Tôi đã thành công khi sử dụng driver.close()trước đây driver.quit(). Tôi trước đây chỉ sử dụng driver.quit().


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


driver.close();

driver.quit();

Điều này không hiệu quả với tôi. Đang gọi driver.close (); sẽ đóng trình duyệt và đặt trình điều khiển thành null. Và sau đó không có điểm nào để gọi driver.quit (); vì nó sẽ ném ra ngoại lệ null.
Priyanka

việc triển khai có một số thay đổi trong selen hiện tại, bạn có thể không cần bỏ () nếu quá trình bị hủy. Đảm bảo rằng khi bạn làm điều đó, trình quản lý tác vụ của bạn sẽ không có quá trình trình duyệt bị giết.
Shantonu

7

Nó hơi lạ nhưng nó hiệu quả với tôi. Tôi đã gặp sự cố tương tự, sau một số lần đào, tôi thấy rằng vẫn có một hành động giao diện người dùng đang diễn ra trong trình duyệt (URL tải hoặc lâu hơn), khi tôi nhấnWebDriver.Quit() .

Giải pháp cho tôi (rất khó chịu) là thêm Sleep()3 giây trước khi gọi Quit ().


3
Cảm ơn, điều này thực sự làm việc cho tôi. Tôi cũng đã sử dụng WebDriver.Quit()trước đây, nhưng đôi khi nó để lại một quá trình chrome.exe còn sống. Ngoài ra, tôi đoán nó không xảy ra trên tất cả các hệ điều hành.
Grengas

1
Điều này cũng làm việc cho tôi! Nó có thể khiến bạn cảm thấy hơi bẩn nhưng đôi khi Thread.Sleeps ngẫu nhiên dường như là thứ mà bác sĩ chỉ định cho các xét nghiệm UI.
Dan Csharpster

Tương tự đối với tôi, tự đóng hoặc tự thoát sẽ để lại quy trình trình điều khiển. Làm cả hai đều làm sạch đẹp.
Mark Ball

Tuyệt quá! Điều này cũng làm việc cho tôi. Tôi đã thêm Task.Delay (TimeSpan.FromSeconds (3)); trước khi gọi driver.Quit () và nó đang đóng tất cả các tệp chromedriver.exe
Priyanka

5

Câu trả lời này là cách xử lý đúng trình điều khiển trong C #

Nếu bạn muốn sử dụng một cơ chế 'thích hợp' được sử dụng để 'dọn dẹp' sau khi chạy, ChromeDriver bạn nên sử dụng IWebDriver.Dispose();

Thực hiện các tác vụ do ứng dụng xác định liên quan đến giải phóng, phát hành hoặc đặt lại các tài nguyên không được quản lý. (Được kế thừa từ IDisposable.)

Tôi thường triển khai IDisposabletrên lớp đang xử lýIWebDriver

public class WebDriverController : IDisposable
{
    public IWebDriver Driver;

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

và sử dụng nó như:

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

Hy vọng điều này giúp bạn tiết kiệm thời gian


6
Tôi có thể xác nhận rằng vẫn còn vấn đề với chiến lược này! Tôi đang sử dụng Selenium WebDriver API .NET v3.13.1.0, phiên bản Chrome của tôi đã được cập nhật và Windows 10 của tôi cũng vậy ... Tôi đang sử dụng ChromeDriver (triển khai IDisposable theo kế thừa) như sau: using (var driver = new ChromeDriver()) { //my code here } Đôi khi, không phải lúc nào, "cái gì đó" (không biết là gì ??) xảy ra và chromedriver.exevẫn chưa được phát hành theo người quản lý tác vụ của tôi.
Hauns TM

Yup, điều này cũng không sửa được lỗi cho tôi.
Pxtl

4

Diệt nhiều quá trình từ dòng lệnh Điều đầu tiên bạn cần làm là mở dấu nhắc lệnh, sau đó sử dụng lệnh taskkill với cú pháp sau:

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

Các tham số này sẽ buộc phải giết bất kỳ quá trình nào khớp với tên của tệp thực thi mà bạn chỉ định. Ví dụ, để giết tất cả các quy trình iexplore.exe, chúng tôi sẽ sử dụng:

taskkill /F /IM iexplore.exe

nhập mô tả hình ảnh ở đây


3

Mã c #

sử dụng System.Diagnostics;

sử dụng 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;
            }
        }

    }

và chức năng này

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

Kêu gọi

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

            }

Tôi đã áp dụng mã của bạn để làm sạch lần cuối. Cho đến nay nó dường như hoạt động. Làm tốt lắm!
Exzile

2

Tôi đã gặp vấn đề tương tự khi chạy nó bằng Python và tôi phải chạy lệnh 'killall' theo cách thủ công để giết tất cả các quy trình. Tuy nhiên, khi tôi triển khai trình điều khiển bằng Python giao thức quản lý ngữ cảnh tất cả các quy trình đã biến mất. Có vẻ như trình thông dịch Python thực hiện rất tốt công việc dọn dẹp mọi thứ.

Đây là cách thực hiện:

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

Và cách sử dụng:

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

2

Vì vậy, bạn có thể sử dụng như sau:

driver.close()

Đóng trình duyệt (giả lập nhấn nút đóng)

driver.quit()

Thoát khỏi trình duyệt (giả lập chọn tùy chọn thoát)

driver.dispose()

Thoát khỏi trình duyệt (cố gắng đóng mọi tab, sau đó thoát)

Tuy nhiên, nếu bạn VẪN gặp sự cố với các phiên bản treo (như tôi đã từng), bạn cũng có thể muốn hủy phiên bản đó. Để làm điều đó, bạn cần PID của phiên bản 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)

Nếu còn sót lại vết rôm sảy sau đó, tôi sẽ đội nón ra đi. :(


2

Mã Python:

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

1

Tôi biết đây là một câu hỏi cũ, nhưng tôi nghĩ tôi sẽ chia sẻ những gì hiệu quả với tôi. Tôi đang gặp sự cố với Eclipse - nó sẽ không giết các quy trình và vì vậy tôi có một loạt các quy trình ảo đang tồn tại sau khi kiểm tra mã bằng trình chạy Eclipse.

Giải pháp của tôi là chạy Eclipse với tư cách quản trị viên. Điều đó đã sửa nó cho tôi. Có vẻ như Windows không cho phép Eclipse đóng quá trình mà nó tạo ra.


Điều này rất có ý nghĩa, nhưng trong trường hợp của tôi, nó không hoạt động, chromedriver.exevẫn hiển thị giữa các quy trình Trình quản lý tác vụ cho dù tôi khởi động Eclipse với tư cách quản trị viên hay người dùng bình thường. Có thể trong trường hợp của tôi đây là vấn đề, vì chromedriver.exelà 32 bit và JRE của tôi là 64 bit. Eclipse Neon.1a (4.6.1), Windows 8.1 Pro 64 bit, Java 1.8.0_92-b14.
SantiBailors

1

Tôi đã sử dụng bên dưới trong nightwatch.js trong afterEach hooks.

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

.closeWindow () chỉ cần đóng cửa sổ. (Nhưng sẽ không hoạt động đối với nhiều cửa sổ được mở). Trong khi .end () kết thúc tất cả các quá trình chrome còn lại.


0

Tôi có vấn đề này. Tôi nghi ngờ nó là do phiên bản Serenity BDD và Selenium. Quy trình chromedriver không bao giờ phát hành cho đến khi toàn bộ bộ thử nghiệm kết thúc. Chỉ có 97 bài kiểm tra, nhưng có 97 quá trình ngốn bộ nhớ của một máy chủ không có nhiều tài nguyên có thể ảnh hưởng đến hiệu suất.

Để giải quyết, tôi đã làm 2 điều (điều này dành riêng cho windows).

  1. trước mỗi bài kiểm tra (chú thích bằng @Before), hãy lấy id quy trình (PID) của quy trình chromedriver với:

    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. sau mỗi lần kiểm tra (được chú thích bằng @After), hãy giết PID bằng:

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

0

Tôi đến đây ban đầu nghĩ rằng chắc chắn điều này sẽ được trả lời / giải quyết nhưng sau khi đọc tất cả các câu trả lời, tôi hơi ngạc nhiên khi không ai thử gọi cả ba phương thức với nhau:

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
}

Tôi chỉ ở đây để tìm kiếm câu trả lời và không có ý định cung cấp câu trả lời. Vì vậy, giải pháp trên chỉ dựa trên kinh nghiệm của tôi. Tôi đang sử dụng trình điều khiển chrome trong ứng dụng bảng điều khiển C # và tôi chỉ có thể xóa các quy trình còn tồn tại sau khi gọi cả ba phương thức cùng nhau.


0

Đối với người dùng Ubuntu / Linux: - lệnh là pkillhoặc killall. pkillthường được khuyến nghị, vì trên một số hệ thống, killallsẽ thực sự giết tất cả các quy trình.


0

Tôi đang sử dụng Thước đo góc với directConnect. Việc tắt tùy chọn "--no-sandbox" đã khắc phục sự cố cho tôi.

// 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
  • Đảm bảo rằng bạn nhận được phiên bản Driver dưới dạng Singleton
  • sau đó Áp dụng ở cuối
  • driver.close ()
  • driver.quit ()

Lưu ý: Bây giờ nếu chúng tôi thấy trình quản lý tác vụ, bạn sẽ không tìm thấy bất kỳ trình điều khiển hoặc quy trình chrome nào vẫn bị treo


0

Tôi đã xem xét tất cả các câu trả lời và kiểm tra tất cả. Tôi đã tổng hợp khá nhiều tất cả chúng thành một dưới dạng 'Kết thúc an toàn'. Điều này trong c #

LƯU Ý bạn có thể thay đổi thông số từ ứng dụng IModule thành thông số của trình điều khiển thực tế.

 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

Quan sát trên phiên bản 3.141.0:

Nếu bạn khởi chạy ChromeDriver của mình chỉ với ChromeOptions, thì thoát () sẽ không đóng chromedriver.exe.

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

Nếu bạn tạo và chuyển vào ChromeDriverService, thì thoát () sẽ đóng chromedriver.exe một cách chính xác.

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

Đây là giải pháp trong java mà tôi tin tưởng. Ít nhất, nó đã làm việc cho tôi
Isabelle T.

0

Tôi chỉ đơn giản là sử dụng trong mọi thử nghiệm một phương thức dropsDown () như sau và tôi không gặp vấn đề gì.

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

Sau khi thoát khỏi phiên bản trình điều khiển, hãy xóa nó khỏi bộ nhớ cache bằng driver = null

Hy vọng câu trả lời cho câu hỏi


0

Có một cách khác chỉ hoạt động cho windows, nhưng bây giờ nó không được dùng nữa. nó hoạt động cho các bản phát hành selen trước đó (nó hoạt động trên phiên bản 3.11.0).

import org.openqa.selenium.os.WindowsUtils;

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.