Selenium Python使用MutationObserver监听DOM倒计时元素变更问题
问题修复方案
一、MutationObserver未触发的核心原因
- 选择器不可靠:注入JS时使用的超长层级选择器容错性极低,页面结构、类名的动态变化都会导致
targetNode为null,监听空对象自然不会触发回调。 - 加载时机错误:点击比赛卡片后没有等待详情页元素渲染完成就注入脚本,此时倒计时元素还不存在,
targetNode为空。 - 监听配置不全:现有配置没有开启
characterData: true,倒计时修改文本节点内容的变更无法被捕获。
二、修复后的代码实现
1. 先优化元素定位与等待逻辑
import time import selenium from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC URL = 'https://live.dartsdata.com/' # 如果需要收集浏览器日志可以加这个配置 options = webdriver.ChromeOptions() options.set_capability('goog:loggingPrefs', {'browser': 'ALL'}) driver = webdriver.Chrome('/Users/hjam/downloads/chromedriver', options=options) driver.get(URL) time.sleep(1) matches = driver.find_elements(By.XPATH, ".//*[@class='sr-match__wrapper srt-base-1 sr-ml-list__match']") matches[0].click() # 显式等待倒计时元素加载完成 wait = WebDriverWait(driver, 10) countdown_elem = wait.until(EC.presence_of_element_located((By.XPATH, ".//*[@class='sr-lmt-0-ms-countdown__time srt-primary-7 srm-large']")))
2. 修正MutationObserver注入逻辑
直接将Selenium定位好的元素传入JS,不用写死选择器,同时补全监听配置:
driver.execute_script(""" const targetNode = arguments[0]; const config = { attributes: true, childList: true, subtree: true, characterData: true }; window.latestCountdown = targetNode.textContent; const callback = function(mutationsList, observer) { for(const mutation of mutationsList) { window.latestCountdown = targetNode.textContent; console.log('Time is ticking', window.latestCountdown); } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); """, countdown_elem)
三、将监听结果输出到Python控制台的两种方法
方法1:读取全局变量(更稳定)
Python侧循环读取JS中定义的全局变量即可:
while True: current_countdown = driver.execute_script("return window.latestCountdown") print(f"当前倒计时:{current_countdown}") time.sleep(1)
方法2:读取浏览器控制台日志
需要提前配置Chrome的日志收集能力(前面初始化driver时已经加了相关配置),循环拉取日志即可:
while True: browser_logs = driver.get_log('browser') for log in browser_logs: if 'Time is ticking' in log['message']: print(f"收到倒计时更新:{log['message']}") time.sleep(0.5)
内容的提问来源于stack exchange,提问作者HJA24
相关产品推荐
相关产品推荐

