我正在使用 Selenium 编写一个 Python 脚本来自动执行网站上的任务。在我的脚本中,我有一个循环在网页上执行各种操作,例如检查输入和单击按钮。但我希望能够通过返回主页并重新启动循环来手动使驱动程序重新启动程序。我认为这需要使用多线程来完成,因为我无法停止主循环来检查键盘输入,因为循环可能需要几分钟才能完成并重新启动。线程之间的驱动程序应该保持相同。
我尝试使用
multiprocessing
模块,因为它允许使用 proc.terminate()
终止线程,与 threading
模块不同。但是,我遇到了一个问题:multiprocessing
无法在进程之间直接共享全局变量(Selenium WebDriver)。
(我知道突然停止线程不是一个好主意,但由于这是手动输入,因此应该可以随时停止。)
if __name__ == '__main__':
print("Starting program...")
proc = multiprocessing.Process(target=programThread)
proc.start()
is_pressing = False
while True:
if keyboard.is_pressed('ctrl+f10'):
if not is_pressing:
print("Resetting Program...")
is_pressing = True
proc.terminate()
if resetProgram(driver):
proc = multiprocessing.Process(target=programThread)
proc.start()
else:
print("Could not reset program, exiting...")
exit()
continue
if keyboard.is_pressed('ctrl+f9'):
if not is_pressing:
print("Stopping Program...")
is_pressing = True
proc.terminate()
continue
is_pressing = False
我的问题是:如何启用手动输入来重新启动脚本而不中断正在进行的自动化循环?我是否应该使用多处理,如果是,如何解决进程之间共享 WebDriver 的问题?
好吧,所以我认为我最初的想法可能无法正确实现,但我找到了一种解决方法,只需不使用相同的驱动程序并终止驱动程序的进程并使用 psutil 杀死仍然打开的 chrome 窗口
parent_processes = []
for proc in psutil.process_iter(attrs=['pid', 'name', 'connections']):
if proc.name() != 'chrome.exe':
continue
process = psutil.Process(proc.info['pid'])
if process.ppid() not in parent_processes:
parent_processes.append(process.ppid())
for parent in parent_processes:
parent_process = psutil.Process(parent)
if parent_process.name() == 'chrome.exe':
if "VSCODE_NONCE" in parent_process.environ():
print("Terminating dead selenium instance...")
parent_process.terminate()
这可能不是最优雅的解决方案,但它确实有效。 之后,我只需重新创建原始线程,一切都会按预期重新启动