Python Selenium: 元素定位

想要操作web页面上的元素,首先必须要定位到这个元素上。每个元素都有他各自的属性,比如id,name,class等,我们就通过这些属性来定位元素。

定位方法

webdriver提供的定位方法如下:

名称定义Python用法
ID通过ID定位元素find_element_by_id()
NAME通过NAME定位元素find_element_by_name()
CLASS_NAME通过CLASS_NAME定位元素find_element_by_class_name()
TAG_NAME通过TAG_NAME定位元素find_element_by_tag_name()
LINK_TEXT通过链接的文字定位元素find_element_by_link_text()
PARTIAL_LINK_TEXT通过部分的链接文字定位元素find_element_by_partial_link_text()
XPATH通过XPATH定位元素find_element_by_xpath()
CSS_SELECTOR通过CSS_SELECTOR定位元素find_element_by_css_selector()

id、name、class name、tag name定位元素

html中,大多数的元素都具备id和name的属性,并且id是唯一的,因此用id和name来定位元素是比较常见的方式。
不过有的元素并不具备id和name属性,我们则可以用class name来定位元素。
当然我还可以用tag name来定位,但是标签名字太容易重复,除非想定位一组相同标签的元素,否则一般不推荐使用。
我们来看一下百度首页的搜索框和搜索按钮的html代码

...
<span class="bg s_ipt_wr quickdelete-wrap">
    <span class="soutu-btn"></span>
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    <a href="javascript:;" id="quickdelete" title="清空" class="quickdelete" style="top: 0px; right: 0px; display: none;"></a>
</span>
<span class="bg s_btn_wr">
    <input type="submit" id="su" value="百度一下" class="bg s_btn">
</span>
...

从上面代码我们看到,搜索框具备id=“kw”,name=“wd”,class="s_ipt"的属性,搜索按钮具备id=“su”,class="bg s_btn"的属性,我们分别用这些属性来定位操作搜索框和搜索按钮(为了方便看到结果,每一步我都停止1秒)。

#coding = utf-8
from selenium import webdriver #导入selenium的webdriver包
from time import sleep

driver = webdriver.Chrome() #获得浏览器对象,这里我使用的是chrome
driver.get("https://www.baidu.com") #打开网址

driver.find_element_by_id('kw').send_keys('test1') #使用id定位,在搜索框中输入test1
sleep(1)
driver.find_element_by_name('wd').clear() #使用name定位,删除搜索框中输入的文字
sleep(1)
driver.find_element_by_class_name('s_ipt').send_keys('python')#使用class name定位,再一次在搜索框中输入文字
sleep(1)
driver.find_element_by_id('su').click()#使用id定位,点击‘百度一下’按钮进行搜索
sleep(1)

driver.quit() #关闭浏览器

link text、partial link text定位

对于一个链接,我们可以使用link text和partial link text来定位。
我们先自己写一个html test sample,保存为test.html。这个网页会显示三个指向百度的链接,但每个链接的显示文字不同

<html>
    <head>
        <title>link Test Html</title>
    </head>
    <body>
        <a href = 'https://www.baidu.com'>baidu</a>
        <br>
        <a href = 'https://www.baidu.com'>also baidu</a>
        <br>
        <a href = 'https://www.baidu.com'>still baidu</a>
    </body>
</html>

接着我们用link text和partial link text来定位这三个链接,并点击。注意python文件要与上面的html文件在同一个文件夹下

#coding = utf-8
from selenium import webdriver #导入selenium的webdriver包
from time import sleep
import os

driver = webdriver.Chrome() 
file_name = 'file:///' + os.path.abspath('test.html')
driver.get(file_name) #打开网址

driver.find_element_by_link_text('baidu').click()#使用link text定位
sleep(1)
driver.back() # 浏览器后退到上一个页面
sleep(1)
driver.find_element_by_link_text('also baidu').click() 
sleep(1)
driver.back()
sleep(1)
driver.find_element_by_partial_link_text('still').click()#使用partial link text定位
sleep(1)

driver.quit()

XPATH定位

XPath是XML和Path的缩写,是一种在XML文档中定位元素的语言。与CSS Selector不同,XPath支持向前和向后查找,而CSS Selector只能向前查询。这说明,使用XPATH方法,可以通过子元素定位父元素。
常用的定位方法有以下几种:

  • 使用绝对路径定位(当页面发生变化时,绝对路径可能会失败)
  • 使用相对路径定位
  • 使用索引定位(可与绝对路径相对路径结合使用)
  • 使用属性定位(XPATH还支持布尔运算,可以与属性定位结合使用)
#绝对路径,寻找html → body → div → input元素,一层一层定位寻找
find_element_by_xpath('html/body/div/input') 

#相对路径,先定位到div,再找到div下的input
find_element_by_xpath('//div/input')

#带索引的绝对路径,寻找body下面第三个div下的span/p
find_element_by_xpath('html/body/div[3]/span/p') 

#带索引的相对路径,寻找div下第二个span下面的input
find_element_by_xpath('//div/span[2]/input') 

#属性定位
find_element_by_xpath('//span[@id = 'test']/input') #寻找id为test的span下面的input
find_element_by_xpath('//input[@type]') #寻找带有type属性的input
find_element_by_xpath('//input[@name = 'search' and @type = 'text']') #使用布尔运算:寻找name为search并且type为text的input(也可以使用布尔运算or)
find_element_by_xpath('//a[starts-with(@href,'https://www.b')]') #模糊匹配,寻找以https://www.b开头的网址(可以使用ends-with,以结尾、contains包含)
find_element_by_xpath('//a[@*='test']')#定位任意值匹配,所有含有属性test的网址

CSS Selector定位

使用CSS Selector来定位元素,一般比XPATH更快更准确也更容易,但学习它的语法,相对XPATH来说会难一些。我们先来看一下CSS Selector的语法。

以上图片取自W3school,内有详细举例说明,请参照:W3school CSS选择器

这其中比较常用的有以下几种:

选择器例子描述
.class.introclass选择器,选择class="intro"的所有元素
#id#firstid选择器,选择id="first"的所有元素
**选择所有元素
elementinput选择所有<input>元素
element,elementdiv,p并列选择,所有<div>和所有<p>元素
element elementdiv p后代选择,<div>中内部包含的所有<p>元素
element>elementdiv>p子元素选择,父元素为<div>的所有<p>元素
换言之,若一个<p>元素是<div>子元素的子元素,则不会被选中
element+elementdiv+p相邻选择,紧接<div>的<p>元素(只会选中第一个邻接<p>元素)
element~elementdiv~p同级选择,在<div>之后的同级<p>元素
element[attribute]a[target]选择带有target属性的<a>元素
element[attribute=value]a[target=_blank]选择target="_blank"的<a>元素
element[attribute~=value]a[title~=flower]选择target属性包含flower的<a>元素
element[attribute|=value]a[target|=to]选择target属性值以"to"开头的<a>元素
element[attribute^=value]a[src^=“https”]选择src属性以"https"开头的<a>元素
element[attribute$=value]a[src$=".com"]选择src属性以".com"结尾的<a>元素
element[attribute*=value]a[src*=“aaa”]选择src属性包含"aaa"的<a>元素
element:first-of-typep:first-of-type选择元素<p>其父元素的首个<p>元素
同理可推论:last-of-type、:only-of-type使用
element:only-childp:only-child选择元素<p>其父元素的唯一子元素<p>
element:nth-child(n)p:nth-child(2)选择元素<p>其父元素的第二个子元素<p>
同理可推论:nth-last-chiled(n)、:last-child用法
:root:root选择根元素
element:emptyp:empty选择没有子元素的<p>元素

使用

分别用XPATH和CSS Selector来定位元素
我们使用下面的test.html来练习。

<!DOCUMENTTYPE html>
<html>
    <head>
        <title>Test Html</title>
    </head>
    <body>
        <div id='div1'>
            <input type='checkbox' name='1'>option1</input>
            <input type='checkbox' name='2' >option2</input>
            <input type='checkbox' name='3' id='id_option3'>option3</input>
        </div>
        <input type='checkbox'>option</input>
        <div id='div2'>
            <input type = 'radio' name = '4'>option4</input>
            <input type = 'radio' name = '4'>option5</input>
            <input type = 'radio' name = '4'>option6</input>
        </div>
    </body>
</html>

我们使用XPATH和CSS Selector的几种方法来分别点击几个选项来观察是否实现了定位元素的效果

#coding = utf-8
from selenium import webdriver #导入selenium的webdriver包
from time import sleep
import os

driver = webdriver.Chrome() #获得浏览器对象,这里我使用的是chrome
file_name = 'file:///' + os.path.abspath('inner.html')
driver.get(file_name) #打开网址

driver.find_element_by_xpath("html/body/div/input").click()#xpath绝对路径定位,点击opthon1
sleep(2)
driver.find_element_by_xpath("//div[@id='div1']/input").click()#xpath带属性的相对路径定位,再次点击option1
sleep(2)
driver.find_element_by_xpath("html/body/div[2]/input").click()#xpath带索引的绝对路径定位,点击option4
sleep(2)
driver.find_element_by_xpath("//input[@type='checkbox' and @name='3']").click()#带布尔运算的属性绝对路径定位,点击option3
sleep(2)
driver.find_element_by_css_selector("#id_option3").click()#使用id定位,再次点击option3
sleep(2)
driver.find_element_by_css_selector("div+input").click()#div相邻的input元素,点击option,注意此处input不是div的子元素
sleep(2)
driver.find_element_by_css_selector("#div2>input:nth-child(2)").click()#id为div2下第二个input定位,点击option5
sleep(2)

driver.quit() #关闭浏览器

在实际使用中,我们要定位的情况比例子中要复杂的多,需要大量练习才能得心应手。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值