gpt4 book ai didi

python - 在不关闭 Python 中的 Selenium Webdriver session 的情况下捕获 `KeyboardInterrupt`

转载 作者:IT老高 更新时间:2023-10-28 20:55:50 24 4
gpt4 key购买 nike

一个 Python 程序通过 Selenium WebDriver 驱动 Firefox。代码嵌入在 try/except block 中,如下所示:

session = selenium.webdriver.Firefox(firefox_profile)
try:
# do stuff
except (Exception, KeyboardInterrupt) as exception:
logging.info("Caught exception.")
traceback.print_exc(file=sys.stdout)

如果程序因错误而中止,WebDriver session 不会关闭,因此 Firefox 窗口保持打开状态。但是如果程序因 KeyboardInterrupt 异常而中止,Firefox 窗口就会关闭(我想是因为 WebDriver session 也被释放了),我想避免这种情况。

我知道这两个异常都通过同一个处理程序,因为我在这两种情况下都看到了 "Caught exception" 消息。

如何避免使用 KeyboardInterrupt 关闭 Firefox 窗口?

最佳答案

我有一个解决方案,但它很丑。

当按下 Ctrl+C 时,python 会收到一个中断信号 (SIGINT),该信号会在整个进程树中传播。Python 还会生成一个 KeyboardInterrupt,因此您可以尝试处理与您的进程的逻辑绑定(bind)的东西,但与子进程耦合的逻辑不会受到影响。

要影响将哪些信号传递给您的子进程,您必须在通过 subprocess.Popen 生成进程之前指定应如何处理信号。

有多种选择,这个取自another answer :

import subprocess
import signal

def preexec_function():
# Ignore the SIGINT signal by setting the handler to the standard
# signal handler SIG_IGN.
signal.signal(signal.SIGINT, signal.SIG_IGN)

my_process = subprocess.Popen(
["my_executable"],
preexec_fn = preexec_function
)

问题是,调用Popen的不是你,即delegated to selenium .有various discussions就这样。根据我收集到的其他解决方案,如果在调用 Popen 之前未立即执行屏蔽,则其他尝试影响信号屏蔽的解决方案很容易失败。

另外请记住,有一个 big fat warning regarding the use of preexec_fn in the python documentation ,因此请自行决定使用它。

“幸运”python 允许在运行时覆盖函数,所以我们可以这样做:

>>> import monkey
>>> import selenium.webdriver
>>> selenium.webdriver.common.service.Service.start = monkey.start
>>> ffx = selenium.webdriver.Firefox()
>>> # pressed Ctrl+C, window stays open.
KeyboardInterrupt
>>> ffx.service.assert_process_still_running()
>>> ffx.quit()
>>> ffx.service.assert_process_still_running()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 107, in assert_process_still_running
return_code = self.process.poll()
AttributeError: 'NoneType' object has no attribute 'poll'

monkey.py 如下:

import errno
import os
import platform
import subprocess
from subprocess import PIPE
import signal
import time
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common import utils

def preexec_function():
signal.signal(signal.SIGINT, signal.SIG_IGN)

def start(self):
"""
Starts the Service.
:Exceptions:
- WebDriverException : Raised either when it can't start the service
or when it can't connect to the service
"""
try:
cmd = [self.path]
cmd.extend(self.command_line_args())
self.process = subprocess.Popen(cmd, env=self.env,
close_fds=platform.system() != 'Windows',
stdout=self.log_file,
stderr=self.log_file,
stdin=PIPE,
preexec_fn=preexec_function)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
except TypeError:
raise
except OSError as err:
if err.errno == errno.ENOENT:
raise WebDriverException(
"'%s' executable needs to be in PATH. %s" % (
os.path.basename(self.path), self.start_error_message)
)
elif err.errno == errno.EACCES:
raise WebDriverException(
"'%s' executable may have wrong permissions. %s" % (
os.path.basename(self.path), self.start_error_message)
)
else:
raise
except Exception as e:
raise WebDriverException(
"The executable %s needs to be available in the path. %s\n%s" %
(os.path.basename(self.path), self.start_error_message, str(e)))
count = 0
while True:
self.assert_process_still_running()
if self.is_connectable():
break
count += 1
time.sleep(1)
if count == 30:
raise WebDriverException("Can not connect to the Service %s" % self.path)

code for start is from selenium ,添加的行突出显示。这是一个粗略的黑客,它可能会咬你。祝你好运:D

关于python - 在不关闭 Python 中的 Selenium Webdriver session 的情况下捕获 `KeyboardInterrupt`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27495376/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com