如何用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
相关产品推荐
相关产品推荐

