You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过按键控制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,操作同一个浏览器会话。

操作步骤

  1. 先启动Selenium Server(命令行执行,确保ChromeDriver在系统PATH中):
chromedriver --port=4444
  1. 修改代码,用远程连接获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:33:13