如何正确使用find_element_by_link_text()以避免引发NoSuchElementException?
我有一段这样的HTML代码:
<div class="links nopreview"><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://REFLECTION/INSTANCE/_CS_Data/null">Home</a></span> • <span><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://SITEADMIN/_CS_Site">Setup</a></span> • </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
来更有效地诊断问题。
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
这个调用会让浏览器不断检查,直到页面上出现你想要的东西,并且可以进行操作。