如何通过按键控制Python中Selenium WebDriver实现脚本重启?
问题与解决方案:Selenium自动化脚本的手动重启控制
需求与问题背景
- 基于Python+Selenium编写网站自动化脚本,核心是一个耗时数分钟的循环,执行页面检查、按钮点击等操作
- 需要通过快捷键(如Ctrl+F10)手动触发:回到主页并重启循环;Ctrl+F9终止脚本
- 无法在循环内部插入键盘检查(会中断自动化流程),因此考虑多线程/多进程方案,但要求WebDriver实例在控制流程中保持一致
- 尝试
multiprocessing时遇到瓶颈:进程间无法直接共享WebDriver实例,而threading不支持强制终止线程
尝试的代码示例
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
解决方案1:线程+协作式中断(推荐)
不用强制终止线程,而是给自动化循环加全局信号标记,键盘监听线程负责修改标记,自动化循环定期检查标记(如每次迭代开始时),实现优雅重启/终止,同时保证WebDriver实例全程在同一线程中,无共享问题。
示例代码
import threading import keyboard from selenium import webdriver # 全局信号标记 should_restart = False should_stop = False driver = None def automation_loop(): global driver, should_restart, should_stop driver = webdriver.Chrome() driver.get("你的主页URL") while True: # 优先检查终止信号 if should_stop: driver.quit() break # 检查重启信号 if should_restart: driver.get("你的主页URL") should_restart = False # 重置标记 print("已回到主页,重启循环") # --- 此处编写你的自动化操作逻辑 --- # 示例: # driver.find_element(By.ID, "input_box").send_keys("测试内容") # driver.find_element(By.ID, "submit_btn").click() # ... def keyboard_listener(): global should_restart, should_stop while True: if keyboard.is_pressed('ctrl+f10'): should_restart = True print("收到重启信号") # 防止快捷键重复触发 while keyboard.is_pressed('ctrl+f10'): pass elif keyboard.is_pressed('ctrl+f9'): should_stop = True print("收到终止信号") while keyboard.is_pressed('ctrl+f9'): pass if __name__ == '__main__': print("Starting program...") # 启动自动化线程 auto_thread = threading.Thread(target=automation_loop) auto_thread.start() # 启动键盘监听线程 key_thread = threading.Thread(target=keyboard_listener) key_thread.start() # 等待线程结束 auto_thread.join() key_thread.join()
方案优势
- 避免强制终止线程导致的WebDriver资源泄漏、浏览器进程残留
- 逻辑简单,符合线程协作的最佳实践
- WebDriver实例全程在同一线程,无跨进程/线程共享问题
解决方案2:多进程+WebDriver远程连接(满足强制终止需求)
如果一定要使用multiprocessing的强制终止功能,可以通过Selenium远程WebDriver实现进程间的驱动共享:所有进程连接同一个独立运行的Selenium Server,操作同一个浏览器会话。
操作步骤
- 先启动Selenium Server(命令行执行,确保ChromeDriver在系统PATH中):
chromedriver --port=4444
- 修改代码,用远程连接获取WebDriver实例:
import multiprocessing import keyboard from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities def automation_loop(): # 连接远程WebDriver服务 driver = webdriver.Remote( command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME ) driver.get("你的主页URL") while True: # --- 此处编写你的自动化操作逻辑 --- pass def reset_program(): # 连接远程驱动,回到主页 driver = webdriver.Remote( command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME ) driver.get("你的主页URL") driver.quit() # 关闭当前会话连接,不关闭浏览器 return True if __name__ == '__main__': print("Starting program...") proc = multiprocessing.Process(target=automation_loop) 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 reset_program(): proc = multiprocessing.Process(target=automation_loop) 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() # 关闭远程驱动和浏览器 driver = webdriver.Remote( command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME ) driver.quit() exit() continue is_pressing = False
方案注意点
- 强制终止进程可能导致远程会话残留,需额外处理
- 必须保证Selenium Server全程运行,否则无法连接
- 资源占用高于线程方案,易出现会话异常
内容的提问来源于stack exchange,提问作者Ewan
相关产品推荐
相关产品推荐

