三 Selenium之元素定位方式

一 Python中元素定位的方式 

    通常使用find_element或find_elements方法来定位元素.
        ①find_element使用给定的方法定位和查找一个元素.
        ②find_elements使用给定的方法定位和查找所有元素list.

二 常用的八种定位方式 + JS +JQuery定位

    注:大部分的示例以百度首页为例

    2.1 by_id

element = driver.find_element_by_id('kw')

 

  2.2  by_name

     当定位的元素具有name属性的时候可以通过by_name来定位该元素.

element = driver.find_element_by_name('wd')

2.3 by_class_name

   当定位的元素具有class属性的时候,可以通过by_class_name来定位该元素.

element = driver.find_element_by_class_name('s_ipt')

  注:若class属性中间的空格并不是空字符串,那是间隔符号,表示的是一个字符串有多个class的属性名称,如下所示(除了class有多个属性之外,id,name是没有多个属性的

 

 

如class=bg s_btn
若想定位到上述的class属性的元素,'bg''s_btn'都可以定位到,并且要唯一,若不唯一的话,可以把所有相同元素定位出来,
按下标取第几个就行element = driver.find_elements_by_class_name('bg')[2],
由于s_btn在页面中唯一,所以可以使用如下方法:element = driver.find_element_by_class_name('s_btn') #也可以通过css定位,中间加点就行(可以看下面CSS定位方式[复合class])

2.4 by_tag_name

    可以通过元素的标签名来查找元素,由于搜索到的标签名通常buzhiyige,所以一般结合find_elements方法来使用.然后通过name或classname等属性筛选.

elements = driver.find_elements_by_tag_name('input')
for element in elements:
    if element.get_attribute('type') == 'submit':
        print(element.get_attribute('value'))

2.5 by_link_text

   通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接.

element = driver.find_element_by_link_text('地图')

 2.6 by_partial_link_text

   当不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用该方法.通过部分链接文字进行匹配.

element = driver.find_element_by_partial_link_text('')

2.7 by_css_selector

   by_css_selector通过CSS查找元素,这种定位方式跟by_xpath比较类似.Selenium官网的Document里极力推荐使用CSS locator,而不是XPath来定位元素.原因是CSS locator比XPath locator速度快,特别是在IE下比XPath更高效更准确更易编写,对各种浏览器支持也很好。

by_css_selector常用定位
①根据tagName(html标签)
#使用find_element_by_css_selector只会定位到第一个input标签的元素.
element = driver.find_element_by_css_selector('input')
#find_elements_by_css_selector会定位到目标页面所有的input元素.
elements = driver.find_elements_by_css_selector('input')

②根据ID
element = driver.find_element_by_css_selector("#kw")
#可以使用标签+id的css方式定位元素
element = driver.find_element_by_css_selector("form#form")

③根据className
#单一class ,如下所示
<input id="kw" class="s_ipt" autocomplete="off" maxlength="255" value="" name="wd">
element = driver.find_element_by_css_selector(".s_ipt")
#复合class(clss的属性值之间有空格),如下所示
<input id="su" class="bg s_btn" type="submit" value="百度一下">
element = driver.find_element_by_css_selector('.bg.s_btn')

④根据元素属性
 1)精确匹配
 #属性名=属性值,,id,class等都可以写成这种形式
element = driver.find_element_by_css_selector("input[value='百度一下']")
#多属性值
element = driver.find_element_by_css_selector("input[value='百度一下'][type='submit']")
#存在属性。例如img元素存在alt属性
driver.find_element_by_css_selector("img[alt]")
2)模糊匹配(正则表达式匹配属性)
# ^= 匹配到属性值的头部
element = driver.find_element_by_css_selector("input[name^='w']")
# $=匹配到属性值的尾部
element = driver.find_element_by_css_selector("input[name$='d']")
# *=匹配属性值的中间值
element = driver.find_element_by_css_selector("input[value*='度']")

⑤ 查询子元素
1)子元素 A>B(注:不包含孙子辈元素,只有儿子辈元素)
#若使用find_element_by_css_selector,则会查找form标签下的第一个span子元素(不包含孙子辈元素),该span下的第一个input,即为百度首页的输入框
element = driver.find_element_by_css_selector("form>span>input")
#若使用find_elements_by_css_selector,则会查找form标签下所有的span子元素,然后在每一个span元素下查找所有的input元素.
elements = driver.find_elements_by_css_selector("form>span>input")
2)后代元素 A空格B(注:既包含孙子辈元素又包含子元素)
#若使用find_element_by_css_selector会查找form标签下第一个input元素
element = driver.find_element_by_css_selector("form input")
#使用find_elements_by_css_selector会查找form标签下所有的input标签元素
elements = driver.find_elements_by_css_selector("form input")
3)第一个后代元素 :first-child
注: ("form :first-child")会匹配到form标签下的第一个元素及其后代元素中的第一个元素(即只要后代元素中有子元素,都会定位到其第一个子元素);
   若使用find_element_by_css_selector,则会得到上述所有元素的第一个元素;
   若使用find_elements_by_css_selector("form :first-child"),则会得到上述中的所有元素.
#若使用find_element_by_css_selector,则会定位到form标签下第一个span元素的第一个子元素
element = driver.find_element_by_css_selector('form>span :first-child')
#若使用find_elements_by_css_selector,则会定位到form标签下所有span子元素(不包含孙子辈元素)的所有后代元素的第一个元素
element = driver.find_elements_by_css_selector('form>span :first-child')
4)最后一个子元素   :last-child  [类同:first-child]
5)第N个子元素    :nth-child(N)  [类同:first-child]
6)兄弟元素,使用加号
#定位到百度首页的输入框
element = driver.find_element_by_css_selector("form#form>span :first-child+input")
by_css_selector常用定位

cssSelector参考手册

 

 

2.8 by_xpath

by_xpath这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素.Xpath是XML Path的简称,是一门在XML文档中查找信息的语言.由于HTML文档本身就是一个标准的XML页面,所以XPath在XML文档中通过元素和属性进行导航。
     注意:
            ①元素的XPath绝对路径可通过Firefox的FirePath直接查询.
            ②一般不推荐使用绝对路径的写法,因为一旦页面结构发生变化,该路径也随之失效,必须重写.
            ③绝对路径以/表示,相对路径以//表示.
            ④当XPath的路径以/开头时,表示让XPath解析引擎从文档的根节点开始解析。当XPath路径以//开头时,则表示让XPath引擎从文档的任意符合的元素节点开始进行解析。而当/出现在XPath路径中时,则表示寻找父节点的直接子节点,当//出现在XPath路径中时,表示寻找父节点下任意符合条件的子节点,不管嵌套了多少层级.
            ⑤关于XPath这种定位方式,Selenium会将整个页面的所有元素进行扫描以定位我们所需要的元素,所以这是非常耗时的操作,如果脚本中大量使用XPath做元素定位的话,将导致脚本执行速度大大降低.

  <1> 选取节点 

 

   <2>谓语(Predicates):谓语用来查找某个特定的节点或者包含某个指定值的节点.谓语被嵌在[]中

 

 

element = driver.find_element_by_xpath("//input[@id='kw']")
element = driver.find_element_by_xpath("//input[last()-1]")
示例

<3>选取未知节点

 

 

# 选取所有元素,find_element会默认选第一个元素,find_elements会将所有元素放进list中
element = driver.find_element_by_xpath("//*")
#选取所有form节点下的子元素(不包含孙子辈元素)
element = driver.find_elements_by_xpath("//form/*")
#选取带有属性的input元素
element = driver.find_elements_by_xpath("//input[@*]")
示例

<4>选取若干路径:通过在路径表达式中使用'|'元素符,可以选取若干个路径.

 

 

#选取文档中所有的input元素和span元素下的input元素
element = driver.find_elements_by_xpath("//input|//span/input")

<5>XPath Axes(轴):轴可定义相对于当前节点的节点集。

 

 

<6>位置路径表达式

        位置路径可以是绝对的,也可以是相对的.

#查找文档中name属性为tj_trmap,且在先辈节点中存在有id属性为'u1'的div节点的a节点
element = driver.find_elements_by_xpath("//a[@name='tj_trmap' and ancestor::div[@id='u1']]")
#查找文档中name属性为f的input节点之后的所有同级input节点
#若使用find_element,默认查找name属性为f的input节点之后的第一个input节点
element = driver.find_elements_by_xpath("//input[preceding-sibling::input[@name='f']]")
#查找文档中name属性为f的input节点之前的所有同级input节点
element = driver.find_elements_by_xpath("//input[following-sibling::input[@name='f']]")
#查找文档中超链接的文本为地图,且在先辈节点中存在有id属性为u1的div节点的a节点
element = driver.find_element_by_xpath("//a[contains(text(),'地图') and ancestor::div[contains(@id,'u1')]]")
#电子书(王猛)上的例子自己领悟
driver.find_element_by_xpath("//div[preceding-sibling::div/div/a[contains(text(),'苹果')]]/a[text()='删除']")
#练习:自己领悟
driver.find_element_by_xpath("//li[descendant::div[preceding-sibling::div[contains(text(), 'Chaturbate')]]][last()-2]//div[contains(text(),'Someone you')]")
#在文档中查找id属性为u1的div节点的所有a后代节点,且该a节点的文本值为地图
element = driver.find_element_by_xpath("//div[@id='u1']/descendant::a[text()='地图']")
示例

<7>模糊匹配

①contaions关键字
#寻找页面中href属性值包含有order这个单词的所有a元素
driver.find_element_by_xpath("//a[contains(@href, 'order')]")
#也可以用contains关键字进行模糊匹配,比如查找“咖啡”
driver.find_element_by_xpath("//li[contains(text(), '咖')]")
②start-with
#寻找rel属性以mi开头的a元素。其中@后面的rel可以替换成元素的任意其他属性。
driver.find_element_by_xpath("//a[starts-with(@rel, 'mi')]")
③Text关键字
#查找页面中所有的“茶”,根本就不用知道它是个li元素。这种方法也经常用于纯文字的查找。
driver.find_element_by_xpath("//*[text()='茶']")

2.9 js几种定位方法总结

注:除了id是定位到的是单个element元素对象,其他的都是elements返回的是list对象.

1,通过id获取

js = "document.getElementById('su').click()"
driver.execute_script(js)

2,class定位

#使用class定位,获取到的是一个list列表对象
js1 = "document.getElementsByClassName('input-text')[0].value='rwwh'"
driver.execute_script(js1)
js2 = "document.getElementsByClassName('input-text')[1].value='rhww1250.com'"
driver.execute_script(js2)
注:ByName和ByTagName的使用方法和class一样,都是定位一组元素.

3,通过css定位

js = "document.querySelectorAll('#signin')[0].click()"
driver.execute_script(js)

2.10 Jquery定位

语法:$(selector).action
      -- selector:这里的定位语法和css的定位语法一致,如id是#,class是(.),tag标签名前面是无符号.
      -- action:这个是定位元素后的操作行为事件,如click。
jquery2 = "$('#kw').val('第一次')"
driver.execute_script(jquery2)
#清空文本
jquery3 = "$('#kw').val('')"
jquery4 = "$('#su').click()"
driver.execute_script(jquery4)

 

posted on 2020-03-17 23:14  rwwh  阅读(172)  评论(0)    收藏  举报

导航