Python Selenium Detect when the browser is closed
Asked Answered
S

4

8

Right now, I use this as a way to detect when the user closes the browser:

while True:
    try:
        # do stuff
    except WebDriverException:
        print 'User closed the browser'
        exit()

But I found out that it is very unreliable and a very bad solution since WebDriverException catches a lot of exception (if not all) and most of them are not due to the user closing the browser.

My question is: How to detect when the user closes the browser?

Seften answered 4/8, 2018 at 11:56 Comment(12)
You can use Browser Unreachable exception. seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/…Fabrianna
HI, I am sorry I misunderstood that Exception is common across all the bindings, We use Selenium::WebDriver::Error::NoSuchWindowError in Ruby Selenium Binding, So I suggested you! Okay you may search the corresponding Exception for Python Binding.Inexhaustible
Check out this discussion : #18619621Combination
@Combination This discussion might not help, as here browser will be closed by user's action, not by calling driver.quit().Fabrianna
@RajKamal : why would any user close the window(s) when the script is running? Any appropriate use case ?Combination
@RajKamal Exactly, that's what I observed as well.Inexhaustible
@Combination The script is like an 'assistant' working along the user. I could have the user to close the browser via some UI but to have it more user-friendly I want the script to automatically detect when the user close the driver so it can do few stuff (saving data..etc.) before also quiting.Seften
Again how do you do that manually ? How do you get to know about saving data before quick ? Any alert , any notification ? If that is the case, then it can be handled very easily.Combination
@Combination Unfortunately that is not the case. The user can close the browser anytime he/she desire. I can think of a few 'ugly' 'roundabout' solution like having win32gui check if the window still exist or through tasklist check if the browser window is still running but I am searching for the most selenium-ish way of solving this.Seften
check if your browser instance is None.Priestley
@RajKamal, because they are users :) Users can and may do anything, even if it seems crazy.Platinum
@CoreyGoldberg I can confirm that doesn't work. In fact, none of the browser object's properties appear to change when the user manually closes the browser. I was trying to catch that so I could re-open the browser programmatically, but I've given up. "What happens if you close the browser?" is like "What happens if you pull the plug on the computer?" or "What happens if you slam the keyboard over the monitor?" You can't guard against it in software.Mlle
P
8

I would suggest using:

>>> driver.get_log('driver')
[{'level': 'WARNING', 'message': 'Unable to evaluate script: disconnected: not connected to DevTools\n', 'timestamp': 1535095164185}]

since driver logs this whenever user closes browser window and this seems the most pythonic solution.

So you can do something like this:

DISCONNECTED_MSG = 'Unable to evaluate script: disconnected: not connected to DevTools\n'

while True:
    if driver.get_log('driver')[-1]['message'] == DISCONNECTED_MSG:
        print 'Browser window closed by user'
    time.sleep(1)

If you're interested you can find documentation here.

I am using chromedriver 2.41 and Chrome 68.

Polyamide answered 24/8, 2018 at 8:5 Comment(1)
Very helpful answerJanelljanella
E
5

Similar to Federico Rubbis answer, this worked for me:

import selenium
from selenium import webdriver
browser = webdriver.Firefox()

# Now wait if someone closes the window
while True:
    try:
        _ = browser.window_handles
    except selenium.common.exceptions.InvalidSessionIdException as e:
        break
    time.sleep(1)

# ... Put code here to be executed when the window is closed

Probably not a solution that is stable across versions of selenium.
EDIT: Not even stable across running from different environments. Ugly fix: Use BaseException instead of selenium.common.exceptions.InvalidSessionIdException .

Ekaterinodar answered 8/9, 2019 at 15:45 Comment(1)
I used selenium.common.exceptions.WebDriverException thanks.Memorabilia
B
0

this worked for me:

#libraries
from selenium.webdriver.chrome.options import Options
from selenium import webdriver

#open browser in kiosk mode
def openBrowser():
    chrome_options = Options()
    chrome_options.add_argument("--kiosk")
    path = '"C:\\Users\\an8799\Documents\Repositorio\\testes\chromedriver.exe"'
    driver = webdriver.Chrome(path, chrome_options=chrome_options)
    driver.get('https://google.com.br')
    return driver

#verify if browser is opened.
def uptdateBrowser(browser):
    try:
       _ = browser.window_handles
       print('windon opened')
       return 0, 0
    except:
        newbrowser = openBrowser()
        print('window closed')
        return 1, newbrowser

#start browser verification loop
def main():
    browser = openBrowser()
    while(True):
        flagNew, newB = uptdateBrowser(browser)
        if flagNew == 1:
            browser = newB
#call main loop
if __name__ == '__main__':
    main()
Blazonry answered 30/8, 2022 at 11:25 Comment(0)
C
0

Although Federico Rubbi answer works, it doesn't work always. When the user closes the webdriver, the driver.get_log('driver') will raise an excepton.

The following function works quite well, as far as i tested it (Chrome version 110). It also works with undetected chromedriver.

from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from urllib3.exceptions import NewConnectionError, MaxRetryError


def is_driver_open(driver: webdriver.Chrome) -> bool:
    """
    Checks if the webdriver is still open by checking the logs.
    """
    disconnected_msg = 'Unable to evaluate script: disconnected: not connected to DevTools\n'
    disc_msg = "Unable to evaluate script: no such window: target window already closed" \
               "\nfrom unknown error: web view not found\n"
    message_listener = "subscribing a listener to the already connected DevToolsClient"
    if driver:
        try:
            log = driver.get_log('driver')
        except (ConnectionRefusedError, MaxRetryError, NewConnectionError):
            # The webdriver is closed, the connection to the Chrome is refused.
            return False
        print(f"is_driver_open(): log: {log}")
        if len(log) != 0:  # This does not catch all other messages.
            if log[-1]['message'] in (disconnected_msg, disc_msg):
                print("Webdriver is closed")
                return False
            elif message_listener in log[-1]['message']:
                # It's not closed.
                return True
            else:
                return True
        else:  # No errors, return True.
            return True


if __name__ == "__main__":
    options = Options()
    driver = webdriver.Chrome(options=options)
    print(f"Is driver open: {is_driver_open(driver)}")
    driver.quit()
    print(f"Is driver open: {is_driver_open(driver)}")
Chitterlings answered 1/3, 2023 at 20:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.