如何正确使用find_element_by_link_text()以避免引发NoSuchElementException?

20 投票
4 回答
68656 浏览
提问于 2025-04-16 22:51

我有一段这样的HTML代码:

<div class="links nopreview"><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://REFLECTION/INSTANCE/_CS_Data/null">Home</a></span>&nbsp;•&nbsp;<span><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://SITEADMIN/_CS_Site">Setup</a></span>&nbsp;•&nbsp;</span><span><a
title="Sign Out" class="csiAction csiActionLink">Sign Out</a></span></div>

我想点击一个文本是Home的链接。因为这个Home链接是在登录后才出现的,所以我写了这样的代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re

browser = webdriver.Firefox() # Get local session of firefox
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()

到登录的部分都运行得很好。但是倒数第二行出现了问题。

elem = browser.find_element_by_link_text("Home")

它抛出了一个NoSuchElementException的错误,尽管从HTML代码中可以看到Home链接是存在的。

raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: u'Unable to locate element: {"method":"link text","selector":"Home"}' 

请问我哪里做错了呢?

4 个回答

2

也许你要找的那个元素和你看到的文字不完全一致?我知道这可能有点棘手,虽然在屏幕上看起来像是一样的,但有时候里面会有一些奇怪的格式,比如这个简单的标记 "Home" 或 "Home",这会让第一个字母变成斜体:

"<i>H</i>ome" is visually identical to "<em>H</em>ome" but does not match text.

补充:在写完上面的回答后,我仔细研究了一下问题,发现HTML示例确实显示了“Home”这个词,但因为长行没有换行,所以看不见。所以我把原帖编辑了一下,让它更容易阅读。

新的观察:我注意到“注销”这个元素有一个“title”属性,但“首页”链接元素没有这个属性——试着给它加上一个,然后再用这个。

5

在使用NoSuchElementException时,最常见的问题是虽然元素存在,但却找不到,可能是因为:

解决方法可以包括:

  • 检查你是否在使用正确的框架或窗口,可以用:driver.window_handles
  • 写一个等待的函数,等元素出现,
  • 试试用XPath,比如:driver.find_element_by_xpath(u'//a[text()="Foo"]').click()
  • 使用pdb来更有效地诊断问题。

另见:如何在遇到NoSuchElement异常时使用find_element_by_link_text?

19

你有没有试过加一个隐式等待,这样它就不会运行得太快,而是会等一等。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re

browser = webdriver.Firefox() # Get local session of firefox

browser.implicitly_wait(10) #wait 10 seconds when doing a find_element before carrying on

browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()

implicitly_wait这个调用会让浏览器不断检查,直到页面上出现你想要的东西,并且可以进行操作。

撰写回答