Selenium在while循环第二次执行时抛出WebDriverException问题求助
解决Selenium循环中"No node with given id found"错误
问题描述
运行以下Selenium代码时,首次while循环可正常执行,但第二次循环时程序崩溃并抛出错误,预期输出的“Factory purchased”日志未出现:
import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys game_mins = 5 play_seconds = 5 chrome_driver_path = "your own chrome driver address here" ser = Service(executable_path=chrome_driver_path) driver = webdriver.Chrome(service=ser) driver.get("http://orteil.dashnet.org/experiments/cookie/") cookie = driver.find_element(By.ID, "cookie") Most_expensive = driver.find_element(By.ID, "buyTime machine") Second_expensive = driver.find_element(By.ID, "buyPortal") Third_expensive = driver.find_element(By.ID, "buyAlchemy lab") Fourth_expensive = driver.find_element(By.ID, "buyShipment") Fifth_expensive = driver.find_element(By.ID, "buyMine") Sixth_expensive = driver.find_element(By.ID, "buyFactory") Seventh_expensive = driver.find_element(By.ID, "buyGrandma") Eighth_expensive = driver.find_element(By.ID, "buyCursor") game_end = time.time() + game_mins * 60 while time.time() < game_end: t_end = time.time() + play_seconds while time.time() < t_end: cookie.click() print("Moving on to the ifs statement") time.sleep(4) if Most_expensive.get_attribute("class") != "grayed": print("Time machine purchased") Most_expensive.click() elif Second_expensive.get_attribute("class") != "grayed": print("Portal purchased") Second_expensive.click() elif Third_expensive.get_attribute("class") != "grayed": print("Alchemy lab purchased") Third_expensive.click() elif Fourth_expensive.get_attribute("class") != "grayed": print("Shipment purchased") Fourth_expensive.click() elif Fifth_expensive.get_attribute("class") != "grayed": print("Mine purchased") Fifth_expensive.click() elif Sixth_expensive.get_attribute("class") != "grayed": print("Factory purchased") Sixth_expensive.click() elif Seventh_expensive.get_attribute("class") != "grayed": print("Granma purchased") Seventh_expensive.click() else: print("Cursor purchased") Eighth_expensive.click() time.sleep(50)
控制台输出的错误信息:
Moving on to the ifs statement Granma purchased Moving on to the ifs statement selenium.common.exceptions.WebDriverException: Message: unknown error: unhandled inspector error: {"code":-32000,"message":"No node with given id found"}
问题根源
错误核心是失效元素引用(Stale Element Reference):
- 程序启动时一次性获取了所有物品元素的引用
- 购买物品后页面DOM结构会更新(比如物品状态、价格变化),之前的元素引用会失效,Selenium无法找到对应DOM节点,从而抛出"No node with given id found"错误
解决方案
每次循环时重新获取所有物品元素的引用,确保操作的是当前页面的有效DOM元素。同时优化逻辑,用列表存储物品优先级,避免冗长的elif判断:
import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By game_mins = 5 play_seconds = 5 chrome_driver_path = "your own chrome driver address here" ser = Service(executable_path=chrome_driver_path) driver = webdriver.Chrome(service=ser) driver.get("http://orteil.dashnet.org/experiments/cookie/") game_end = time.time() + game_mins * 60 # 按优先级从高到低定义物品ID和名称 items = [ ("buyTime machine", "Time machine"), ("buyPortal", "Portal"), ("buyAlchemy lab", "Alchemy lab"), ("buyShipment", "Shipment"), ("buyMine", "Mine"), ("buyFactory", "Factory"), ("buyGrandma", "Grandma"), ("buyCursor", "Cursor") ] while time.time() < game_end: # 每次循环重新获取cookie元素(保险起见,避免DOM更新导致引用失效) cookie = driver.find_element(By.ID, "cookie") t_end = time.time() + play_seconds while time.time() < t_end: cookie.click() print("Moving on to the ifs statement") time.sleep(4) # 遍历物品列表,找到第一个可购买的(未被grayed的) purchased = False for item_id, item_name in items: try: item = driver.find_element(By.ID, item_id) if item.get_attribute("class") != "grayed": print(f"{item_name} purchased") item.click() purchased = True break except Exception as e: # 处理元素暂时找不到的情况(比如页面加载延迟) continue if not purchased: print("No affordable items found") time.sleep(50) driver.quit() # 关闭浏览器释放资源
关键优化点
- 实时获取元素:每次循环重新查找物品元素,避免引用失效
- 简化逻辑:用列表存储物品优先级,通过循环替代冗长的elif判断,代码更易维护
- 异常处理:添加try-except捕获元素查找时的临时异常,提升程序稳定性
- 资源清理:最后调用
driver.quit()关闭浏览器,释放系统资源
内容的提问来源于stack exchange,提问作者MakT
相关产品推荐
相关产品推荐

