selenimu找不到元素的几种情况和解决办法

2019-10-11  本文已影响0人  attentionYSF
一、页面刷新(StaleElementReferenceException: Message: Element not found in the cache...)

原因:页面被刷新了。
在当前页面找不到这个元素了,但是你自己手动复制到页面开发者工具上查看明明有啊,为啥在代码里面就找不到了呢?这时,你还可能会问“可是明明元素就在那里,没有变,甚至我是回退回来的,页面都没有变,怎么会说是新页面?”。
其实呢是在操作的过程中页面发生了变化,刷新了,虽然表面上看起来两个元素长得一模一样,事实上是每一个元素都有自己的一个ID号。
用代码(Python)来证明!

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://cn.bing.com/')
print(driver.find_element_by_id('sb_form_q'))  # sb_form_q before refresh
driver.refresh()  #刷新
#driver.back()    #此处不管是刷新还是点击了其他操作又会回到这个页面都是一样的
print(driver.find_element_by_id('sb_form_q'))  # sb_form_q after refresh
driver.quit()

结果如下图:很明显,element有一个对应的ID是不一样的,只能在当前页面时去使用、存取才会有效。


异常测试图.png

分析:
refresh,不论你是主动刷新还是页面自动刷新
back,已经跳转到了其他页面,然后你用driver.back()跳回来,这也是一张新的页面了
跳转到了新的页面,但这张新页面上有一些元素跟之前页面是长得一样的,这也是一张新的页面了。比如:一排分页按钮,你点击下一页跳转到了第二页,想要还用原来的元素操作到下一页,那也是不可能的了。

解决:
只要刷新页面之后重新获取元素就行,不要提前获取一组元素,然后去循环操作每一个元素,这种情况还是获取元素的个数,然后在循环中获取相应位置的元素,在用的时候才去获取,这样你就获取到最新的id了,也不会出现找错人的尴尬了。

我今天就遇到一个,其实之前也遇到了,只是没有着重记录一下而已。
有一个四个菜单,分别要去带四个传入的数据点击四次,检查是否能到另外一个页面,页面返回是否正常。
我就使用了一个循环,但是最开始没细看,直接循环成了元素,到新页面验证完成之后又返回原来的页面继续定位,发现定位不了了;这时我才想起来不应该循环元素,应该循环元素的个数,在这个循环的过程中再来定位获取元素。


异常测试图2.png
二、iframe原因定位不到元素需要切换Iframe

这种情况一般发生在有内嵌的iframe的情况下,需要切换一下iframe
另外注意的是有的页面会有多个iframe,找不到元素同样是没有切换iframe,切换即可

driver.switch_to.frame(driver.find_element_by_xpath("//div[@id='loginDiv']/iframe"))
switch_to.default_content()
<html>
    <iframe id='frame1'>
        <iframe id='frame2'></iframe>
    </iframe>
</html>
   driver.switch_to.frame("frame1")
   driver.switch_to.frame("frame2")
 driver.switch_to.parent_frame()
三、隐藏元素
#如果界面有隐藏元素:可以调用js脚本,处理隐藏元素
js = "document.getElementById(\"normalLoginTab\").style.display='block';"
driver.execute_script(js)
sleep(4)
四、页面刷新(StaleElementReferenceException: Message: Element not found in the cache...)

这个需要增加一定等待时间,显示等待时间可以通过WebDriverWait 和util来实现

示例代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("http://www.126.com")
print('---------登录前----------')
# 获取当前title
print("title:" + driver.title)
# 获取当前URL
print("URL:" + driver.current_url)

#默认为二维码登录,获取html元素,通过点击事件切换到 使用密码登录
driver.find_element_by_id('switchAccountLogin').click()
#等待界面渲染完成
sleep(4)

#如果界面有隐藏元素:可以调用js脚本,处理隐藏元素
#js = "document.getElementById(\"normalLoginTab\").style.display='block';"
#driver.execute_script(js)
#sleep(4)

#我们需要获取的元素在iframe标签的,必须切换到iframe标签,才能获取html元素
print(driver.switch_to.frame(driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")))
sleep(4)

#测试一下该元素能否获取
a = driver.find_element_by_id('account-box')
print(a)

#填充邮箱账号密码
driver.find_element_by_xpath("//input[@name='email']").clear()
driver.find_element_by_xpath("//input[@name='email']").send_keys('testing111111')
driver.find_element_by_xpath("//input[@name='password']").clear()
driver.find_element_by_xpath("//input[@name='password']").send_keys('123')
driver.find_element_by_id('dologin').click()

#睡眠一会,等待登录后的提示信息渲染完成后,再获取提示语
sleep(4)
print('--------登录后---------')
print(driver.title)
print(driver.current_url)
print(driver.find_element_by_xpath("//div[@id='nerror']/div[2]").text)
上一篇 下一篇

猜你喜欢

热点阅读