Selenium循环下拉菜单触发StaleElementReferenceException问题求助
解决Selenium循环中StaleElementReferenceException异常
错误原因
你提前把下拉菜单的所有选项元素存在了all_options里,但点击查询按钮后,页面大概率发生了刷新或DOM结构重新渲染,导致之前保存的这些元素对象和当前页面的DOM树失去关联,第二次循环访问这些失效元素时就会抛出这个异常。
修正方案
方案一:每次循环重新获取下拉菜单与选项
把获取下拉菜单的逻辑放到循环内部,确保每次操作的都是当前页面最新的DOM元素:
from selenium import webdriver from tqdm import tqdm from tqdm.notebook import trange, tqdm from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.select import Select from selenium.webdriver.common.by import By import time servico = Service(ChromeDriverManager().install()) navegador = webdriver.Chrome(service=servico) # 先提前收集所有有效选项的文本,避免存元素对象 dropdownField = navegador.find_element(By.NAME, 'customer_id') select = Select(dropdownField) valid_option_texts = [opt.text for opt in select.options if opt.text.strip() != ""] for text in tqdm(valid_option_texts): # 每次循环重新定位下拉菜单,选择对应文本的选项 dropdown = navegador.find_element(By.NAME, 'customer_id') select = Select(dropdown) select.select_by_visible_text(text) time.sleep(3) navegador.find_element(By.ID,'email').click() time.sleep(1) navegador.find_element(By.ID,'email').send_keys(email) time.sleep(1) navegador.find_element(By.ID,'button_find').click() time.sleep(2) print("Test ok")
方案二:用显式等待替代固定sleep(可选优化)
固定time.sleep()不够灵活,换成Selenium的显式等待能让代码更稳定,还能节省不必要的等待时间:
from selenium import webdriver from tqdm import tqdm from tqdm.notebook import trange, tqdm from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.select import Select from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC servico = Service(ChromeDriverManager().install()) navegador = webdriver.Chrome(service=servico) # 收集有效选项文本 dropdownField = navegador.find_element(By.NAME, 'customer_id') select = Select(dropdownField) valid_option_texts = [opt.text for opt in select.options if opt.text.strip() != ""] wait = WebDriverWait(navegador, 10) # 最大等待10秒 for text in tqdm(valid_option_texts): dropdown = navegador.find_element(By.NAME, 'customer_id') select = Select(dropdown) select.select_by_visible_text(text) # 等待输入框可点击后再操作 email_input = wait.until(EC.element_to_be_clickable((By.ID, 'email'))) email_input.click() email_input.send_keys(email) # 等待查询按钮可点击后再点击 submit_btn = wait.until(EC.element_to_be_clickable((By.ID, 'button_find'))) submit_btn.click() # 等待页面加载完成(可根据实际情况调整等待条件) wait.until(EC.staleness_of(submit_btn)) print("Test ok")
内容的提问来源于stack exchange,提问作者Marcos Amorim
相关产品推荐
相关产品推荐

