Selenium leaves behind running processes?
As already pointed out you should run browser.quit()
But on linux (inside docker) this will leave defunct processes. These are typically not really a problem as they are mere an entry in the process-table and consume no resources. But if you have many of those you will run out of processes. Typically my server melts down at 65k processes.
It looks like this:
# root@dockerhost1:~/odi/docker/bf1# ps -ef | grep -i defunct | wc -l28599root@dockerhost1:~/odi/docker/bf1# ps -ef | grep -i defunct | tailroot 32757 10839 0 Oct18 ? 00:00:00 [chrome] <defunct>root 32758 895 0 Oct18 ? 00:00:02 [chrome] <defunct>root 32759 15393 0 Oct18 ? 00:00:00 [chrome] <defunct>root 32760 13849 0 01:23 ? 00:00:00 [chrome] <defunct>root 32761 472 0 Oct18 ? 00:00:00 [chrome] <defunct>root 32762 19360 0 01:35 ? 00:00:00 [chrome] <defunct>root 32763 30701 0 00:34 ? 00:00:00 [chrome] <defunct>root 32764 17556 0 Oct18 ? 00:00:00 [chrome] <defunct>root 32766 8102 0 00:49 ? 00:00:00 [cat] <defunct>root 32767 9490 0 Oct18 ? 00:00:00 [chrome] <defunct>
The following code will solve the problem:
def quit_driver_and_reap_children(driver): log.debug('Quitting session: %s' % driver.session_id) driver.quit() try: pid = True while pid: pid = os.waitpid(-1, os.WNOHANG) log.debug("Reaped child: %s" % str(pid)) #Wonka's Solution to avoid infinite loop cause pid value -> (0, 0) try: if pid[0] == 0: pid = False except: pass #---- ---- except ChildProcessError: pass
Whats happening is that your code is throwing an exception, halting the python process from continuing on. As such, the close/quit methods never get called on the browser object, so the chromedrivers just hang out indefinitely.
You need to use a try/except block to ensure the close method is called every time, even when an exception is thrown. A very simplistic example is:
from selenium import webdriverbrowser = webdriver.Chrome("path/to/chromedriver")try: browser.get("http://stackoverflow.com") browser.find_element_by_id('...').click()except: browser.close() browser.quit() # I exclusively use quit
There are a number of much more sophisticated approaches you can take here, such as creating a context manager to use with the with
statement, but its difficult to recommend one without having a better understanding of your codebase.
Chromedriver.exe crowds the TaskManager ( in case of Windows) everytime Selenium runs on Chrome.Sometimes, it doesn't clear even if the browser didn't crash.
I usually run a bat file or a cmd to kill all the existing chromedriver.exe processes before launching another one.
Take a look at this : release Selenium chromedriver.exe from memory
- I know this is a Unix-related question but I am sure the way it has been handled in Windows can be applied there.