zoukankan      html  css  js  c++  java
  • Selenium---元素定位之CSS定位

    CSS 选择器:

    常见符号:

    #表示 id选择器

    .表示 class选择器

    >表示子元素,层级

    一个空格也表示子元素,但是是所有的后代子元素,相当于 xpath 中的相对路径

    一、css:属性定位

    1.css可以通过元素的id、class、标签这三个常规属性直接定位到

    2.如下是百度输入框的的html代码:

    <input id="kw" class="s_ipt" type="text" autocomplete="off" maxlength="100" name="wd"/>

    3.css用#号表示id属性,如:#kw

    4.css用.表示class属性,如:.s_ipt

    5.css直接用标签名称,无任何标示符,如:input

    二、css:其它属性

    1.css除了可以通过标签、class、id这三个常规属性定位外,也可以通过其它属性定位

    2.以下是定位其它属性的格式

    [name=wd] [autocomplete='off'][maxlength='255']

    三、css:标签

    css页可以通过标签与属性的组合来定位元素

    input.s_ipt input#kw input[id='kw']

    四、css:层级关系

    //form的id属性

    form#form>span>input

    //form的class属性 

    form.fm>span>input

    五、css:索引

    css也可以通过索引nth-child(1)来定位子元素,直接翻译过来就是第几个小孩

    总结:选择标签后,找第几个小孩即可

    Select控件第三个Opel

    #select>select>option:nth-child(3)

    CheckBox第一个Volvo

    #checkbox>input:nth-child(1)

    CheckBox第二个Saab

    #checkbox>input:nth-child(4)

    RadioBox第二个Saab

    #radio>input:nth-child(4)

    通过索引nth-of-type(2)来定位子元素,按照分类指定

    选择select的saab

    #select>select>option:nth-of-type(2);

     选择 id 为 radio 的 div 下的第 1 个子节点

    div#radio>input:nth-of-type(4)+label

     选择id 为radio 的div 下的第4 个input 节点之后挨着的 label

    节点

    div#radio>input:nth-of-type(4)~label

    六、css:逻辑运算

    css同样也可以实现逻辑运算,同时匹配两个属性,这里跟xpath不一样,无需写and关键字

    [type='checkbox'][name='checkbox1']

    Selenium webdriver是完全模拟用户在对浏览器进行操作,所有用户都是在页面进行的单击、双击、输入、滚动等操作,而webdriver也是一样,所以需要我们指定元素让webdriver进行单击、双击、输入等操作,所以元素定位是UI自动化测试的前提条件。

    CSS定位方式和XPATH定位方式基本相同,只是CSS定位表达式有其自己的格式。CSS定位方式拥有比XPATH定位速度快,且比XPATH稳定的特性。下面详细介绍CSS定位方式的使用方法

    其中xpath与css为最常用的定位方式,本文章以百度搜索框为例重点介绍css定位的使用

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get("https://www.baidu.com")
    
    # 1)绝对路径(一般不推荐使用,此处不介绍)
    # 2)id选择器
    # driver.find_element_by_css_selector("#kw").send_keys("ethon")
    
    # 3)class选择器
    # driver.find_element_by_css_selector(".s_ipt").send_keys("ethon")
    
    # 4)其他属性定位
    # driver.find_element_by_css_selector("[autocomplete='off']").send_keys("ethon")
    
    # 5)通过部分属性定位
    #      * 包含某个字符
    #      ^ 以某个字符开关
    #      $ 以某个字符结尾
    
    # driver.find_element_by_css_selector("[autocomplete*='f']").send_keys("ethon")
    # driver.find_element_by_css_selector("[autocomplete^='o']").send_keys("ethon")
    # driver.find_element_by_css_selector("[autocomplete$='f']").send_keys("ethon")
    
    # 6)通过层级定位
    # driver.find_element_by_css_selector("form>span>input").send_keys("ethon")
    # driver.find_element_by_css_selector("form#form>span>input").send_keys("ethon")  # 层级与id组合定位
    # driver.find_element_by_css_selector("form.fm>span>input").send_keys("ethon")  # 层级与class组合定位
    
    # 7)通过兄弟节点定位
    # driver.find_element_by_css_selector("div#u1>a:first-child").click()
    # driver.find_element_by_css_selector("div#u1>a:nth-child(2)").click()
    driver.find_element_by_css_selector("div#u1>a:last-child").click()

    被测网页的HTML代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <style type="text/css">
            input.spread { Font-SIZE:20pt;}
            input.tight { FONT-SIZE:10pt;}
        </style>
    </head>
    <body onload="document.getElementById('div1input').focus()">
        <div id="div1" style="text-align:center">
            <input id="div1input" class="spread"/></input>
            <a href="http://www.sogou.com">搜狗搜索</a>
            <img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png" 
            href="http://www.sogou.com">搜狗图片</img>
            <input type="button" value="查询"></input>
        </div>
        <br>
        <p>第一段文字</p>
        <p>第二段文字</p>
        <div name= "div2" style="text-align:center">
            <input name="div2input" class="tight"></input>
            <a href="http://www.baid.com">百度搜索</a>
            <img alt="div2-img2" src="http://www.baidu.com/img/bdlogo.png" 
            href="http://www.baidu.com">百度图片</img>
            <input type="button" value="查询"></input>
        </div>
        <div class="foodDiv">
            <ul id="recordlist">
                <p>土豆</p>
                <li>西红柿</li>
            </ul>
        </div>
    </body>
    </html>

    ①使用绝对路径定位元素

    目的

    在被测试网页中,查找第一个div中的查询按钮

    CSS定位方式:

    html > body > div >input[value="查询"]

    Python定位语句:

    element = driver.find_element_by_css_selector('html > body > div >input[value="查询"]')

    代码解释:

    上述CSS定位表达式使用绝对路径定位属性value的值为“查询”的页面元素。从CSS定位表达式可以看出,步间通过“>"分割,区别于XPATH路径中的正”/“,并且也不再使用@符号选择属性。

    ②使用相对路径定位元素

    目的

    在被测试网页中,查找第一个div下的查询按钮

    CSS定位表达式:

    input[value="查询"]

    Python定位语句:

    element = driver.find_element_by_css_selector('input[value="查询"]')

    代码解释

    上述CSS表达式通过相对路径使用元素名称和元素的属性及属性值进行页面元素的定位。

    ③使用class名称定位元素

    目的

    在被测网页中,查找第一个div元素下的input输入框

    CSS定位表达式:

    css.spread

    python定位语句:

    element = driver.find_element_by_css_selector('css.spread')

    代码解释

    上述CSS定位表达式使用input页面元素的class属性名称spread来进行定位,用点(.)分割元素名与class属性名,点号后面是class属性名称

    ④使用ID属性值定位元素

    目的

    在被测试网页中,查找第一个dic元素下ID属性值为div1input“的input元素

    CSS定位语句:

    input#div1input

    Python定位语句:

    element = driver.find_element_by_css_selector('input#div1input')

    代码解释

    上述CSS定位表达式使用input页面元素的ID属性值div1input进行定位,使用#号分割元素名和ID属性值,#后面是ID属性值

    ⑤使用页面其他属性值定位元素

    目的

    在被测网页中,查找div元素下的第一张图片元素img

    CSS定位表达式:

    img[alt="div1-img1"]
    img[alt="div1-img1"][href="http://www.sogou.com"]

    Python定位语句:

    element = driver.find_element_by_css_selector('img[alt="div1-img1"]')
    element = driver.find_element_by_css_selector('img[alt="div1-img1"][href="http://www.sogou.com"]')

    代码解释:

    表达式1和表达式2是等价的,都是定位第一个img元素

    表达式1:表示使用img页面元素的alt元素的属性值div1-img1进行定位。若定位的页面元素始终具有唯一的属性值,此定位方式可以解决很多频繁变动的页面元素

    表达式2:表示同时使用了img页面元素的alt和href属性进行页面元素的定位。在某些复杂的定位场景,可使用多个属性来确保定位元素的唯一性。

    ⑥使用属性值的一部分内容定位元素

    目的

    在被测试网页中,查找“搜狗搜索”链接

    CSS定位表达式:

    1 a[href^="http://www.so"]
    2 a[href$="gou.com"]
    3 a[href*="sogou"]

    Python定位语句:

    1 element = driver.find_element_by_css_selector('a[href^="http://www.so"]')
    2 element = driver.find_element_by_css_selector('a[href$="gou.com"]')
    3 element = driver.find_element_by_css_selector('a[href*="sogou"]')

    代码解释

    1.表示匹配链接地址开始为http://www.so关键字串的链接元素,以字符^指明从字符串的开始匹配

    2.表示匹配链接地址结尾包含gou.com关键字串的链接元素,以字符$指明在字符串的结尾匹配

    3.表示匹配链接地址包含sogou关键字串的链接元素,以字符*指明在需要进行模糊查询

    使用此模糊定位方式,可匹配动态变化的属性值的页面元素,只要找到属性值固定不变的关键部分,就可以进行模糊匹配定位。此方法可以解决大部分复杂定位的问题,当然无论是方式都需要灵活使用才能确保能够准确的定位都想要定位的元素

    ⑦使用页面元素进行子页面元素的查找

    目的

    在被测网页中,查找第一个div下的第一个input元素

    CSS定位表达式:

    1 div#div1>input#div1input
    2 div input

    Python定位语句:

    1 element=driver.find_element_by_css_selector("div#div1>input#div1input")
    2 element=driver.find_elements_by_css_selector("div input")

    代码解释

    1.表达式1中的div#div1,表示在被测试网页上定位到ID属性值为div1的div页面元素,> 表示在以查找到的div元素的子页面元素中进行查找,input#div1input表示查找ID属性值为div1input的input页面元素,此方法可实现查找div下子页面元素的办法

    2.表达式2表示匹配所有属于div元素后代的input元素,表达式中父元素div和子元素input中间需用空格分割,注意此表达式是定位一组input元素,并不是单个input元素

    ⑧使用伪类定位元素

    目的

    在被测试网页中查找第一个div下的指定子页面元素

    CSS定位表达式:

    1 div#div1 :first-child
    2 div#div1 :nth-child(2)
    3 div#div1 :last-child
    4 input:focus
    5 input:enabled
    6 input:checked
    7 input:not([id])

    Python定位语句:

    1 element=driver.find_element_by_css_selector("div#div1 :first-child") 
    2 element=driver.find_element_by_css_selector("div#div1 :nth-child(2)")
    3 element=driver.find_element_by_css_selector("div#div1 :last-child")
    4 element=driver.find_element_by_css_selector("input:focus")
    5 element=driver.find_elements_by_css_selector("input:enabled")
    6 element=driver.find_elements_by_css_selector("input:checked")
    7 element=driver.find_elements_by_css_selector("input:not([id])")

    代码解释

    伪类表达式是CSS语法支持的定位方式,前3个表达式特别注意的是在冒号前一定要有一个空格,否则定位不到想要定位的元素

    1.表达式1表示查找ID属性值为div1的div页面元素下的第一个子元素,根据被测试网页定位的是div下的input元素,first-child表示查找某个页面元素下的第一个子页面元素

    2.表达式2表示查找ID属性值为div1的div页面元素下的第二个子元素,参照被测网页,定位到的页面元素是一个链接元素

    3.表达式3表示查找ID属性值为div1的div页面元素下的最后一个子元素,根据被测试网页定位的是一个按钮元素;last-child表示的是查找某个页面元素下的最后一个子页面元素

    4.表达式4 表示查找当前获取焦点的input页面元素

    5.表达式5表示查找可操作的input元素

    6.表示查找处于勾选状态的checkbox页面元素

    7.表示查找所有无id属性的input页面元素

    ⑨查找同级兄弟页面元素

    目的

    在被测试网页中,查找第一个div下第一个input子页面元素同级兄弟页面元素

    CSS定位表达式:

    1 div1#div1 > input + a
    2 div1#div1 > input + a + img
    3 div1#div1 > input + * + img
    4 ul#recordlist > p~li

    Python定位语句:

    1 element=driver.find_element_by_css_selector("div1#div1 > input + a") 
    2 element=driver.find_element_by_css_selector("div1#div1 > input + a + img") 
    3 element=driver.find_element_by_css_selector("div1#div1 > input + * + img") 
    4 element=driver.find_elements_by_css_selector("ul#recordlist > p~li")

    代码解释

    1.表达式1表示在ID属性值为div1的页面元素下,查找input页面元素后的同级的且相邻的链接元素a

    2.表达式2表示在ID属性值为div1的页面元素下,查找input元素和链接元素a后面相邻的图片元素img

    3.表达式3表示在ID属性值为div1的页面元素下,创造找input页面元素和任意一种页面元素后面的同级且相邻的图片元素img,* 表示任意类型的一个页面元素,只能表示一个元素,如果想用此方法查找第一个div下的最后一个input元素,表达式写法为div#div1 > input + * + * + input或div#div1 > input + a + * + input或div#div1 > input + a + img + input

    4.表达式4表示ID属性值为recordlist的ul页面元素下,查找p页面元素以后所有的li元素

    ⑩多元素选择器

    CSS定位表达式支持多元素选择器,也就是一次可以同时选择多个相同的标签,也可以同时选择多个不同的标签,不同标签间用英文的逗号隔开

    目的

    在被测网页中,同时选择多个不同的页面元素

    CSS定位表达式:

    div#div1,input,a

    Python定位语句:

    element=find_elements_by_css_selector("div#div1,input,a')

    代码解释

    上面的css表达式表示同时查找所有ID属性值为div1的div元素,所有的input元素,所有的a元素

    总结

    目前为止,已经整理了自动化测试Python+Selenium中对于web测试定位页面元素的两种主流,也是最好的定位方式XPATH和CSS定位方式,在我个人看来两个方式都很不错,效率都很高,也很容易解决日常工作中的问题,也能够减少页面的变动对于脚本的维护成本,当然不同问题还需要不同的方式解决,能解决问题的方法都是好方法,希望以后的日子对于定位元素不再是难题。下面我们对这两种定位方式大概做个对比;

    XPATH定位和CSS定位很相似,XPATH功能更强大一些吧,但CSS定位方式执行速度更快,鉴于某些浏览器不支持CSS定位方式,并且一般在自动化测试实施过程中使用xpath定位方式要比css更普遍,所以建议大家先掌握xpath,再来看下二者在语法上有什么区别

    定位元素目标 XPATH CSS
    所有元素   //* *
    所有div元素 //div div
    所有div元素子元素 //div/* div>*
    根据ID属性获取元素 //*[@id=''] div#id
    根据class属性获取元素 //*[@class=''] div.class
    拥有某个属性的元素 //*[@href=''] *[href='']
    所有div元素的第一个子元素 //div/*[1] div>* :first-child
    所有拥有子元素a的div元素 //div[a] 无法实现
    input的下一个兄弟元素 //input/following-sibling::[1] input+*
  • 相关阅读:
    如何通过npm编译Typescript代码
    TypeScript 中的':' 和'?:'的区别
    无法读取本地服务器JSON文件, 返回404错误
    Nodejs , npn 注册 包上传,更新,下载
    Java 字符流
    Java 字节流
    Java中的File类,递归是什么?
    JDBC工具类—如何封装JDBC
    JDBC的开发步骤
    vFor和vIf不要一起使用
  • 原文地址:https://www.cnblogs.com/nini0806/p/13411263.html
Copyright © 2011-2022 走看看