CSS Selector定位元素用法
通过CSS Selector 选择单个元素的方法是
find_element(By.CSS_SELECTOR, CSS Selector参数)
选择所有元素的方法是
find_elements(By.CSS_SELECTOR, CSS Selector参数)
CSS Selector 同样可以根据tag名、id 属性和 class属性 来 选择元素,
根据tag名 选择元素的 CSS Selector 语法非常简单,直接写上tag名即可
Tag方式定位
比如 要选择 所有的tag名为div的元素,就可以是这样
elements = wd.find_elements(By.CSS_SELECTOR, 'div')
等价于
elements = wd.find_elements(By.TAG_NAME, 'div')
id方式定位
有下面这样的元素:
就可以使用 #searchtext 这样的 CSS Selector 来选择它。
比如,我们想在 id 为 searchtext 的输入框中输入文本 你好 ,完整的Python代码如下
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Chrome()
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')
element = wd.find_element(By.CSS_SELECTOR, '#searchtext')
element.send_keys('你好')
Class方式定位
根据class属性 选择元素的语法是在 class 值 前面加上一个点: .class值
要选择所有 class 属性值为 animal的元素。除了这样写
elements = wd.find_elements(By.CLASS_NAME, 'animal')
还可以这样写
elements = wd.find_elements(By.CSS_SELECTOR, '.animal')
选择 子元素 和 后代元素
HTML中,元素 内部可以 包含其他元素, 比如 下面的 HTML片段
内层11
内层12
内层21
下面的一段话有些绕口, 请 大家细心 阅读:
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
根据属性选择
id、class 都是web元素的 `属性` ,因为它们是很常用的属性,所以css选择器专门提供了根据 id、class 选择的语法。
那么其他的属性呢?
比如
里面根据href选择,可以用css 选择器吗?
当然可以!
css 选择器支持通过任何属性来选择元素,语法是用一个方括号 [] 。
比如要选择上面的a元素,就可以使用 [href="http://www.miitbeian.gov.cn"] 。
这个表达式的意思是,选择 属性href值为 http://www.miitbeian.gov.cn 的元素。
完整代码如下
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Chrome()
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')
# 根据属性选择元素
element = wd.find_element(By.CSS_SELECTOR, '[href="http://www.miitbeian.gov.cn"]')
# 打印出元素对应的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"]
如果一个元素具有多个属性
沙漠之鹰
CSS 选择器可以指定 选择的元素要 同时具有多个属性的限制,像这样 div[class=misc][ctype=gun]
验证 CSS Selector
那么我们怎么验证 CSS Selector 的语法是否正确选择了我们要选择的元素呢?
当然可以像下面这样,写出Python代码,运行看看,能否操作成功
element = wd.find_element(By.CSS_SELECTOR, '#searchtext')
element.input('输入的文本')
如果成功,说明选择元素的语法是正确的。
但是这样做的问题就是:太麻烦了。
当我们进行自动化开发的时候,有大量选择元素的语句,都要这样一个个的验证,就非常耗时间。
由于CSS Selector 是浏览器直接支持的,可以在浏览器 开发者工具栏 中验证。
比如我们使用Chrome浏览器打开 https://cdn2.byhy.net/files/selenium/sample1.html
按F12打开 开发者工具栏
如果我们要验证 下面的表达式
#bottom > .footer2 a
能否选中 这个元素
可以这样做:
点击Elements 标签后, 同时按 Ctrl 键 和 F 键, 就会出现下图箭头处的搜索框
我们可以在里面输入任何 CSS Selector 表达式 ,如果能选择到元素, 右边的的红色方框里面就会显示出类似 2 of 3 这样的内容。
of 后面的数字表示这样的表达式 总共选择到几个元素
of 前面的数字表示当前黄色高亮显示的是 其中第几个元素
上图中的 1 of 1 就是指 :CSS 选择语法 #bottom >.footer2 a
在当前网页上共选择到 1 个元素, 目前高亮显示的是第1个。
如果我们输入 .plant 就会发现,可以选择到3个元素