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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:15:04