基础介绍
通过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() |
下面详细介绍如何使用这些定位方法,首先复制百度首页的部分前端代码,用于举例说明:
<!-- 该部分为百度首页搜索框与搜索按钮的部分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定位百度输入框与百度搜索按钮的示例如下:
driver.find_element_by_id("kw")
driver.find_element_by_id("su")
name定位
name用来指定元素的姓名(name可以重复),即HTML元素的name属性,通过标签的name属性定位百度输入框的用法如下:
driver.find_element_by_name("wd")
class定位
class用来指定元素的类名,即HTML元素的class属性,通过标签的class属性定位百度输入框的用法如下:
driver.find_element_by_class_name("s_ipt")
tag定位
tag用来定义不同页面的元素,即HTML元素的标签名,如input标签、a标签等,通过tag name定位百度输入框的用法如下:
driver.find_element_by_tag_name("input")
很少用到。
link_text定位
link_text专门用来定位文本链接,例如百度输入框上面几个文字链接的HTML如下:
<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都是个不错的选择):
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定位的补充,可以取文字链接的部分文字进行定位,注意,需要这部分文字可以唯一地标识这个链接。
<a class="mnav" id="u1">一个很长的文本链接</a>
通过partial link定位如下:
driver.find_element_by_partial_link_text("一个很长的")
driver.find_element_by_partial_link_text("文本链接")
Xpath定位
Xpath通过元素的路径、属性或者结合层级与属性来进行元素定位。对于要使用Xpath进行定位,而又不了解Xpath的人来说,最省事的办法无非是使用浏览器自带的开发者工具进行Xpath提取:Copy XPath与Copy full XPath的区别在于,前者会复制混合定位的Xpath,后者则是从HTML头部开始到该元素所在位置的全XPath路径。
1.绝对路径定位
driver.find_element_by_xpath("/html/body/div[2]/div[2]/div[5]/div[1]/div/form/span[1]/input")
如需了解详细XPath定位,请移步至XPath教程
2.元素属性定位
driver.find_element_by_xpath('//input[@id="kw"]')
driver.find_element_by_xpath('//*[@id="su"]')
input表示当前页面某个input标签,*号表示不指定标签名,[@id="kw"]表示这个元素的id值是kw。同理可得:
driver.find_element_by_xpath('//*[@name="wd"]')
driver.find_element_by_xpath('//*[@class="s_ipt"]')
上述XPath定位并不仅限于@id、@name、@class,只要目标定位元素的属性能唯一标识这个元素,即使用该属性进行标识。
3.混合定位
如果一个元素本身没有可以唯一标识这个元素的属性值,那么可以查找能唯一标识的父级元素,再按层级向下查找至目标元素即可,即以能唯一标识的父级元素为起点,至目标元素的路径进行定位。
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可以使用逻辑运算符连接多个属性来查找元素。
driver.find_element_by_xpath('//input[@id="kw" and @class="s_ipt"]')
表示某个input标签中id为kw且class为s_ipt的元素,仅以id和class属性进行举例,可替换成其他属性。使用频率较低。
5.使用contains方法
contains方法用于匹配一个属性中包含的字符串。
driver.find_element_by_xpath('//span[contains(@class,"s_ipt_wr)")]')
表示定位class名包含s_ipt_wr的span标签。使用频率较低。
6.使用text()方法
text()方法用于匹配显示文本信息,如link_text定位可改写为:
driver.find_element_by_xpath('//a[text(),"新闻")]')
即匹配标签文本为新闻的a标签。
也可以和上述contains方法结合使用:
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 | 选择所有<p>元素 |
element>element | div>input | 选择父元素为<div>的所有<input>元素 |
element+element | div+input | 选择同一级中紧接在<div>元素只有的所有<input>元素 |
[attribute=value] | [target=_blank] | 选择target="_blank"的所有元素 |
1.通过class定位
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定位
driver.find_element_by_css_selector("#kw")
driver.find_element_by_css_selector("#su")
定位页面中id为kw、su的元素,井号(#)在CSS中用于指代id名。
3.通过标签名定位
driver.find_element_by_css_selector("input")
定位页面中标签为input的元素,使用标签名定位元素是不需要任何符号标识,直接使用标签名即可。
4.通过标签层级关系定位
driver.find_element_by_css_selector("span > input")
定位页面中父元素为span的所有input元素。
5.通过属性定位
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.组合定位
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定位的介绍了。
欢迎访问我的个人博客:Lemon - 万事顺遂