我们在进行元素定位的过程中,可能会出现no such element:Unable to locate elementd的错误提示。
出现这一问题可能有如下3方面的原因,分别是:
(1)元素定位表达式有误
定位方案:在html页面中,通过按F12后输入定位表达式确认是否有误
(2)等待不到位
定位方案:在代码运行的过程中,通过自动截图查看页面的状态
(3)元素在iframe中,即在当前的html页面中内嵌了另外一个html页面
解决方案:
3.1、分辨元素是否在iframe中;
3.2、若在,从当前的html页面中切换到iframe当中的html中,然后再进行元素的定位。
本节中,主要针对等待不到位导致元素无法定位的问题,给出相应的解决方案:在元素查找查找定位执行进行相应的等待,以确保页面加载完成。
等待主要可以划分为:强制等待和智能等待。
一、强制等待
sleep -- 强制方式,无论页面是否加载完成,等待时间未达到,无法进行其他业务操作。 (可以作为辅助)
二、智能等待
1、隐式等待 -- implicity_wait(了解即可)
1.1、每个会话只需调用一次;
1.2、找到元素后,执行元素操作。
补充说明:
假设隐式等待的时间设置为10秒,
首先,我们需要明确的是这10秒并非一个固定的等待时间,它并不影响脚本的执行速度;
其次,隐式并不是针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。假设在第6秒定位到了元素则继续执行,若直到超出设置的时长10秒还没有定位到元素,则抛出异常。
2、显示等待(掌握)
使用显示等待需要引入WebDriverWait类以及期望条件(expected_condition)
WebDriverWait(driver,timeout,查看周期=0.5).until(条件)
常见的条件有:
(1)元素存在:presence_of_element_located
(2)元素可见:visibility_of_element_located
(3)元素可点击:element_to_be_clickable
说明:
元素在页面中存在,但是不一定可见;但是元素可见,该元素一定在页面中存在。
比如我们在实际应用中可能会遇到元素可以定位成功,但是在对元素进行操作时报错提示元素没有找到的问题。
出现这种情况,可能是元素的什么属性导致了元素不可见,如hidden=“hidden”就能导致当前元素不可见。
因此在设置期望条件时要根据自己的业务需求进行合理的设置。一般情况下,设置元素可见就可以解决大部分的需求了。
附录:
1 from selenium import webdriver 2 from selenium.webdriver.common.by import By 3 from selenium.webdriver.support.wait import WebDriverWait 4 from selenium.webdriver.support import expected_conditions as EC 5 6 driver = webdriver.Chrome() 7 driver.get("http://www.baidu.com") 8 9 wait = WebDriverWait(driver,20) 10 11 login_btn_loc = (By.ID,‘s-top-loginbtn‘) # 登录元素定位 12 wait.until(EC.visibility_of_element_located(login_btn_loc)) # 等待元素可见 13 driver.find_element(*login_btn_loc).click() # 查找元素并进行点击操作 14 15 # 点击显示登录界面 16 login_loc = (By.XPATH,‘//p[@title="用户名登录"]‘) 17 wait.until(EC.visibility_of_element_located(login_loc)) 18 driver.find_element(*login_loc).click() 19 20 # 在登录页面输入用户名和密码,并提交登录信息 21 user_loc = (By.ID,"TANGRAM__PSP_11__userName") 22 pwd_loc = (By.ID,"TANGRAM__PSP_11__password") 23 submit_loc = (By.ID,"TANGRAM__PSP_11__submit") 24 wait.until(EC.visibility_of_element_located(submit_loc)) 25 driver.find_element(*user_loc).send_keys("18272165137") # 输入用户名 26 driver.find_element(*pwd_loc).send_keys("12345678") # 输入密码 27 driver.find_element(*submit_loc).click() # 登录提交