Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

driver.quit not working #1667

Open
tromotixc opened this issue Nov 18, 2023 · 10 comments
Open

driver.quit not working #1667

tromotixc opened this issue Nov 18, 2023 · 10 comments

Comments

@tromotixc
Copy link

tromotixc commented Nov 18, 2023

driver.quit closes the driver window but leaves the chromes in task manager which eat the CPU

@VQHieu1012
Copy link

same

@Ko4ka
Copy link

Ko4ka commented Nov 29, 2023

Same here

@ours1505
Copy link

ours1505 commented Dec 3, 2023

same

@typhoon93
Copy link

typhoon93 commented Dec 6, 2023

I have created a custom function that is run at __del of my class. This is for my specific case where I have a specific browser folder I use / set in the class that uses ChromeDriver, and can probably be implemented in more general way.

self.user_data_folder is set like this in the beginning of my code where i instantiate the chrome with this options :

chrome_options.add_argument(f"--user-data-dir={self.user_data_folder}")

self.user_data_folder.replace :

    def __del__(self):
        try:
            self.close_driver()
        except Exception:
            pass



 def close_driver(self):
        print("Closing chromedriver gracefully.")
        self.driver.quit()
        # WIDNOWS LOGIC, probably needs different for Linux.
        path_with_forward_slashes = self.user_data_folder.replace("\\", "/")
        path_with_double_backslashes = self.user_data_folder.replace("/", "\\\\")

        # Formulate the wmic query, this check for both - forward slased and non forward slashed folder paths,
        # as it seems like both are used to spawn the processes.
        query = (
            f'wmic process where "(name=\'chrome.exe\' and commandline like \'%{path_with_forward_slashes}%\') '
            f'or (name=\'chrome.exe\' and commandline like \'%{path_with_double_backslashes}%\')" get processid')

        # Execute the query
        result = os.popen(query).read()

        # Extract process IDs from the result
        process_ids = [line.strip() for line in result.splitlines() if line.strip().isdigit()]

        # Kill each process
        for pid in process_ids:
            os.system(f'taskkill /f /pid {pid}')

@bigcharl
Copy link

bigcharl commented Dec 8, 2023

Made this workaround which has been bulletproof enough to run in a loop for a couple days with no issues, similar to @typhoon93's approach. I'm not skilled enough to add this to uc's init and PR but I'm sure it's possible. Apparently the quit() is "crashing" the driver and the crashpad process lingers(?), same goes for the renderer

import undetected_chromedriver as uc
from selenium.webdriver.chrome.options import Options
import psutil


options = Options()
options.add_argument('--headless')
driver = uc.Chrome(options=options)
driver.get('https://nowsecure.nl')
driver.quit()

def terminate_crashpad_processes():
    target_type = ['--type=crashpad-handler', '--type=renderer']

    for process in psutil.process_iter(['pid', 'name', 'cmdline']):
        if process.info['name'] == 'chrome.exe' and any(tt in process.info['cmdline'] for tt in target_type):
            try:
                psutil.Process(process.info['pid']).terminate()
                print(f"Terminated (PID: {process.info['pid']})")
            except Exception as e:
                print(f"Error terminating (PID: {process.info['pid']}): {e}")

terminate_crashpad_processes()

@ArtemBernatskyy
Copy link

Same, crashes when used headless with persistent session, not crashes when non headless with persistent session

@martinrotter
Copy link

Thanks for the workaround.

@fygarcia
Copy link

The short term fix in this issue for me was addressing the error line:
File "[...].venv\Lib\site-packages\undetected_chromedriver_init_.py", line 799, in quit
I added 'finally' and 'break' to the end if the if clause, inside the for loop:

    if (
        hasattr(self, "keep_user_data_dir")
        and hasattr(self, "user_data_dir")
        and not self.keep_user_data_dir
    ):
        for _ in range(5):
            try:
                shutil.rmtree(self.user_data_dir, ignore_errors=False)
            except FileNotFoundError:
                pass
            except (RuntimeError, OSError, PermissionError) as e:
                logger.debug(
                    "When removing the temp profile, a %s occured: %s\nretrying..."
                    % (e.__class__.__name__, e)
                )
            else:
                logger.debug("successfully removed %s" % self.user_data_dir)
                break
            finally:    # <<<-- added a finally and break
                break # time.sleep(0.1) <<<-- 

without this, the code was reaching 'break' and trying to perform actions continuously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants