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

Selenium爬取YouTube评论偶发element not attached错误求助

问题成因

你遇到的是Selenium中常见的StaleElementReferenceException错误,核心原因如下:

  1. 代码执行初期就通过find_elements_by_xpath把所有评论元素一次性存到了l_com列表中,这些元素本质是指向当时页面DOM树节点的引用
  2. 循环过程中执行了点击回复按钮、window.history.go(-1)回退页面的操作,会触发页面DOM树重新渲染,甚至整个页面重载
  3. 回退后当前页面的DOM树已经是全新的,之前存在l_com里的所有引用都不属于当前DOM,因此访问i.text或者调用元素方法时就会抛出「element is not attached to the page document」错误
解决方案

可以按照以下逻辑修改代码修复问题:

  • 不要提前存储评论元素对象,改为先获取所有评论的文本和对应位置索引,只存可序列化的字符串和数字,不存DOM引用
  • 处理单条评论完成回退后,先等待页面评论区域渲染完成,再重新获取当前页的评论元素列表,再处理下一条
  • 不要用全局索引n匹配评论和回复按钮,改为从当前评论元素出发查找对应子级的回复按钮,避免索引错位
  • 可以增加异常捕获逻辑,遇到过时元素错误时自动重试获取元素

如果社区评论是懒加载的,需要先滚动页面触发所有评论加载完成后再执行预扫描逻辑,避免漏掉后续未加载的评论。

修改后参考代码:

from selenium import webdriver as wbd
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException

attend = wbd.support.ui.WebDriverWait
avec = wbd.common.by.By

com_commu = {}
terme = 'vidéo'
délai = 5

# 第一步:预扫描所有评论,记录符合关键词的索引,不存储易失效的DOM元素对象
valid_indexes = []
# 首次获取评论列表
attend(driver, délai).until(EC.presence_of_element_located((avec.XPATH, '//*[@id="content-text"]')))
l_com = driver.find_elements_by_xpath('//*[@id="content-text"]')
for idx, com in enumerate(l_com):
    try:
        if terme in com.text:
            valid_indexes.append(idx)
        else:
            print(f'Il n\'y a pas le terme "{terme}" dans le post : {com.text}')
    except StaleElementReferenceException:
        # 预扫描时如果遇到元素失效,重新获取评论列表后重试
        l_com = driver.find_elements_by_xpath('//*[@id="content-text"]')
        if terme in l_com[idx].text:
            valid_indexes.append(idx)

# 第二步:逐个处理符合要求的评论
for idx in valid_indexes:
    # 每次处理前重新获取最新的评论和回复按钮列表,避免引用失效
    attend(driver, délai).until(EC.presence_of_element_located((avec.XPATH, '//*[@id="content-text"]')))
    current_coms = driver.find_elements_by_xpath('//*[@id="content-text"]')
    reply_btns = driver.find_elements_by_xpath('//*[@id="reply-button-end"]/ytd-button-renderer/a')
    
    current_com_text = current_coms[idx].text
    # 点击对应评论的回复按钮
    reply_btns[idx].click()
    # 等待回复内容加载完成
    attend(driver, délai).until(EC.presence_of_element_located((avec.XPATH, '//*[@id="body"]')))
    com_commu[current_com_text] = driver.find_elements_by_xpath('//*[@id="body"]')
    # 回退到评论列表页
    driver.execute_script("window.history.go(-1)")
    # 等待回退后评论列表重新渲染完成
    attend(driver, délai).until(EC.presence_of_element_located((avec.XPATH, '//*[@id="content-text"]')))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:54:07