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

Python Selenium使用for循环遍历餐厅链接出现StaleElementReferenceException问题

错误原因

StaleElementReferenceException报错的核心原因是:你在进入列表页后提前抓取了所有餐厅条目元素存储在titles列表中,当你点击进入详情页再调用driver.back()返回列表页时,页面DOM已经重新渲染,之前存储在titles里的元素引用全部失效,第二次循环调用元素时就会触发该错误。

解决思路

不要提前一次性抓取所有餐厅元素,改为先统计餐厅总数量,通过索引循环,每次返回列表页后重新定位当前索引对应的餐厅元素即可。

修正后代码
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(executable_path='../chromedriver.exe')
driver.get("https://www.zomato.com/kolkata/dine-out?dishv2_id=76487754bd59c594cd5218d3427e68e0_2&rating_range=4.0-5.0")
screen_height = driver.execute_script("return window.screen.height;")  # 获取页面屏幕高度
i = 1
count = 0
scroll_pause_time = 1

while True:
    # 每次滚动一屏高度
    driver.execute_script("window.scrollTo(0, {screen_height}*{i});".format(screen_height=screen_height, i=i))
    i += 1
    time.sleep(scroll_pause_time)   
    # 每次滚动后更新滚动高度,因为页面滚动后高度可能变化
    scroll_height = driver.execute_script("return document.body.scrollHeight;")
    # 当需要滚动的高度超过总滚动高度时退出循环
    if (screen_height) * i > scroll_height:
        break

driver.execute_script("window.scrollTo(0, 0);")
res_list = []
# 先获取餐厅总数量
total_rest = len(driver.find_elements_by_xpath('//a[@class="sc-dBAPYN kcrxQo"]'))

# 按索引循环处理每个餐厅
for index in range(total_rest):
    time.sleep(2)
    driver.execute_script("window.scrollTo(0, 0);")
    # 每次重新获取餐厅列表,取当前索引对应的元素
    titles = driver.find_elements_by_xpath('//a[@class="sc-dBAPYN kcrxQo"]')
    element = titles[index].find_element_by_xpath('./div/h4')
    driver.execute_script("arguments[0].click();", element)
    # 等待详情页标题加载完成再取值,比固定sleep更稳定
    name_of_rests = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, '#root > div > main > div > section.sc-kxynE.jzTfFZ > section > section > div > div > div > h1'))
    ).text
    res_list.append(name_of_rests)
    # 返回列表页
    driver.back()
    # 等待列表页加载完成
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, '//a[@class="sc-dBAPYN kcrxQo"]'))
    )

print(res_list)
driver.close()
优化说明
  • 新增了显式等待WebDriverWait替代固定time.sleep,代码运行效率和稳定性更高
  • 每次返回列表页后重新抓取元素,完全规避过期元素引用问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:18:04