Selenium循环中StaleElementException问题及解决方法问询
解决StaleElementException并正常退出爬取循环
你的问题核心在于页面跳转后,之前获取的DOM元素引用已经失效——比如company_links_elements是上一页的元素集合,当点击下一页刷新页面后,这些元素已经不在当前文档中,继续遍历就会触发StaleElementReferenceException。另外,next_page元素也可能因为页面更新变成无效引用。
修复方案
我们需要调整逻辑,确保每次处理当前页时都重新获取最新的元素,同时捕获StaleElementReferenceException来处理元素失效的情况,并用显式等待替代固定的time.sleep来确保页面加载完成:
- 每次进入循环先获取当前页的公司链接元素,处理完再尝试获取下一页按钮
- 同时捕获
NoSuchElementException和StaleElementReferenceException,覆盖下一页按钮不存在或失效的场景 - 使用显式等待确保元素加载完成,避免因页面未加载完全导致的元素获取失败
修改后的代码
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import csv import random import time from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException with open(f"{provider}-{state}-{city}-links.csv", 'w', newline='') as file: writer = csv.writer(file) idx = 1 while True: try: # 显式等待当前页的公司链接加载完成 WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.XPATH, "//h3[@class='jss320 jss324 jss337 sc-gzOgki eucExu']/a")) ) # 重新获取当前页的公司链接元素(每次循环都获取最新的) company_links_elements = driver.find_elements(By.XPATH, "//h3[@class='jss320 jss324 jss337 sc-gzOgki eucExu']/a") # 处理当前页的所有链接 for company in company_links_elements: try: company_url = company.get_attribute("href") writer.writerow((idx, company_url, provider)) idx += 1 time.sleep(random.randint(2, 3)) except StaleElementReferenceException: # 单个公司链接元素失效,跳过该元素继续处理下一个 continue # 尝试获取并点击下一页按钮 try: # 显式等待下一页按钮加载完成且可点击 next_page = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.XPATH, "//a[@role='link'][contains(text(),'Next')]")) ) next_page.click() # 等待页面跳转完成 time.sleep(random.randint(2, 3)) except (NoSuchElementException, StaleElementReferenceException): # 没有下一页按钮或按钮失效,退出循环 print("没有下一页,退出爬取") break except Exception as e: print(f"出现异常: {str(e)}") break driver.quit()
关键改进点说明
- 每次循环重新获取元素:
company_links_elements在每次循环开始时重新获取,确保是当前页的有效元素引用 - 捕获单个元素的Stale异常:在遍历公司链接时,如果单个元素失效,直接跳过继续处理下一个,不会中断整个循环
- 显式等待:用
WebDriverWait确保元素加载完成,比固定time.sleep更可靠,减少因页面加载慢导致的问题 - 双重异常捕获:获取下一页按钮时同时处理两种异常,覆盖下一页按钮不存在或失效的所有场景
内容的提问来源于stack exchange,提问作者Kyle Linden
相关产品推荐
相关产品推荐

