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

如何用Python实现Selenium单会话操作同步复制到其他多会话?

实现思路

核心逻辑是捕获用户在可见Selenium会话窗口的所有操作事件,将事件参数同步转发到其余后台无头会话,执行相同操作。无需额外依赖复杂的图像识别工具,仅通过Selenium原生能力+JS注入即可实现。

实现步骤
  • 依赖安装:只需安装Selenium库以及对应浏览器的驱动(以Chrome为例需要ChromeDriver),安装命令为pip install selenium
  • 初始化多会话:仅第一个会话设置为可见模式,其余会话全部设置无头后台运行,所有会话同步打开目标网址
  • 注入事件监听:给可见会话的页面注入JS脚本,监听所有需要同步的用户操作(点击、输入、滚动、下拉等),将事件类型、元素定位、操作参数暂存在页面变量中供Python端拉取
  • 事件同步执行:Python端定期拉取可见会话的事件队列,遍历所有后台会话执行相同操作
  • 页面跳转适配:每次检测到可见会话页面跳转后,重新注入事件监听脚本,避免新页面无法上报操作
可运行示例代码
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time

# 可根据需求修改配置
SESSION_COUNT = 3  # 总会话数量
TARGET_URL = "https://www.baidu.com"  # 目标操作网址

# 初始化所有会话
drivers = []
for i in range(SESSION_COUNT):
    chrome_opt = Options()
    # 仅第一个会话可见,其余后台运行
    if i != 0:
        chrome_opt.add_argument("--headless=new")
    # 所有会话统一窗口大小,避免坐标偏移
    chrome_opt.add_argument("--window-size=1920,1080")
    chrome_opt.add_argument("--disable-blink-features=AutomationControlled")
    driver = webdriver.Chrome(options=chrome_opt)
    driver.get(TARGET_URL)
    drivers.append(driver)

main_driver = drivers[0]
slave_drivers = drivers[1:]

# 注入JS事件监听函数
def inject_event_listener(driver):
    js_script = """
    window.event_queue = window.event_queue || [];
    // 生成元素XPath定位的辅助函数
    function getXPath(element) {
        if (element.id !== '') return 'id("' + element.id + '")';
        if (element === document.body) return element.tagName;
        let ix = 0;
        let siblings = element.parentNode.childNodes;
        for (let i = 0; i < siblings.length; i++) {
            let sibling = siblings[i];
            if (sibling === element) return getXPath(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
            if (sibling.nodeType === 1 && sibling.tagName === element.tagName) ix++;
        }
    }
    // 监听点击事件
    document.addEventListener('click', function(e) {
        let xpath = getXPath(e.target);
        window.event_queue.push({type: 'click', xpath: xpath});
    }, true);
    // 监听输入事件
    document.addEventListener('input', function(e) {
        let xpath = getXPath(e.target);
        window.event_queue.push({type: 'input', xpath: xpath, value: e.target.value});
    }, true);
    // 监听滚动事件
    document.addEventListener('scroll', function() {
        window.event_queue.push({
            type: 'scroll', 
            top: document.documentElement.scrollTop || document.body.scrollTop,
            left: document.documentElement.scrollLeft || document.body.scrollLeft
        });
    }, true);
    """
    driver.execute_script(js_script)

inject_event_listener(main_driver)
last_url = main_driver.current_url

print("所有会话启动完成,操作主窗口即可同步到后台会话,按Ctrl+C停止运行")
try:
    while True:
        # 检测页面跳转,重新注入监听
        current_url = main_driver.current_url
        if current_url != last_url:
            time.sleep(1)
            inject_event_listener(main_driver)
            last_url = current_url
        # 拉取事件队列
        events = main_driver.execute_script("let e = window.event_queue || []; window.event_queue = []; return e;")
        if events:
            for event in events:
                # 同步所有从会话执行操作
                for slave in slave_drivers:
                    try:
                        if event['type'] == 'click':
                            slave.find_element(By.XPATH, event['xpath']).click()
                        elif event['type'] == 'input':
                            elem = slave.find_element(By.XPATH, event['xpath'])
                            elem.clear()
                            elem.send_keys(event['value'])
                        elif event['type'] == 'scroll':
                            slave.execute_script(f"window.scrollTo({event['left']}, {event['top']})")
                    except:
                        # 单个会话操作失败不中断流程,可自行添加日志
                        pass
        time.sleep(0.1)
except KeyboardInterrupt:
    print("正在关闭所有会话")
    for d in drivers:
        d.quit()
注意事项
  • 示例仅实现了点击、输入、滚动三种常见操作,如需同步下拉选择、鼠标悬停、键盘快捷键等操作,只需在JS监听部分新增对应事件类型,Python端补充对应的操作逻辑即可
  • 示例默认用XPath做元素定位,你可以根据目标网站的特点替换为CSS选择器等其他定位方式,提升定位准确率
  • 如果目标网站有反爬机制、元素ID动态随机生成的情况,需要针对性优化定位逻辑,避免从会话出现元素找不到的问题
  • 如果需要同步坐标类操作(比如画布绘制),需要保证所有会话的窗口大小、缩放比例完全一致

内容的提问来源于stack exchange,提问作者rdy4sv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:15:02