如何在Selenium中通过execute_script让MutationObserver通知Python脚本变更事件
实现JS侧MutationObserver通知Python侧的3种可行方案
方案1:全局变量轮询(实现最简单)
JS侧触发变更时将状态和数据挂载到window全局对象下,Python侧定时调用execute_script读取变量即可。
- JS注入代码:
window.__mutationFlag = false window.__mutationDetail = null const observer = new MutationObserver((mutations) => { // 替换为你的目标变更匹配逻辑 const isTargetChange = mutations.some(m => m.addedNodes.length > 0) if (isTargetChange) { window.__mutationFlag = true window.__mutationDetail = mutations } }) observer.observe(document.body, { childList: true, subtree: true })
- Python侧代码:
import time from selenium import webdriver driver = webdriver.Chrome() driver.get("目标页面URL") # 注入上述MutationObserver代码 driver.execute_script(""" // 上面的JS代码直接粘贴到这里 """) while True: # 读取全局标记 has_change = driver.execute_script("return window.__mutationFlag") if has_change: change_detail = driver.execute_script("return window.__mutationDetail") print("收到变更通知:", change_detail) # 重置标记等待下一次变更 driver.execute_script("window.__mutationFlag = false; window.__mutationDetail = null;") # 此处编写你的业务逻辑 time.sleep(0.5) # 轮询间隔可按需调整
方案2:自定义事件+显式等待(性能最优)
JS触发变更时抛出自定义DOM事件,Python侧用Selenium显式等待替代轮询,减少无效请求开销。
- JS注入代码:
window.__eventFired = false window.__eventData = null // 监听自定义事件,更新全局状态 document.addEventListener("targetMutation", (e) => { window.__eventFired = true window.__eventData = e.detail }) const observer = new MutationObserver((mutations) => { const isTargetChange = mutations.some(m => m.addedNodes.length > 0) if (isTargetChange) { // 抛出自定义事件,携带变更数据 const event = new CustomEvent("targetMutation", {detail: mutations}) document.dispatchEvent(event) } }) observer.observe(document.body, { childList: true, subtree: true })
- Python侧代码:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait driver = webdriver.Chrome() driver.get("目标页面URL") driver.execute_script(""" // 上面的JS代码直接粘贴到这里 """) wait = WebDriverWait(driver, timeout=60) # 超时时间可自定义 while True: # 等待事件触发 wait.until(lambda d: d.execute_script("return window.__eventFired")) change_data = driver.execute_script("return window.__eventData") print("收到变更通知:", change_data) # 重置状态 driver.execute_script("window.__eventFired = false; window.__eventData = null;")
方案3:Console日志拦截(轻量无侵入)
JS触发变更时输出带特定标识的控制台日志,Python侧监听浏览器控制台日志匹配标识即可。
- JS注入代码:
const observer = new MutationObserver((mutations) => { const isTargetChange = mutations.some(m => m.addedNodes.length > 0) if (isTargetChange) { // 输出带固定前缀的日志,便于Python侧匹配 console.log("[MUTATION_NOTICE]", JSON.stringify(mutations)) } }) observer.observe(document.body, { childList: true, subtree: true })
- Python侧代码:
import time from selenium import webdriver from selenium.webdriver.chrome.options import Options opts = Options() # 开启浏览器日志采集能力 opts.set_capability("goog:loggingPrefs", {"browser": "ALL"}) driver = webdriver.Chrome(options=opts) driver.get("目标页面URL") driver.execute_script(""" // 上面的JS代码直接粘贴到这里 """) while True: # 拉取最新的浏览器控制台日志 logs = driver.get_log("browser") for log in logs: if "[MUTATION_NOTICE]" in log["message"]: print("收到变更通知:", log["message"]) time.sleep(1)
内容的提问来源于stack exchange,提问作者RafaelLeo
相关产品推荐
相关产品推荐

