乐趣区

关于selenium:selenium-定位方式3cssselector

对于页面元素定位,能够依据 id、class、name 属性以及 link_text。

其中 id 属性是最现实的定位形式,class 与 name 属性,有时候也还行。

然而,如果要定位的元素,没有上述的属性,或者通过上述属性找到多个元素,该怎么办?

Selenium 提供了 2 种能够惟一定位的形式:

  1. find_element_by_css_selector
  2. 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>

验证与搜寻形式:

  1. F12 关上 开发者工具栏
  2. Ctrl 键 和 F 键,显示搜寻框

利用

# find_element_by_css_selector 的利用:依据标签(tag)名定位
from selenium import webdriver  # 导入 webdriver 模块

driver = webdriver.Chrome()  # 调用 Chrome 浏览器
driver.get('https://www.douban.com/')  # 关上豆瓣
element = driver.find_element_by_css_selector("a")  # 依据 a 标签定位元素
print(element.text)  # 打印 定位元素 的文本

driver.quit()  # 敞开浏览器

依据 id 定位

依据 id 属性抉择元素的语法是,在 id 后面加上一个 “#” 号:#id 值

利用

# find_element_by_css_selector 的利用:依据 id 定位
from selenium import webdriver  # 导入 webdriver 模块
from time import sleep  # 导入 sleep 模块,能够使程序强制休眠

driver = webdriver.Chrome()  # 调用 Chrome 浏览器
driver.maximize_window()  # 窗口最大化
driver.get('https://www.baidu.com/')  # 关上 百度
sleep(2)  # 强制休眠 2 秒
element = driver.find_element_by_css_selector("#kw")  # 依据 id 定位元素
element.send_keys("自动化测试")  # 输出内容
sleep(3)  # 强制休眠 3 秒
driver.quit()  # 敞开浏览器

依据 class 定位

依据 class 属性抉择元素的语法是,在 class 值后面加上一个 ”.”:.class 值

利用

# find_element_by_css_selector 的利用:依据 class 定位
from selenium import webdriver  # 导入 webdriver 模块
from time import sleep  # 导入 sleep 模块,能够使程序强制休眠

driver = webdriver.Chrome()  # 调用 Chrome 浏览器
driver.maximize_window()  # 窗口最大化
driver.get('https://www.baidu.com/')  # 关上 百度
sleep(2)  # 强制休眠 2 秒
element = driver.find_element_by_css_selector(".s-top-login-btn")  # 依据 class 定位元素
element.click()  # 点击定位元素
sleep(3)  # 强制休眠 3 秒

driver.quit()  # 敞开浏览器

依据子元素与后辈元素定位

HTML 中,元素外部能够 蕴含其余元素,比方 上面的 HTML 片段:

<div id='container'>
    <div id='layer1'>  <!--layer1 是 container 的间接子元素 -->
        <div id='inner11'>  <!--inner11 是 layer1 的间接子元素,是 container 的后辈元素 -->
            <span id='span1'> 内层 11</span>  <!--span1 是 inner11 的间接子元素,是 layer1 与 container 的后辈元素 -->
        </div>
        <div id='inner12'>
            <span> 内层 12</span>
        </div>
    </div>
    <div id='layer2'>
        <div id='inner21'>
            <span> 内层 21</span>
        </div>
    </div> 
</div>
子元素

如果 元素 2 是 元素 1 的 间接子元素,css selector 抉择间接子元素的语法是:

/* 一个层级 */
元素 1 > 元素 2
/* 多个层级 */
元素 1 > 元素 2 > 元素 3 > 元素 4
/* layer1 是 container 的间接子元素 */
#container > #layer1
/* inner11 是 layer1 的间接子元素,是 container 的后辈元素 */
#layer1 > #inner11
#container > #layer1 > #inner11
/* span1 是 inner11 的间接子元素,是 layer1 与 container 的后辈元素 */
#inner11 > #span1
#layer1 > #inner11 > #span1
#container > #layer1 > #inner11 > #span1

理论利用:

# find_element_by_css_selector 的利用:依据 子元素 定位
from selenium import webdriver  # 导入 webdriver 模块
from time import sleep  # 导入 sleep 模块,能够使程序强制休眠

driver = webdriver.Chrome()  # 调用 Chrome 浏览器
driver.maximize_window()  # 窗口最大化
driver.get('https://www.baidu.com/')  # 关上 百度
sleep(2)  # 强制休眠 2 秒
element = driver.find_element_by_css_selector(".s_ipt_wr > #kw")  # 依据 子元素 定位元素
element.send_keys("自动化测试")  # 输出内容
sleep(3)  # 强制休眠 3 秒

driver.quit()  # 敞开浏览器
后辈元素

如果元素 2 是元素 1 的 后辈元素 后辈元素蕴含子元素),css selector 抉择后辈元素的语法是:

/* 一个层级 */
元素 1 元素 2
/* 多个层级 */
元素 1 元素 2 元素 3 元素 4
/* layer1 是 container 的间接子元素 */
#container #layer1
/* inner11 是 layer1 的间接子元素,是 container 的后辈元素 */
#layer1 #inner11
#container #inner11
/* span1 是 inner11 的间接子元素,是 layer1 与 container 的后辈元素 */
#inner11 #span1
#layer1 #span1
#container #span1

理论利用:

# find_element_by_css_selector 的利用:依据 后辈元素 定位
from selenium import webdriver  # 导入 webdriver 模块
from time import sleep  # 导入 sleep 模块,能够使程序强制休眠

driver = webdriver.Chrome()  # 调用 Chrome 浏览器
driver.maximize_window()  # 窗口最大化
driver.get('https://www.baidu.com/')  # 关上 百度
sleep(2)  # 强制休眠 2 秒
element = driver.find_element_by_css_selector("#form #kw")  # 依据 后辈元素 定位元素
element.send_keys("自动化测试")  # 输出内容
sleep(3)  # 强制休眠 3 秒
driver.quit()  # 敞开浏览器

依据属性定位

在 HTML 中,idclass 是罕用的属性,当然,一个标签内能够蕴含多个属性,同时属性名称也能够是自定义的,如上面的 HTML 代码段所示:

<li id="quick-entrance">
    <a href="https://www.lagou.com/s/subscribe.html" 
       data-lg-webtj-_address_id="1nny" 
       data-lg-webtj-_seq="1" 
       rel="nofollow">
        职位订阅
    </a>
</li>
<!--
li 标签含有的属性:id
a 标签含有的属性:href、data-lg-webtj-_address_id、data-lg-webtj-_seq、rel
-->

css selector 反对通过任何属性来抉择元素,语法是用一个方括号 []

/* li 标签含有的属性:id */
[id="quick-entrance"]
/* 加上标签名限度 */
li[id="quick-entrance"]
/* a 标签含有的属性:href、data-lg-webtj-_address_id、data-lg-webtj-_seq、rel */
a[href="https://www.lagou.com/s/subscribe.html"]
a[data-lg-webtj-_address_id="1nny"]
a[data-lg-webtj-_seq="1"]
a[rel="nofollow"]

另外,css selector 依据属性值定位,还反对含糊匹配:

  • 蕴含关系 *=a[href*="lagou.com/s/"]
  • 匹配结尾 ^=a[href^="https://www.lagou"]
  • 匹配结尾 $=a[href$="lagou.com/s/subscribe.html"]

如果一个元素具备多个属性,css selector 还能够同时限度多个属性:

  • a[rel="nofollow"][data-lg-webtj-_seq="1"]

理论利用:

# find_element_by_css_selector 的利用:依据 属性 定位
from selenium import webdriver  # 导入 webdriver 模块
from time import sleep  # 导入 sleep 模块,能够使程序强制休眠

driver = webdriver.Chrome()  # 调用 Chrome 浏览器
driver.maximize_window()  # 窗口最大化
driver.get('https://www.baidu.com/')  # 关上 百度
sleep(2)  # 强制休眠 2 秒
element = driver.find_element_by_css_selector("input[id='kw']")  # 依据 属性 定位元素
# element = driver.find_element_by_css_selector("input[class='s_ipt']")  # 依据 属性 定位元素
# element = driver.find_element_by_css_selector("input[name='wd']")  # 依据 属性 定位元素
element.send_keys("自动化测试")  # 输出内容
sleep(3)  # 强制休眠 3 秒
driver.quit()  # 敞开浏览器

联结应用

css selector 反对抉择语法的联结应用。如上面的 HTML 代码段:

<div id='bottom'>
    <div class='footer1'>
        <span class='copyright'> 版权 </span>
        <span class='date'> 公布日期:2018-03-03</span>
    </div>
    <div class='footer2'>
        <span> 备案号
            <a href="http://www.miitbeian.gov.cn">
                苏 ICP 备 88885574 号
            </a>
        </span>
    </div>        
</div> 
/*
抉择语法联结应用
定位指标:<span class='copyright'> 版权 </span>
*/
/* 第一种办法 标签 +class+ 子元素 */
div.footer1 > span.copyright
/* 第二种办法 属性 + 后辈元素 */
div[id='bottom'] span[class='copyright']
/* 第三种办法 属性 + 后辈元素 */
#bottom .copyright
.footer1 .copyright

依据秩序抉择子节点

父元素的第 n 个子节点

应用 nth-child(n),能够指定抉择 父元素的第几个子节点

留神:

  • 这里的排序,是所有的子元素一起排序,而不是按标签分类后再排序
  • 下标的开始值是 1
父元素的倒数第 n 个子节点

应用 nth-last-child(n),能够倒过去,抉择的是 父元素的倒数第几个子节点

父元素的第几个某类型的子节点

应用 nth-of-type(n),能够指定抉择的元素是 父元素的第几个某类型的子节点

父元素的倒数第几个某类型的子节点

应用 nth-last-of-type(n),能够倒过去,抉择 父元素的倒数第几个某类型的子节点

奇数节点和偶数节点

如果要抉择的是父元素的 偶数节点,应用 nth-child(even)

如果要抉择的是父元素的 奇数节点,应用 nth-child(odd)

如果要抉择的是父元素的 某类型偶数节点,应用 nth-of-type(even)

如果要抉择的是父元素的 某类型奇数节点,应用 nth-of-type(odd)

依据兄弟节点抉择

相邻兄弟节点抉择

应用办法:标签类型 1 + 标签类型 2 ,两者为兄弟标签(同级标签),定位到紧跟 标签类型 1 后的第 1 个 标签类型 2 的元素,如下图所示:

后续所有兄弟节点抉择

应用办法:标签类型 1 ~ 标签类型 2 ,抉择 标签类型 1 后续兄弟节点中所有的 标签类型 2 的元素,如下图所示:

总结

退出移动版