• 关于定位不到元素的解决


    Selenium无法定位元素的九种解决方案

    0.8532018.08.25 14:20:51字数 2,161阅读 13,990
    一、frame/iframe表单嵌套

    WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌的页面元素无法直接定位。
    解决方法:driver.switch_to.frame(id/name/obj)
    switch_to.frame()默认可以直接取表单的id或name属性。如果没有可用的id和name属性,可以先定位到frame/iframe,再将定位对象传给switch_to.frame(对象)方法。

    xf = driver.find_element_by_xpath('//*[@class="if"]')
    driver.switch_to.frame(xf)
    ...
    

    driver.switch_to.parent_frame() 切到父frame。影响性能,可以提给开发,让其改进。
    driver.switch_to.default_content() 跳回最外层的页面

    二、页面跳转到新的标签页,或者弹出的警告框等

    在页面操作过程中有时候点击某个链接会弹出新窗口,这时就需要切换焦点到新窗口上进行操作。
    解决方法1:driver.switch_to.window(window_handle)切换到新窗口。
    首先获取当前窗口的句柄driver.current_window_handle,接着打开弹出新窗口,获得当前打开的所有窗口的句柄driver.window_handles。通过for循环遍历handle,如果不等于第一次打开窗口的句柄,那么一定是新窗口的句柄,因为执行过程只打开了两个窗口;改变条件,如果等于第一次打开窗口的句柄,那么可以切换回第一次打开的窗口。
    解决方法2:对于JavaScript生成的alert、confirm以及prompt,无法使用前端工具对弹出窗口进行定位的,使用driver.switch_to.alert方法定位弹出框。alert的方法有:

    .accept()    '等同于点击“确认”或“OK”'
    .dismiss()    '等同于点击“取消”或“Cancel”'
    .text        '获取alert文本内容,对有信息显示的alert框'
    .send_keys(text)    '发送文本,对有提交需求的prompt框'
    .authenticate(username,password)    '验证,针对需要身份验证的alert'
    
    三、页面元素失去焦点导致脚本运行不稳定

    解决方法:driver.switch_to.active_element 遇到脚本不稳定,有时会失去焦点导致测试失败的情况下,可以先切到焦点元素再进行操作。注意.active_element后面不带括号()。
    下面是一个参考案例

    '最初的 “右击鼠标 → 新建文件夹 → 输入文件夹名称” 的代码'
    l = driver.find_element_by_id('pm_treeRoom_1_span')
    ActionChains(driver).context_click(l).perform()
    driver.find_element_by_class_name('fnew').click()
    time.sleep(2)
    driver.find_element_by_xpath('//*[@id="pm_treeRoom_1_ul"]/li[...]').send_keys('filename')
    time.sleep(2)
    

    结果这种操作总会导致输入框失去焦点,直接消失,更不能send_keys进去了,直接报错。

    '修改后的代码如下'
    driver.find_element_by_class_name('fnew').click()
    time.sleep(2)
    driver.switch_to.active_element.send_keys('filename')
    time.sleep(2)
    
    四、使用Xpath或CSS定位

    find_element_by_xpath("//标签[属性='值']")
    使用Xpath/CSS方法,非常适合定位属性值动态生成、不容易定位的元素。如果不想指定标签,则可以使用“*”代替,使用xpath不局限于id、name和class这三个属性,元素的任意属性值都可以使用,只要它能唯一的标识一个元素。
    解决方法1:如果一个元素没有唯一属性,那么我们可以一级一级向上查找,直到找到可以唯一定位元素的属性,再向下查找其子元素。
    find_element_by_xpath("//form[@id='form']/span[2]/input") 首先通过唯一标识属性id=form定位最外层元素,接着找到最外层元素下的第2个span标签的元素为父元素,最后向下查找定位到父元素下标签为input的子元素。
    解决方法2:如果一个属性不能唯一地区分一个元素,那么使用多个属性来唯一地定位一个元素。
    find_element_by_xpath("//input[@id='kw' and @class='su']/span/input") 首先找到标签为input,id=kw且class=su的元素,接着找到其下标签为span的子元素,继续向下查找找到标签为input的子元素。
    解决方法3:检查Xpath描述是否有误,导致无法定位到元素。

    五、页面还没有加载出来,就对页面上的元素进行的操作

    因为加载元素延时造成的脚本失败,我们可以通过设置等待时间来提升自动化脚本的稳定性。
    解决方法1:WebDriverWait() 显示等待。等待单个的元素加载,通常配合until()until_not()方法使用。

    WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
    - driver - 传入WebDriver实例,必填
    - timeout - 最长等待时间,必填
    - poll_frequency - 调用`until`/`until_not`方法的时间间隔,默认为0.5秒,可省。
    - ignored_exceptions - 忽略异常,默认仅包含NoSuchElementException,可省。
    
    WebDriverWait(driver,10).until(method,message='')     '等待目标出现'
    WebDriverWait(driver,5,1).until_not(method,
  • 相关阅读:
    HDU 2844 Coins(多重背包)
    HDU 4540 威威猫系列故事——打地鼠(DP)
    Codeforces Round #236 (Div. 2)
    FZU 2140 Forever 0.5
    HDU 1171 Big Event in HDU(DP)
    HDU 1160 FatMouse's Speed(DP)
    ZOJ 3490 String Successor
    ZOJ 3609 Modular Inverse
    ZOJ 3603 Draw Something Cheat
    ZOJ 3705 Applications
  • 原文地址:https://www.cnblogs.com/summer-cy/p/13254824.html
Copyright © 2020-2023  润新知