为什么这段代码会这样工作?

-1 投票
1 回答
32 浏览
提问于 2025-04-12 14:26

这是大部分主要代码

            driver.get(url)
            usernameelem = driver.find_element(By.XPATH,usernameId) 
            usernameelem.send_keys(username) 
            passwordelem = driver.find_element(By.XPATH,passwordId)
            passwordelem.send_keys(password)
            passwordelem.send_keys(Keys.ENTER)
            try:
                submitbut = driver.find_element(By.XPATH,submit_buttonId)
                submitbut.click()
            except:
                submitbut1 = driver.find_element(By.XPATH,submit_buttonId)
                submitbut1.send_keys(Keys.ENTER) 
            time.sleep(5)

这段代码我不太确定:

            try:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.click()
            except:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.send_keys(Keys.ENTER) 

这是唯一一段能正常工作的代码,当我尝试点击提交按钮时

其他方法,比如

                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.send_keys(Keys.ENTER) 

试图预测错误..或者

            try:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.click()
            except:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.click() 

实际上是同样的事情,但点击

都不行,总是会出现“selenium.common.exceptions.StaleElementReferenceException: 消息:过期元素引用:找不到过期元素”这样的错误

我不太明白为什么只有在这么特定的顺序下才能工作,提交按钮总是可见的,而且如果手动点击也是可以的

1 个回答

0

不看到页面很难确定具体情况,但听起来页面加载后,至少有一部分又被重新加载了。这就导致了 StaleElementException(过时元素异常)。过时的元素在 submit 中……你从页面上获取了这个元素的引用,并把它放进了 submit 里。然后页面重新加载了,这样 submit 就不再指向任何东西了(它的引用过时了)。解决这个问题的唯一办法就是重新获取这个引用……这就是为什么你需要调用同一行代码两次,第一次是在 try 里面。

为了避免这种情况,你可以:

  1. 等待元素出现
  2. 等待它变得过时
  3. 等待它可以被点击
  4. 然后点击它

这听起来工作量很大,但这个过程应该能减少很多间歇性(和确定性)的失败。代码大概会是这样的:

wait = WebDriverWait(driver, 10)
# define the locator since we're going to use it more than once
submit_locator = (By.XPATH, submit_buttonId)
# wait for the page to load enough that the element exists
submit = wait.until(EC.presence_of_element_located(submit_locator))
# wait for the element to go stale
wait.until(EC.staleness_of(submit))
# now that it's gone stale, now we wait for it to be clickable and click it
wait.until(EC.element_to_be_clickable(submit_locator)).click()

撰写回答