前面咱们学习了根据 id、class属性、tag名选择元素。css
若是咱们要选择的元素没有id、class 属性,或者有些咱们不想选择的元素也有相同的id、class属性值,怎么办呢?html
这时候咱们一般能够经过CSS selector语法选择元素。web
HTML中常常要为某些元素指定显示效果,好比前景文字颜色是红色,背景颜色是黑色,字体是微软雅黑等。chrome
那么CSS必须告诉浏览器:要选择哪些元素,来使用这样的显示风格。编程
好比,下图中,为何灰太狼红太狼小灰灰会显示为红色呢?浏览器
html代码:工具
<head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .wolf{ color: red; } </style> </head> <body> <div class="raise"><span>喜羊羊</span></div> <div class="raise"><span>美羊羊</span></div> <div class="raise"><span>暖羊羊</span></div> <div class="wolf"><span>灰太狼</span></div> <div class="wolf"><span>红太狼</span></div> <div class="wolf"><span>小灰灰</span></div> </body>
由于蓝色框里面用css 样式,指定了class值为wolf的元素,要显示为红色。学习
其中蓝色框里面的.wolf就是CSS Selector,或者说CSS选择器。字体
CSS Selector语法就是用来选择元素的。网站
既然CSS Selector语法天生就是浏览器用来选择元素的,selenium天然就可使用它用在自动化中,去选择要操做的元素了。
只要CSS Selector的语法是正确的,Selenium就能够选择到该元素。
CSS Selector很是强大,学习Selenium Web自动化必定要学习CSS Selector。
经过CSS Selector选择单个元素的方法是:
find_element_by_css_selector(CSS Selector参数)
选择全部元素的方法是:
find_elements_by_css_selector(CSS Selector参数)
CSS Selector选择元素很是灵活强大,你们能够从下面的例子看出来。
CSS Selector一样能够根据tag名、id 属性和class属性来选择元素。
根据tag名选择元素的CSS Selector语法很是简单,直接写上tag名便可。
好比要选择全部的tag名为div的元素,就能够是这样:
elements = wd.find_elements_by_css_selector('div')
等价于
elements = wd.find_elements_by_tag_name('div')
根据id属性选择元素的语法是在id号前面加上一个井号:#id值
下面这样的元素:
<input type="text" id='searchtext' />
就可使用#searchtext这样的CSS Selector来选择它。
好比,咱们想在id为searchtext的输入框中输入文本 你好,完整的Python代码以下:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') element = wd.find_element_by_css_selector('#searchtext') element.send_keys('你好')
根据class属性 选择元素的语法是在 class 值 前面加上一个点:.class值
要选择全部class属性值为wolf的元素狼除了这样写:
elements = wd.find_elements_by_class_name('wolf')
还能够这样写:
elements = wd.find_elements_by_css_selector('.wolf')
由于是选择全部符合条件的,因此用find_elements而不是find_element。
HTML中,元素内部能够包含其余元素,好比下面的 HTML片断:
<div id='container'> <div id='layer1'> <div id='inner11'> <span>内层11</span> </div> <div id='inner12'> <span>内层12</span> </div> </div> <div id='layer2'> <div id='inner21'> <span>内层21</span> </div> </div> </div>
下面的一段话有些绕口,请你们细心阅读:
id为container的div元素包含了id为layer1和layer2的两个div元素。
这种包含是直接包含,中间没有其余的层次的元素了。 因此id为layer1和layer2的两个div元素是id为container的div元素的直接子元素。
而id为layer1的div元素又包含了id为inner11和inner12的两个div元素。其中没有其余层次的元素,全部这种包含关系也是直接子元素关系。
id为layer2的div元素又包含了id为inner21这个div元素。这种包含关系也是直接子元素关系。
而对于id为container的div元素来讲,id为inner十一、inner十二、inner22的元素和两个span类型的元素都不是它的直接子元素,由于中间隔了几层。
虽然不是直接子元素,可是它们仍是在container的内部,能够称之为它的后代元素。
后代元素也包括了直接子元素,好比id为layer1和layer2的两个div元素,也能够说是id为container的div元素的直接子元素,同时也是后代子元素。
若是元素2是元素1的直接子元素,CSS Selector选择子元素的语法是这样的:
元素1 > 元素2
中间用一个大于号(咱们能够理解为箭头号)
注意,最终选择的元素是元素2,而且要求这个元素2是元素1的直接子元素。
也支持更多层级的选择,好比:
元素1 > 元素2 > 元素3 > 元素4
就是选择元素1里面的子元素元素2里面的子元素元素3里面的子元素元素4,最终选择的元素是元素4。
若是元素2是元素1的后代元素,CSS Selector选择后代元素的语法是这样的:
元素1 元素2
中间是一个或者多个空格隔开
最终选择的元素是元素2,而且要求这个元素2是元素1的后代元素。
也支持更多层级的选择,好比:
元素1 元素2 元素3 元素4
最终选择的元素是元素4.
id、class 都是web元素的属性,由于它们是很经常使用的属性,因此css选择器专门提供了根据 id、class 选择的语法。
那么其余的属性呢?
好比
<a href="https://www.cnblogs.com/liuhui0308/">爱编程的小灰灰</a>
里面根据href选择,能够用css选择器吗?
固然能够!
css选择器支持经过任何属性来选择元素,语法是用一个方括号[]。
好比要选择上面的a元素,就可使用
[href="https://www.cnblogs.com/liuhui0308/"]
这个表达式的意思是,选择属性href值为https://www.cnblogs.com/liuhui0308/的元素。
完整代码以下:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') # 根据属性选择元素 element = wd.find_element_by_css_selector('[href="https://www.cnblogs.com/liuhui0308/"]') # 打印出元素对应的html print(element.get_attribute('outerHTML'))
固然,前面能够加上标签名的限制,好比div[class='SKnet'],表示选择全部标签名为div,且class属性值为SKnet的元素。
属性值用单引号,双引号均可以。
根据属性选择,还能够不指定属性值,好比[href],表示选择全部具备属性名为href的元素,无论它们的值是什么。
CSS还能够选择属性值包含某个字符串的元素。
好比,要选择a节点,里面的href属性包含了miitbeian字符串,就能够这样写:
a[href*="miitbeian"]
还能够选择属性值以某个字符串开头的元素
好比,要选择a节点,里面的href属性以http开头,就能够这样写:
a[href^="http"]
还能够选择 属性值以某个字符串结尾的元素
好比,要选择a节点,里面的href属性以gov.cn 结尾,就能够这样写:
a[href$="gov.cn"]
若是一个元素具备多个属性:
<div class="misc" ctype="gun">沙漠之鹰</div>
CSS选择器能够指定选择的元素要同时具备多个属性的限制,像这样
div[class=misc][ctype=gun]
那么咱们怎么验证CSS Selector的语法是否正确选择了咱们要选择的元素呢?
固然能够像下面这样,写出Python代码,运行看看,可否操做成功。
element = wd.find_element_by_css_selector('#searchtext') element.input('输入的文本')
若是成功,说明选择元素的语法是正确的。
可是这样作太麻烦了,浪费了不少的时间。
当咱们进行自动化开发的时候,有大量选择元素的语句,都要这样一个个的验证,就很是浪费时间。
因为CSS Selector是浏览器直接支持的,能够在浏览器开发者工具栏中验证。
咱们能够打开一个网站,按F12打开开发者工具栏。
若是咱们要验证下面的表达式
#bottom > .footer2 a
可否选中这个元素
<a href="https://www.cnblogs.com/liuhui0308/">爱编程的小灰灰</a>
html代码:
<div id='bottom'> <div class='footer1'> <span class='copyright'>版权</span> <span class='date'>发布日期:2019-11-26</span> </div> <div class='footer2'> <span>主页 <a href="https://www.cnblogs.com/liuhui0308/">爱编程的小灰灰</a> </span> </div> </div>
能够这样作:
点击Elements标签后,同时按Ctrl键和F键,就会出现下图箭头处的搜索框:
咱们能够在里面输入任何CSS Selector表达式,若是能选择到元素,右边的的红色方框里面就会显示出相似1 of 1这样的内容。
of后面的数字表示这样的表达式总共选择到几个元素
of前面的数字表示当前黄色高亮显示的是其中第几个元素
上图中的1 of 1 就是指:CSS选择语法 #bottom > .footer2 a在当前网页上共选择到一个元素,没钱高亮显示的是第1个。
若是咱们输入span就会发现,能够选择到3个元素