使用Selenium点击含href="javascript:void(0)"的元素时出现「元素未附加到页面文档」错误的解决方案咨询
解决Selenium点击分页标签时的Stale Element Reference问题
这个问题我之前爬分页数据时也踩过坑!咱们先搞清楚为什么会出现这个状况:
问题根源:页面元素失效(Stale Element)
你一开始用find_elements_by_xpath获取了所有分页<a>标签的引用,这时候这些元素是和当前页面的DOM绑定的。但当你点击第一个分页标签后,页面大概率会局部刷新或者重新加载——这时候原来存在内存里的pages列表里的元素引用,就和新DOM里的元素完全脱节了,所以执行click()时就会抛出stale element reference错误。
而你能成功打印元素ID,是因为打印操作是在页面刷新前完成的,那时候元素还没失效~
另外,.submit()方法之所以报错,是因为这个方法专门用于提交表单,你的分页<a>标签不属于任何表单元素,找不到祖先级的<form>,自然会提示无法定位元素。
两种可行的解决方案
方案1:每次循环重新定位分页元素
不要一次性缓存所有元素,而是每次点击前都重新从当前DOM里查找分页元素,确保拿到的是最新的引用:
from selenium import webdriver from selenium.webdriver.common.keys import Keys # 若使用显式等待需导入以下模块 # from selenium.webdriver.support.ui import WebDriverWait # from selenium.webdriver.support import expected_conditions as EC def getlink() : url = "###################" driver = webdriver.Chrome('./chromedriver.exe') driver.get(url) input('pause') # 先获取总页数,确定循环次数 total_pages = len(driver.find_elements_by_xpath("//div[@class='paging']/a")) for i in range(total_pages) : # 每次循环都重新查找分页元素,避免引用失效 pages = driver.find_elements_by_xpath("//div[@class='paging']/a") current_page = pages[i] print(current_page.get_attribute("id")) current_page.click() # 推荐用显式等待替代隐式等待,精准等待页面加载完成 # WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@class='paging']"))) driver.quit()
方案2:通过元素ID定位(更可靠)
先把所有分页的ID提取出来,然后循环通过ID重新定位元素——ID是页面元素的唯一标识,每次查找都是从当前DOM里获取最新元素:
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 def getlink() : url = "###################" driver = webdriver.Chrome('./chromedriver.exe') driver.get(url) input('pause') # 先收集所有分页标签的ID page_ids = [elem.get_attribute("id") for elem in driver.find_elements_by_xpath("//div[@class='paging']/a")] for page_id in page_ids : print(page_id) # 每次通过ID重新定位元素,确保是最新的DOM节点 target_page = driver.find_element(By.ID, page_id) target_page.click() # 等待当前元素失效,确认页面已刷新 # WebDriverWait(driver, 10).until(EC.staleness_of(target_page)) driver.quit()
额外提示
- 尽量用显式等待替代
input('pause')和隐式等待,能更精准地控制等待时机,避免不必要的等待时间。 - 如果点击分页后页面URL有规律变化,也可以考虑通过URL拼接的方式直接访问分页,比模拟点击更高效稳定~
内容的提问来源于stack exchange,提问作者StrangeFate.K
相关产品推荐
相关产品推荐

