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

Selenium Python下拉框迭代时StaleElementReferenceException问题排查求助

Hey there, let's break down what's causing that StaleElementReferenceException and fix it up.

问题根源

The error pops up because after you click the first dropdown option, the page (including the dropdown itself) gets re-rendered. The dropdown_menu_list you grabbed at the start of the loop holds references to the original elements from the initial page state. Once the page refreshes, those old element references are no longer attached to the current DOM—hence the stale reference error.

修复思路

Instead of storing the actual WebElement objects upfront, we'll first collect all the value attributes of the dropdown options as plain strings. Then, we'll loop through these string values, and for each iteration, we'll re-locate the dropdown and the specific option we need. This way, we always use fresh element references that are tied to the current DOM state.

修改后的完整代码

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.select import Select
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import time  # Don't forget to import time!

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.delete_all_cookies()

def fetch_d(driver, locator):
    # First, collect all option values as plain strings (no WebElements stored)
    dropdown_menu = WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator))
    option_values = [opt.get_property("value") for opt in Select(dropdown_menu).options]
    
    counter = 0
    for tmp in option_values:
        print("I am in counter no", counter, "\n")
        
        # Re-locate the dropdown every iteration to avoid stale references
        dropdown_menu = WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator))
        select = Select(dropdown_menu)
        
        if counter == 0:
            # Skip the first option (label information)
            counter += 1
            continue
        
        # Select the target option using its stored value
        select.select_by_value(tmp)
        print(f"Selected option: {select.first_selected_option.text}")
        time.sleep(3)
        
        # Wait for the table to load and grab download links
        locator2 = (By.CSS_SELECTOR, "#GridView1")
        element = WebDriverWait(driver, 10).until(EC.presence_of_element_located(locator2))
        a_tags = element.find_elements(By.TAG_NAME, "a")
        
        for link in a_tags:
            link.click()  # Trigger file download
            # Optional: Add a small delay here if your downloads need time to initiate
            time.sleep(1)
        
        counter += 1

# Method call
fetch_d(driver, (By.ID, "ddlacname"))

额外优化说明

  • Replaced the deprecated element.find_elements_by_tag_name with element.find_elements(By.TAG_NAME, "a") to align with modern Selenium standards.
  • Used EC.presence_of_element_located for the table instead of element_to_be_clickable—we only need the table to exist, not be interactive, to grab its links.
  • Added a small wait after each download click to ensure the browser has time to start the download process (adjust the duration based on your site's speed).
  • Made the selected option text print clearer for debugging purposes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:37:47