1. CSS 选择器
前面我们学习了根据 id,class 属性, tag 名选择元素.
如果我们要选择的元素没有 id,class 属性, 或者有些我们不想选择的元素也有相同的 id,class 属性值, 怎么办呢?
这时候我们通常可以通过 CSS selector 语法选择元素.
1.1 CSS Selector 语法选择元素原理
html 中经常要为某些元素指定显示效果, 比如前景文字颜色是红色, 背景颜色是黑色, 字体是微软雅黑等.
那么 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 选择元素非常灵活强大, 大家可以从下面的例子看出来.
1.2 根据 tag 名, id,class 选择元素
CSS Selector 同样可以根据 tag 名, id 属性和 class 属性来选择元素.
1.2.1 根据 tag 名选择元素
根据 tag 名选择元素的 CSS Selector 语法非常简单, 直接写上 tag 名即可.
比如要选择所有的 tag 名为 div 的元素, 就可以是这样:
elements = wd.find_elements_by_css_selector('div')
等价于
elements = wd.find_elements_by_tag_name('div')
1.2.2 根据 id 属性选择元素
根据 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('你好')
1.2.3 根据 class 属性选择元素
根据 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.
1.3 选择子元素和后代元素
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 为 inner11,inner12,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.
1.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]
1.5 验证 CSS Selector
那么我们怎么验证 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 个元素
来源: http://www.bubuko.com/infodetail-3304523.html