selenium - webdriver 元素定位
webdriver是selenium体系中设计出来操作浏览器的一套API。站在编程语言的角度,webdriver是Python的一个用于实现web自动化的第三方库。
web页面上一般有输入框、按钮、文字、文字链接、图片、下拉框等等元素,web自动化要做的就是模拟鼠标和键盘来操作这些元素。首先,要找到它们。webdriver提供了8种元素定位方法(常用红色的3种):
- id
- name
- class name
- tag name
- link text
- partial link text
- xpath
- css selector
下面分别介绍(用百度首页举例):
1. id定位
id具有唯一性
如百度首页上的抗击肺炎链接,找到元素后,复制元素信息,如下:
<a href="https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1" name="tj_trvirus" id="virus-2020" class="mnav sp dot">抗击肺炎</a>
查找元素时,可以按照id查找,如下:
driver.find_element_by_id('virus-2020').click()
2. name定位
name属性不唯一
有时,页面元素没有ID属性,可以使用name属性来定位,元素如下:
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a>
按照name查找,如下:
driver.find_element_by_name('tj_trnews').click()
3. class name定位
通过class来定位“更多产品”按钮,元素如下:
<a href="http://www.baidu.com/more/" name="tj_briicon" class="bri" style="display: block;">更多产品</a>
按照class查找,如下:
driver.find_element_by_class_name('bri').click()
4. tag name定位
每一个元素本质上就是一个tag。
tag往往用来定义一类功能,如<input>、<div>等,所以通过tag识别某个元素的概率很低,很难通过tag区分不同的元素
如百度一下按钮:
<input type="submit" id="su" value="百度一下" class="bg s_btn">
按照tag查找,如下:
driver.find_element_by_tag_name('input')
5. link text定位
link专门用来定位文本链接,通过元素标签对之间的文本信息来定位元素
如百度首页上方的新闻、地图、视频等,元素如下:
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a> <a href="https://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a> <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a> <a href="http://xueshu.baidu.com" name="tj_trxueshu" class="mnav">学术</a>
通过link定位,如下:
driver.find_element_by_link_text('新闻').click()
driver.find_element_by_link_text('hao123').click()
6. partial link text定位
partial link是对link的一种补充,有些文本链接的文字比较长,可以取其中的一部分文字定位。如“抗击肺炎”,可以只取“肺炎”来定位
元素信息如下:
<a href="https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1" name="tj_trvirus" id="virus-2020" class="mnav sp dot">抗击肺炎</a>
用partial link定位,如下:
driver.find_element_by_partial_link_text('肺炎').click()
7. xpath定位
xpath是一种在XML文档中定位元素的语言。(HTML可以看做是XML的一种实现)
在实际项目中,有时候元素没有ID、name这些属性,或者多个元素的name属性相同,又或者每次刷新页面id值都会随机变化,这时,可以使用xpath定位(下面4种方法均可,但一般情况下,在元素信息右键,选择copy xpath,即可自动复制出适合的xpath)
a) 绝对路径
xpath主要用标签名的层级关系来定位元素的绝对路径,如果一个层级下有多个相同的标签名,则按上下顺序确定位置,如div[2]表示当前层级下的第二个div标签。(下标从1开始计数)
如,定位百度首页的“新闻”,复制绝对路径为/html/body/div[1]/div[1]/div/div[3]/a[2],定位如下:
driver.find_element_by_xpath('/html/body/div[1]/div[1]/div/div[3]/a[2]').click()
b) 利用元素属性定位
标签和属性
如,抗击肺炎的文字链接:(当前页面某个目录下,标签名为a,id=virus-2020的元素)
也可以用name、class等属性
driver.find_element_by_xpath('//a[@id="virus-2020"]').click() driver.find_element_by_xpath('//*[@id="virus-2020"]').click() # 如果不想指定标签名,也可以用*星号替代
c) 层级与属性结合
如果一个元素本身没有可以唯一标识这个元素的属性值,我们就可以找其上一级元素,或上上一级,一直找到最外层的<html>标签,就是一个绝对路径的写法了
<span class="bg s_btn_wr">
<input type="submit" id="su" value="百度一下" class="bg s_btn">
</span>
按照父元素查找百度一下按钮,如下:
driver.find_element_by_xpath('//span[@class="bg s_btn_wr"]/input').click()
d) 使用逻辑运算符
如果一个属性不能唯一的区分一个元素,可以使用逻辑运算符连接多个属性来查找
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a> <a href="https://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a>
新闻和hao123的class相同,所以查找新闻,需要多个属性,如下:
driver.find_element_by_xpath('//a[@name="tj_trnews" and @class="mnav"]').click()
8. css定位
css和xpath只掌握一种,即可解决大部分定位问题,so~
ps:
使用xpath定位语法:
通过属性定位:xpath = "//标签名[@属性='属性值']"
通过多个属性定位:xpath= "//input[@type='XX' and @name='XX']"
属性包含某字段:xpath = "//标签名[contains(@属性, '属性值')]" (属性值可以填属性值的部分内容)
属性以某字段开头://tbody/tr[2]/td[starts-with(text(), "汇付")]
通过文本定位:xpath = "//a[text()='XX']"
定位一组元素的最后一个://tbody/tr[1]/td[last()]
定位一组元素的倒数第二个://tbody/tr[1]/td[last()-1]
通过父级元素查找:(定位百度输入框)
//form[@id="form"]/span[contains(@class,"s_ipt")]/input[@id="kw"]
//form[@id="form"]//input[@id="kw"]
通过子节点定位父节点://div[@id='C']/../.. ( .. 代表父节点)
找兄弟节点://div[@id='D']/../div[1] (通过D找brother 1)
<div>brother 1</div> <div id="D"></div> <div>brother 2</div>