简体   繁体   中英

Selenium doesn't quit on KeyboardInterrupt (Python)

I'm trying to close Firefox instance that my app has opened when user interrupts the program. But selenium doesn't close the window. Here is a sample code that shows the problem:

import time

from selenium import webdriver

driver = webdriver.Firefox()

try:
    while True:
        driver.get("https://google.com")
        time.sleep(5)
except KeyboardInterrupt:
    print("Quitting")
    driver.quit()
    print("Done")

When I hit Ctrl+C, I see "Quitting" printed on the console, a few moments later, I see "Done" printed to the console and program ends. But firefox window remains open. How can I solve this issue?

Edit:

import time

from selenium import webdriver

driver = webdriver.Firefox()

try:
    for i in range(5):
        print("Looping")
        driver.get("https://google.com")
        time.sleep(5)
except KeyboardInterrupt:
    print("Quitting")
    driver.quit()
    print("Done")
driver.quit()
print("After loop and stuff")

This won't work neither. If you wait the loop out, browser closes successfully. But if you hit Ctrl+C in the middle of the loop, browser remains open.

I did a research with this issue and check all possible resource available on Stackoverflow and Selenium discussion forum on github.

Same issue has raised here and closed later on due to no proper solution. You can check details here. This issue specific to Windows and firefox. It is working fine on MAC OS. The main reason I get to know it happening due to Geckodriver is getting crash, here you can check that geckodriver-logs

They have tried with Latest Python bindings and latest Geckodriver too. No clean solution is available instead a workaround with killing firefox.exe process generated by Firefox driver.

Please have a look.

    tasklist = check_output(["tasklist", "/fi", "imagename eq firefox.exe"], shell=True).decode()
    currentFFIDs = re.findall(r"firefox.exe\s+(\d+)", tasklist)

    driver = webdriver.Firefox(options=opts, executable_path='./bin/geckodriver.exe')

    tasklist = check_output(["tasklist", "/fi", "imagename eq firefox.exe"], shell=True).decode()
    firefoxIds = set(re.findall(r"firefox.exe\s+(\d+)", tasklist)).difference(currentFFIDs)

 # do your stuff

    try:
        driver.close()
        driver.quit()

        # Could't close the driver via normal means-- Force Close #
        except:
            taskkill = 'taskkill /f '+''.join(["/pid "+f+" " for f in firefoxIds]).strip()
            check_output(taskkill.split(), shell=True)
            print("\nHAD TO FORCE-CLOSE FIREFOX", flush=True)

You can try to use with statement in you code, details can be found here :

import time
from selenium import webdriver

driver = webdriver.Firefox()

with driver:
    while True:
        driver.get("https://google.com")
        time.sleep(5)

If you want to catch KeyboardInterrupt or/and SystemExit , you can find useful information here .

I tested my code and code below in terminal, and Firefox quite as expected:

import time
from selenium import webdriver

driver = webdriver.Firefox()

try:
    for i in range(5):
        print("Looping")
        driver.get("https://google.com")
        time.sleep(5)
except KeyboardInterrupt:
    print("quitting: KeyboardInterrupt")
finally:
    driver.quit()
    print("Done")

There is no terminating condition supplied for while loop.... Your while loop is running endlessly. Keyboard interrupt block is never executed as the control doesn't get out of the while loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM