使用Selenium获取character.ai完整回复:等待元素加载完成问题
解决Selenium获取Character.AI完整回复的问题
问题描述
使用Selenium与Character.AI机器人交互时,发送消息后只能获取到部分回复,原因是承载回复的div元素会持续流式更新,现有显式等待仅能等待元素出现,无法判断回复是否完成。
解决方案核心思路
Character.AI的回复为流式输出,需等待回复元素的文本内容稳定(连续一段时间内不再变化),才能确保获取完整回复。可通过自定义等待条件实现该逻辑。
修改后的完整代码
from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException, TimeoutException import undetected_chromedriver as uc import time chrome_options = Options() ignored_exceptions = (NoSuchElementException, StaleElementReferenceException) driver = uc.Chrome(options=chrome_options) driver.get("https://beta.character.ai/chat?char=YntB_ZeqRq2l_aVf2gWDCZl4oBttQzDvhj9cXafWcF8") # 修复AcceptButton选择器错误(移除多余的#) WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "AcceptButton"))).click() def wait_for_text_stabilize(element_locator, timeout=30, check_interval=0.5): """等待元素文本稳定,连续指定时长无变化则返回完整文本""" prev_text = "" stable_duration = 0 end_time = time.time() + timeout while time.time() < end_time: try: element = WebDriverWait(driver, 1).until(EC.visibility_of_element_located(element_locator)) current_text = element.text if current_text == prev_text: stable_duration += check_interval # 连续2秒文本无变化,判定回复完成 if stable_duration >= 2: return current_text else: prev_text = current_text stable_duration = 0 time.sleep(check_interval) except: # 元素更新过程中可能抛出异常,忽略后继续等待 time.sleep(check_interval) continue raise TimeoutException("回复文本未在指定时间内稳定") while True: # 等待最新回复稳定后获取完整内容 last_msg_locator = (By.CLASS_NAME, "markdown-wrapper-last-msg") full_reply = wait_for_text_stabilize(last_msg_locator) print(full_reply) # 处理用户输入并发送 msg = str(input("Send message: ")) input_box = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "user-input"))) input_box.clear() input_box.send_keys(msg) # 精准定位发送按钮,避免依赖索引导致错误 send_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'btn') and contains(text(), 'Send')]"))) send_btn.click()
关键优化点
- 自定义文本稳定检测:通过
wait_for_text_stabilize函数监测回复文本的变化状态,适配流式输出场景,确保获取完整内容。 - 修复选择器错误:修正原代码中
AcceptButton的ID选择器(移除多余的#)。 - 可靠的元素定位:改用XPATH定位发送按钮,避免依赖按钮列表索引引发的异常;输入框添加
clear()操作,防止残留内容干扰输入。
内容的提问来源于stack exchange,提问作者Eduardo Aldana
相关产品推荐
相关产品推荐

