基础介绍

通过Chrome浏览器自带的开发者工具可以看到,页面元素都是由HTML语言组成的,它们之间有层级地组织起来,每个元素有不同的标签名和属性值,Selenium中WebDriver就是根据这些信息来定位的。

WebDriver提供了8种元素定位方法,在Python中,对应的方法如下:

name Python
id定位 find_element_by_id()
name定位 find_element_by_name()
tag定位 find_element_by_tag_name()
class定位 find_element_by_class_name()
link_text定位 find_element_by_link_text()
partial link定位 find_element_by_partial_link_text()
Xpath定位 find_element_by_xpath()
CSS_selector定位 find_element_by_css_selector()

下面详细介绍如何使用这些定位方法,首先复制百度首页的部分前端代码,用于举例说明:

1
2
3
4
5
6
7
8
9
10
<!-- 该部分为百度首页搜索框与搜索按钮的部分HTML示意(不排除有后续调整id等标签信息的可能性,仅以当时举例) -->
<span id="s_kw_wrap" class="bg s_ipt_wr quickdelete-wrap">
<span class="soutu-btn"></span>
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
<a href="javascript:;" id="quickdelete" title="清空" class="quickdelete" style="top: 0px; right: 0px; display: none;"></a>
</span>
...
<span class="btn_wr s_btn_wr bg" id="s_btn_wr">
<input type="submit" value="百度一下" id="su" class="btn self-btn bg s_btn">
</span>

id定位

HTML规定,HTML标签的id属性值必须是唯一的(如果不唯一,请麻烦前端背锅)。WebDriver提供的id定位方法是通过元素的id来查找元素的,通过id定位百度输入框与百度搜索按钮的示例如下:

1
2
driver.find_element_by_id("kw")
driver.find_element_by_id("su")

name定位

name用来指定元素的姓名(name可以重复),即HTML元素的name属性,通过标签的name属性定位百度输入框的用法如下:

1
driver.find_element_by_name("wd")

class定位

class用来指定元素的类名,即HTML元素的class属性,通过标签的class属性定位百度输入框的用法如下:

1
driver.find_element_by_class_name("s_ipt")

tag定位

tag用来定义不同页面的元素,即HTML元素的标签名,如input标签、a标签等,通过tag name定位百度输入框的用法如下:

1
driver.find_element_by_tag_name("input")

很少用到。

link_text专门用来定位文本链接,例如百度输入框上面几个文字链接的HTML如下:

1
2
3
4
5
6
<div id="u1"><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_text定位链接的用法(当然是用id或者name都是个不错的选择):

1
2
3
4
5
6
driver.find_element_by_link_text("新闻")
driver.find_element_by_link_text("hao123")
driver.find_element_by_link_text("地图")
driver.find_element_by_link_text("视频")
driver.find_element_by_link_text("贴吧")
driver.find_element_by_link_text("学术")

partial link定位

partial link用于对link定位的补充,可以取文字链接的部分文字进行定位,注意,需要这部分文字可以唯一地标识这个链接。

1
<a class="mnav" id="u1">一个很长的文本链接</a>

通过partial link定位如下:

1
2
driver.find_element_by_partial_link_text("一个很长的")
driver.find_element_by_partial_link_text("文本链接")

Xpath定位

Xpath通过元素的路径、属性或者结合层级与属性来进行元素定位。对于要使用Xpath进行定位,而又不了解Xpath的人来说,最省事的办法无非是使用浏览器自带的开发者工具进行Xpath提取:
Xpath.png
如上图所示,选中指定元素右键选择Copy->Copy XPath/Copy full XPath即可。

Copy XPath与Copy full XPath的区别在于,前者会复制混合定位的Xpath,后者则是从HTML头部开始到该元素所在位置的全XPath路径。

1.绝对路径定位

1
driver.find_element_by_xpath("/html/body/div[2]/div[2]/div[5]/div[1]/div/form/span[1]/input")

如需了解详细XPath定位,请移步至XPath教程

2.元素属性定位

1
2
driver.find_element_by_xpath('//input[@id="kw"]')
driver.find_element_by_xpath('//*[@id="su"]')

input表示当前页面某个input标签,*号表示不指定标签名,[@id=”kw”]表示这个元素的id值是kw。同理可得:

1
2
driver.find_element_by_xpath('//*[@name="wd"]')
driver.find_element_by_xpath('//*[@class="s_ipt"]')

上述XPath定位并不仅限于@id、@name、@class,只要目标定位元素的属性能唯一标识这个元素,即使用该属性进行标识。

3.混合定位

如果一个元素本身没有可以唯一标识这个元素的属性值,那么可以查找能唯一标识的父级元素,再按层级向下查找至目标元素即可,即以能唯一标识的父级元素为起点,至目标元素的路径进行定位。

1
driver.find_element_by_xpath('//span[@class="bg s_ipt_wr"]/input')

即通过span[@class=”bg s_ipt_wr”]找到百度输入框的父级元素,/input表示父级元素下面的input子元素,若该父级元素下存在多个input标签的子元素,则可以通过/input[0]、/input[1]等用于区分是第几个元素。

4.使用逻辑运算符

如果一个属性不能唯一区分一个元素,name可以使用逻辑运算符连接多个属性来查找元素。

1
driver.find_element_by_xpath('//input[@id="kw" and @class="s_ipt"]')

表示某个input标签中id为kw且class为s_ipt的元素,仅以id和class属性进行举例,可替换成其他属性。使用频率较低。

5.使用contains方法

contains方法用于匹配一个属性中包含的字符串。

1
driver.find_element_by_xpath('//span[contains(@class,"s_ipt_wr)")]')

表示定位class名包含s_ipt_wr的span标签。使用频率较低。

6.使用text()方法

text()方法用于匹配显示文本信息,如link_text定位可改写为:

1
driver.find_element_by_xpath('//a[text(),"新闻")]')

即匹配标签文本为新闻的a标签。
也可以和上述contains方法结合使用:

1
driver.find_element_by_xpath('//a[text(),"新闻")]')

即匹配标签文本包含新闻的a标签,同partial link定位。

CSS定位

CSS是一种语言,用来描述HTML文档的样式,通过CSS定位需要了解部分CSS知识,CSS选择器的常见语法如下:

选择器 例子 描述
.class .intro class选择器,选择class=”intro”的所有元素
#id #firstname id选择器,选择id=”firstname”的所有元素
* * 选择所有元素
element p 选择所有&#60;p&#62;元素
element>element div>input 选择父元素为&#60;div&#62;的所有&#60;input&#62;元素
element+element div+input 选择同一级中紧接在&#60;div&#62;元素只有的所有&#60;input&#62;元素
[attribute=value] [target=_blank] 选择target=”_blank”的所有元素

1.通过class定位

1
2
driver.find_element_by_css_selector(".s_ipt")
driver.find_element_by_css_selector(".s_btn")

定位页面中class为s_ipt、s_btn的元素,点号(.)在CSS中用于指代class名。

2.通过id定位

1
2
driver.find_element_by_css_selector("#kw")
driver.find_element_by_css_selector("#su")

定位页面中id为kw、su的元素,井号(#)在CSS中用于指代id名。

3.通过标签名定位

1
driver.find_element_by_css_selector("input")

定位页面中标签为input的元素,使用标签名定位元素是不需要任何符号标识,直接使用标签名即可。

4.通过标签层级关系定位

1
driver.find_element_by_css_selector("span > input")

定位页面中父元素为span的所有input元素。

5.通过属性定位

1
2
3
driver.find_element_by_css_selector("[autocomplete=off]")
driver.find_element_by_css_selector("[name='kw']")
driver.find_element_by_css_selector('[type="submit"]')

定位页面中属性autocomplete=off、name=’kw’、type=”submit”的元素,同前面所说的属性定位方法,只要该属性能唯一标识这个元素,均可以进行定位。

6.组合定位

1
2
driver.find_element_by_css_selector("form.fm > span > input.s_ipt")
driver.find_element_by_css_selector("form#form > span > input#kw")

定位页面中标签名为input,class属性为s_ipt,父元素为span,父元素的父元素为form且class属性为fm的元素。

7.更多定位用法

CSS选择器的更多用法可以查看CSS选择器参考手册

用By定位元素

用By定位元素和前面所述的八种基本定位方法相同,仅仅是写法上略有不同而已,具体如下:

name Python By定位元素
id定位 find_element_by_id() find_element(By.ID, “kw”)
name定位 find_element_by_name() find_element(By.NAME, “wd”)
tag定位 find_element_by_tag_name() find_element(By.CLASS_NAME, “s_ipt”)
class定位 find_element_by_class_name() find_element(By.TAG_NAME, “input”)
link_text定位 find_element_by_link_text() find_element(By.LINK_TEXT, “新闻”)
partial link定位 find_element_by_partial_link_text() find_element(By.PARTIAL_LINK_TEXT, “新”)
Xpath定位 find_element_by_xpath() find_element(By.XPATH, “//*[@id=’su’]”)
CSS_selector定位 find_element_by_css_selector() find_element(By.CSS_SELECTOR, “span.bh s_btn_wr>input#su”)

以上就是全部Selenium+Python定位的介绍了。