关于页面元素定位,可以根据 id、class、name 属性以及 link_text。
其中 id 属性是最理想的定位方式,class 与 name 属性,有时候也还行。
但是,如果要定位的元素,没有上述的属性,或者通过上述属性找到多个元素,该怎么办?
Selenium 提供了2种可以唯一定位的方式:
find_element_by_css_selector
find_element_by_xpath
find_element_by_css_selector
原理
HTML 中经常要为页面上的元素指定显示效果,比如前景文字颜色是红色,背景颜色是黑色, 字体是微软雅黑,输入框的宽与高等。
以上这一切,都是靠 css
来告诉浏览器:要选择哪些元素, 显示怎样的风格。
如下图,豆瓣上“登陆豆瓣”的按钮,就是 css
告诉浏览器:.account-anonymous .account-form-field-submit .btn
这个按钮,背景颜色是浅绿色,高是34px
等
其中,.account-anonymous .account-form-field-submit .btn
就是 css selector
,也称为 css
选择器。
css selector
语法就是用来选择元素的。
既然 css selector
语法 天生就是浏览器用来选择元素的,Selenium 自然就可以将它运用到自动化中,来定位要操作的元素了。
只要 css selector
的语法是正确的, Selenium 就可以定位到指定的元素。
根据标签(tag)名定位
HTML 中,以下都属于标签:
<a>a>
<div>div>
<h1>h1>
<script>script>
<body>body>
<span>span>
<footer>footer>
<input>
<form>form>
<button>button>
验证与搜索方式&#xff1a;
- 按
F12
打开 开发者工具栏 - 按
Ctrl
键 和 F 键&#xff0c; 显示搜索框
应用&#xff1a;
from selenium import webdriver driver &#61; webdriver.Chrome()
driver.get(&#39;https://www.douban.com/&#39;)
element &#61; driver.find_element_by_css_selector("a")
print(element.text) driver.quit()
根据 id 定位
根据 id 属性选择元素的语法是&#xff0c;在 id 前面加上一个 “#” 号&#xff1a; #id值
应用&#xff1a;
from selenium import webdriver
from time import sleep driver &#61; webdriver.Chrome()
driver.maximize_window()
driver.get(&#39;https://www.baidu.com/&#39;)
sleep(2)
element &#61; driver.find_element_by_css_selector("#kw")
element.send_keys("自动化测试")
sleep(3)
driver.quit()
根据 class 定位
根据 class 属性选择元素的语法是&#xff0c;在 class 值前面加上一个"."&#xff1a; .class值
应用&#xff1a;
from selenium import webdriver
from time import sleep driver &#61; webdriver.Chrome()
driver.maximize_window()
driver.get(&#39;https://www.baidu.com/&#39;)
sleep(2)
element &#61; driver.find_element_by_css_selector(".s-top-login-btn")
element.click()
sleep(3) driver.quit()
根据子元素与后代元素定位
HTML中&#xff0c; 元素内部可以包含其他元素&#xff0c; 比如 下面的 HTML片段&#xff1a;
<div id&#61;&#39;container&#39;><div id&#61;&#39;layer1&#39;> <div id&#61;&#39;inner11&#39;> <span id&#61;&#39;span1&#39;>内层11span> div><div id&#61;&#39;inner12&#39;><span>内层12span>div>div><div id&#61;&#39;layer2&#39;><div id&#61;&#39;inner21&#39;><span>内层21span>div>div>
div>
子元素
如果 元素2 是 元素1 的 直接子元素&#xff0c; css selector
选择直接子元素的语法是&#xff1a;
元素1 > 元素2
元素1 > 元素2 > 元素3 > 元素4
#container > #layer1
#layer1 > #inner11
#container > #layer1 > #inner11
#inner11 > #span1
#layer1 > #inner11 > #span1
#container > #layer1 > #inner11 > #span1
实际应用&#xff1a;
from selenium import webdriver
from time import sleep driver &#61; webdriver.Chrome()
driver.maximize_window()
driver.get(&#39;https://www.baidu.com/&#39;)
sleep(2)
element &#61; driver.find_element_by_css_selector(".s_ipt_wr > #kw")
element.send_keys("自动化测试")
sleep(3) driver.quit()
后代元素
如果元素2是元素1的后代元素&#xff08;后代元素包含子元素&#xff09;&#xff0c; css selector
选择后代元素的语法是:
元素1 元素2
元素1 元素2 元素3 元素4
#container #layer1
#layer1 #inner11
#container #inner11
#inner11 #span1
#layer1 #span1
#container #span1
实际应用&#xff1a;
from selenium import webdriver
from time import sleep driver &#61; webdriver.Chrome()
driver.maximize_window()
driver.get(&#39;https://www.baidu.com/&#39;)
sleep(2)
element &#61; driver.find_element_by_css_selector("#form #kw")
element.send_keys("自动化测试")
sleep(3)
driver.quit()
根据属性定位
在 HTML 中&#xff0c;id
与 class
是常用的属性&#xff0c;当然&#xff0c;一个标签内可以包含多个属性&#xff0c;同时属性名称也可以是自定义的&#xff0c;如下面的 HTML 代码段所示&#xff1a;
<li id&#61;"quick-entrance"><a href&#61;"https://www.lagou.com/s/subscribe.html" data-lg-webtj-_address_id&#61;"1nny" data-lg-webtj-_seq&#61;"1" rel&#61;"nofollow">职位订阅a>
li>
css selector
支持通过任何属性来选择元素&#xff0c;语法是用一个方括号 []
。
[id&#61;"quick-entrance"]
li[id&#61;"quick-entrance"]
a[href&#61;"https://www.lagou.com/s/subscribe.html"]
a[data-lg-webtj-_address_id&#61;"1nny"]
a[data-lg-webtj-_seq&#61;"1"]
a[rel&#61;"nofollow"]
另外&#xff0c;css selector
根据属性值定位&#xff0c;还支持模糊匹配&#xff1a;
- 包含关系
*&#61;
&#xff1a;a[href*&#61;"lagou.com/s/"]
- 匹配开头
^&#61;
&#xff1a;a[href^&#61;"https://www.lagou"]
- 匹配结尾
$&#61;
&#xff1a;a[href$&#61;"lagou.com/s/subscribe.html"]
如果一个元素具有多个属性&#xff0c;css selector
还可以同时限制多个属性&#xff1a;
a[rel&#61;"nofollow"][data-lg-webtj-_seq&#61;"1"]
实际应用&#xff1a;
from selenium import webdriver
from time import sleep driver &#61; webdriver.Chrome()
driver.maximize_window()
driver.get(&#39;https://www.baidu.com/&#39;)
sleep(2)
element &#61; driver.find_element_by_css_selector("input[id&#61;&#39;kw&#39;]")
element.send_keys("自动化测试")
sleep(3)
driver.quit()
联合使用
css selector
支持选择语法的联合使用。如下面的 HTML 代码段&#xff1a;
<div id&#61;&#39;bottom&#39;><div class&#61;&#39;footer1&#39;><span class&#61;&#39;copyright&#39;>版权span><span class&#61;&#39;date&#39;>发布日期&#xff1a;2018-03-03span>div><div class&#61;&#39;footer2&#39;><span>备案号<a href&#61;"http://www.miitbeian.gov.cn">苏ICP备88885574号a>span>div>
div>
div.footer1 > span.copyright
div[id&#61;&#39;bottom&#39;] span[class&#61;&#39;copyright&#39;]
#bottom .copyright
.footer1 .copyright
根据次序选择子节点
父元素的第n个子节点
使用 nth-child(n)
&#xff0c;可以指定选择父元素的第几个子节点。
注意&#xff1a;
父元素的倒数第n个子节点
使用 nth-last-child(n)
&#xff0c;可以倒过来&#xff0c;选择的是父元素的倒数第几个子节点。
父元素的第几个某类型的子节点
使用 nth-of-type(n)
&#xff0c;可以指定选择的元素是父元素的第几个某类型的子节点。
父元素的倒数第几个某类型的子节点
使用 nth-last-of-type(n)
&#xff0c;可以倒过来&#xff0c; 选择父元素的倒数第几个某类型的子节点。
奇数节点和偶数节点
如果要选择的是父元素的偶数节点&#xff0c;使用 nth-child(even)
如果要选择的是父元素的奇数节点&#xff0c;使用 nth-child(odd)
如果要选择的是父元素的某类型偶数节点&#xff0c;使用 nth-of-type(even)
如果要选择的是父元素的某类型奇数节点&#xff0c;使用 nth-of-type(odd)
根据兄弟节点选择
相邻兄弟节点选择
使用方法&#xff1a;标签类型1 &#43; 标签类型2
&#xff0c;两者为兄弟标签&#xff08;同级标签&#xff09;&#xff0c;定位到紧跟 标签类型1 后的第1个 标签类型2 的元素&#xff0c;如下图所示&#xff1a;
后续所有兄弟节点选择
使用方法&#xff1a;标签类型1 ~ 标签类型2
&#xff0c;选择 标签类型1 后续兄弟节点中所有的 标签类型2 的元素&#xff0c;如下图所示&#xff1a;
总结