Selenium:为什么for循环第二次迭代时会抛出NoSuchElementException异常
问题原因分析
- 你调用
driver.find_elements_by_xpath获取到的WebElement集合,是绑定到你首次获取元素时的页面DOM实例的临时引用。第一次循环中你调用driver.get()跳转新页面后,原页面的DOM树会被浏览器完全销毁,即使后续用driver.back()回到原页面,浏览器也会重新加载构建新的DOM树,之前获取的所有WebElement引用全部失效,因此第二次迭代访问集合里的下一个元素时,就会抛出NoSuchElementException或StaleElementReferenceException异常。 - 额外补充:即使页面没有跳转,只要原DOM节点被前端JS动态删除重建,也会出现相同的元素引用失效问题。
解决方案
方案1:预提取所有需要的信息再循环(最推荐)
提前一次性把你需要从div元素上获取的所有信息(比如跳转链接、元素文本、自定义属性等)提取出来存到普通列表中,完全脱离WebElement引用再循环处理,不需要来回刷新元素列表:
# 第一步:先把所有需要的信息预提取,不要留存WebElement div_info_list = [] for div in driver.find_elements_by_xpath("//div[@class='class_name']"): # 这里把你后续需要用到的所有从div上取的信息都存下来 div_info = { "text": div.text, # 如果div里有跳转链接可以加:"link": div.find_element_by_tag_name("a").get_attribute("href") } div_info_list.append(div_info) # 第二步:循环预存的信息处理 for info in div_info_list: print(info["text"]) print(f"Current url 1: {driver.current_url}") new_url = url + "/page/" time.sleep(2) driver.get(new_url) print(f"Current url 2: {driver.current_url}") time.sleep(2) # 后续从新页面获取相关信息 driver.back() print(f"Current url 3: {driver.current_url}") print("从现在起休眠3秒...") time.sleep(3)
方案2:用索引遍历,每次返回后重新获取元素列表
如果你的业务逻辑必须要操作原页面的div元素(比如需要点击div跳转,无法预提取链接),可以用索引遍历,每次回到原页面后重新获取元素集合:
# 先获取总元素数量 div_count = len(driver.find_elements_by_xpath("//div[@class='class_name']")) # 用索引遍历,不要遍历元素集合本身 for i in range(div_count): # 每次循环首先重新获取元素列表,确保引用有效 divs = driver.find_elements_by_xpath("//div[@class='class_name']") current_div = divs[i] print(current_div.text) print(f"Current url 1: {driver.current_url}") new_url = url + "/page/" time.sleep(2) driver.get(new_url) print(f"Current url 2: {driver.current_url}") time.sleep(2) # 后续从新页面获取相关信息 driver.back() print(f"Current url 3: {driver.current_url}") print("从现在起休眠3秒...") time.sleep(3)
内容的提问来源于stack exchange,提问作者ezzeddin
相关产品推荐
相关产品推荐

