css表达式
前言
参考教程:Python + Selenium Web自动化 2024版 - 自动化测试 爬虫_哔哩哔哩_bilibili
上期文章: Selenium-Java版(操作元素)-CSDN博客
根据 tag名、id、class 选择元素
tag名
List<WebElement> elements = wd.findElements(By.cssSelector("div"));
等价于
List<WebElement> elements = wd.findElements(By.tagName("div"));
#id
WebElement element = wd.findElement(By.cssSelector("#searchtext"));
等价于
WebElement element = wd.findElement(By.id("searchtext"));
.class
List<WebElement> elements = wd.findElements(By.cssSelector(".animal"));
等价于
List<WebElement> elements = wd.findElements(By.className("animal"));
选择子元素和后代元素
定义
在这段HTML代码中:
id为
layer1
和layer2
的两个元素是id为container
的元素的直接子元素id为
inner11
和inner12
的两个元素是id为layer1
的元素的直接子元素id为
inner21的
div元素是id为layer2
的div元素的直接子元素
id为
inner11、id为
inner12和id为
inner21
的元素以及两个span元素是
id为container
的div元素的后代元素
语法
如果元素2
是元素1
的直接子元素,需要选择元素2
元素1 > 元素2
可以套娃,选择元素4
元素1 > 元素2 > 元素3 > 元素4
如果元素2
是元素1
的后代元素,需要选择元素2,中间用空格
元素1 元素2
也可以套娃,选择元素4
元素1 元素2 元素3 元素4
大于号和空格还可以混用
示例
List<WebElement> elements = wd.findElements(By.cssSelector("#container>#layer1 span"));
根据属性选择
除了id、class这种web元素的常用属性,css 选择器支持通过任何属性来选择元素,语法是用一个方括号 []
。
运行代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import java.time.Duration;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 创建WebDriver对象
WebDriver wd = new EdgeDriver();
wd.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
// 打开网页
wd.get("https://www.byhy.net/cdn2/files/selenium/sample1.html");
// 根据属性选择元素
WebElement element = wd.findElement(By.cssSelector("[href='http://www.miitbeian.gov.cn']"));
// 打印出元素对应的html
System.out.println(element.getAttribute("outerHTML"));
// 创建Scanner对象等待用户输入
Scanner scanner = new Scanner(System.in);
System.out.println("等待回车键结束程序");
scanner.next();
// 关闭浏览器
wd.quit();
}
}
输出结果
前面可以加上标签名的限制,中间不能有空格,否则代表的是上级的标签名
WebElement element = wd.findElement(By.cssSelector("a[href='http://www.miitbeian.gov.cn']"));
表示选择所有标签名为a,href属性值为http://www.miitbeian.gov.cn的元素。
也可以不指定属性值,直接[href]
,表示选择所有具有属性名为href 的元素,不管属性值。
还可以选择属性值包含
某个字符串的元素
如:选择a节点里面的href属性包含了miitbeian字符串的元素
a[href*='miitbeian']
还可以选择属性值以某个字符串开头
的元素
a[href^='http']
还可以选择属性值以某个字符串结尾
的元素
a[href$='gov.cn']
如果一个元素有多个属性,可以指定同时具有多个属性的限制, 如:
div[class='misc'][ctype='gun']
验证CSS Selector
打开开发者工具栏后,按ctrl+f可以打开搜索框
有高亮显示元素,说明CSS语法正确
组选择
选择所有 id 为 t1 里面的span和p元素,使用逗号
#t1 > span , #t1 > p
不能这样写,因为这样是选择所有id为t1里面的span
和所有的p元素
#t1 > span,p
注意:组选择结果列表中的排序,不是组表达式的次序,而是元素在HTML文档中的出现的次序。
按次序选择子节点
父元素的第n个子节点
<body>
<div id='t1'>
<h3> 唐诗 </h3>
<span>李白</span>
<p>静夜思</p>
<span>杜甫</span>
<p>春夜喜雨</p>
</div>
<div id='t2'>
<h3> 宋词 </h3>
<span>苏轼</span>
<p>赤壁怀古</p>
<p>明月几时有</p>
<p>江城子·乙卯正月二十日夜记梦</p>
<p>蝶恋花·春景</p>
<span>辛弃疾</span>
<p>京口北固亭怀古</p>
<p>青玉案·元夕</p>
<p>西江月·夜行黄沙道中</p>
</div>
</body>
选择唐诗和宋词的第一个作者,也就是说选择的是第2个子元素,并且是span类型
span:nth-child(2)
如果不加节点类型限制,写成这样
:nth-child(2)
就是选择所有位置为第2个的所有元素,不管是什么类型,这里就会把id='t2'整个元素选进去。
如果这样写,只选到李白
#t1>:nth-child(2)
父元素的倒数第n个子节点
选择的是父元素的倒数第一个子节点,并且是p元素
p:nth-last-child(1)
父元素的第几个某类型的子节点
同样选择李白和苏轼
span:nth-of-type(1)
如果选择杜甫和辛弃疾
span:nth-of-type(2)
父元素的倒数第几个某类型的子节点
选择静夜思和青玉案·元夕
p:nth-last-of-type(2)
奇数节点和偶数节点
选择的是父元素的偶数节点
p:nth-child(even)
选择的是父元素的奇数节点
p:nth-child(odd)
选择的是父元素的某类型偶数节点
p:nth-of-type(even)
选择的是父元素的某类型奇数节点
p:nth-of-type(odd)
兄弟节点选择
选择李白和苏轼,就是选择h3后面紧跟着的兄弟节点
span
h3 + span
选择所有作者,就是选择h3后面所有的兄弟节点
span
h3 ~ span
也可以在前面加父元素的tag名或者属性,更精确查找