跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何使用 Selenium 稳健提取动态聊天框中的 AI 响应内容

本文详解如何通过精准定位策略(XPath + CSS 组合)、显式等待与 DOM 结构分析,可靠获取基于 MUI 构建的聊天界面中最新 AI 回复文本,解决因动态渲染、类名混淆导致的 find_element 失败问题。 本文详解如何通过精准定位策略(xpath + css 组合)、显式等待与 dom 结构分析,可靠获取基于 mui 构建的聊天界面中最新 ai 回复文本,解决因动态渲染、类名混淆导致的 `find_element` 失败问题。 在自动化测试或 RPA 场景中,使用 Selenium 提取聊天机器人响应常面临一个典型困境: 元素存在但内容为空、定位器失效、或文本提取返回空字符串 。尤其当目标应用采用 Material-UI(MUI)构建,且大量使用动态生成的 CSS 类名(如 css-liwoqsn、css-107u4gk)时,传统依赖 class 名的 CSS 选择器极易失效——这些类名可能随构建版本、主题或组件重渲染而变更,不具备稳定性。 根本原因在于:你当前代码中尝试用 .text 直接读取
的文本内容,但该容器内部实际文本分散在嵌套的

    标签中,且可能存在空白

      节点。直接调用 .text 会合并所有子文本(含不可见空白),并忽略 HTML 结构语义,极易导致空值或截断。 ✅ 正确做法是: 先稳定定位到最新响应容器,再精确提取其内真实可见文本节点的内容 。 ✅ 推荐解决方案:XPath 定位 + 深度文本提取 以下为经过验证的健壮实现(已整合显式等待、容错处理与语义化提取):
      from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException, NoSuchElementException def get_response(driver, timeout=15): """ 稳健获取最新聊天响应文本 使用 XPath 精准定位顶部最新响应块,并递归提取所有非空

      /

        /
      • 文本 """ print("Waiting for latest response...") try: # ✅ 关键:用 XPath 定位最上方的响应容器(结构最稳定) latest_container = WebDriverWait(driver, timeout).until( EC.presence_of_element_located(( By.XPATH, '//*[@id="__next"]/main/div/span/div/div[2]/div/div/div/div[2]/div[1]' )) ) except TimeoutException: raise RuntimeError("Timeout: Latest chat response container not found. Check page structure or network delay.") try: # ✅ 关键:不再依赖 .text,而是查找所有有意义的文本子元素 # 查找该容器内所有

          及其子
        • (覆盖段落与列表场景) text_elements = latest_container.find_elements( By.XPATH, ".//p[normalize-space() != ''] | .//ul//li[normalize-space() != '']" ) # 提取去重、去空白后的纯文本行 lines = [elem.text.strip() for elem in text_elements if elem.text.strip()] # 若无 p/li,则回退到直接提取 .content 区域的可见文本(兼容其他结构) if not lines: content_div = latest_container.find_element(By.CSS_SELECTOR, ".content.MuiBox-root") lines = [line.strip() for line in content_div.text.splitlines() if line.strip()] response = "\n".join(lines) print(f"Extracted response: {repr(response[:50] + '...' if len(response) > 50 else response)}") return response except NoSuchElementException: raise RuntimeError("Failed to locate text elements inside response container. HTML structure may have changed.")
      ⚠️ 关键注意事项与最佳实践 避免 implicitly_wait 与 WebDriverWait 混用 :你的原始代码中同时使用了 driver.implicitly_wait(15) 和 WebDriverWait,这会导致等待逻辑冲突。✅ 统一使用显式等待(WebDriverWait) ,并在初始化 driver 后设 driver.implicitly_wait(0) 清除隐式等待。 勿依赖动态 CSS 类名 :css-liwoqsn、css-107u4gk 等是 MUI 的哈希类名,每次构建可能不同。✅ 优先使用语义化属性(如 data-section="copilot_chat")、稳定 ID(如 id="gtiriww2a0souw9")或结构化 XPath 。 处理空白与富文本 :聊天响应常含空

      、换行

      • 列表。直接 .text 会丢失结构信息且易混入空白。✅ 使用 normalize-space() XPath 函数过滤空白节点,并分段提取提升可读性。 超时与重试机制 :AI 响应有延迟,建议将 WebDriverWait 超时设为 15–30 秒,并捕获 TimeoutException 提供清晰错误上下文。 验证响应完整性 :可在 get_response() 后添加断言:
        assert response, f"Empty response extracted from chat container at {datetime.now()}"
        ✅ 总结 Selenium 提取聊天响应失败,本质是 定位策略与 DOM 解析方式不匹配 。本文方案通过: ① 用绝对 XPath 锁定最新响应容器 (规避动态 class 不稳定); ② 用语义化 XPath 提取

        /

      • 等有效文本节点 (避免 .text 的盲目合并); ③ 显式异常处理与结构降级逻辑 (保障鲁棒性)。 这套方法已在多个 MUI/Next.js 聊天界面中验证有效,可作为自动化对话采集的标准实践。

相关文章