我有一个 Python 脚本,它使用 Selenium 来自动化浏览器。我正在使用Windows。我希望能够通过按
CTRL+C
来中断脚本。但即使我捕获了异常,网络驱动程序也会在中断时终止。
考虑以下因素:
from selenium import webdriver
driver = webdriver.Chrome()
try:
while True:
pass
except KeyboardInterrupt:
print('KeyboardInterrupt caught')
driver.get('https://www.google.com') # will fail
按下
CTRL+C
时,网络驱动程序窗口立即关闭。对驱动程序方法的任何后续调用都会引发 urllib3 异常。
在某些情况下,这种行为非常不方便——如果我在 Python REPL 中使用 webdriver 并且我需要通过中断终止某些函数,我不希望它破坏我的驱动程序实例。同样,在测试较长的自动化流程时,如果出现问题,我希望能够手动取消执行,但允许浏览器窗口保持打开状态以进行调试。
我可以按照建议在本地计算机上使用 Remote webdriver 实例(通过 Selenium Grid),但我不想增加管理网格的复杂性。 这里提到的解决方案
似乎只适用于Unix。Webdriver 终止的原因是在 Windows 中,中断执行的
传播到子进程
。 Selenium 的 webdriver 是一个单独的进程(由 Popen 生成),程序通过 HTTP 与之通信。可以使用标志实例化 Selenium Service 对象,该对象启动 webdriver 子进程,以便在单独的进程组中创建 webdriver:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import subprocess
serv = Service(popen_kw={"creation_flags": subprocess.CREATE_NEW_PROCESS_GROUP})
driver = webdriver.Chrome(service = serv)
现在驱动程序将不会收到来自父进程的任何“信号”!经过几个小时的寻找适当的解决方案并最终检查 Selenium 的源代码发现这是可能的,我创建了这个问答。我希望它对其他人有帮助。