学xpath的意义在于部分场景用css选择web元素很麻烦,而xpath 却比较方便
另外 Xpath 还有其他领域会使用到,比如 爬虫框架 Scrapy, 手机App框架 Appium。
文章目录
path 语法中,整个HTML文档根节点用’/‘表示,如果我们想选择的是根节点下面的html节点,则可以在搜索框输入 /html
如果输入下面的表达式:
/html/body/div
这个表达式表示选择html下面的body下面的div元素
/ 有点像CSS中的 > ,表示直接子节点关系
绝对路径
从根节点开始的,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式,就是某元素的 绝对路径
例如上面的xpath表达式 /html/body/div
等价于CSS表达式html>body>div
自动化程序要使用Xpath来选择web元素,应该调用 WebDriver对象的方法 find_element_by_xpath 或者 find_elements_by_xpath:
elements=driver.find_elements(By.XPATH,"/html/body/div")
相对路径
xpath前面加 // , 表示从当前节点往下寻找所有的后代元素,不管它在什么位置。
所以xpath表达式,应该这样写: //div
‘//’ 符号也可以继续加在后面,比如,要选择 所有的 div 元素里面的 所有的 p 元素 ,不管div 在什么位置,也不管p元素在div下面的什么位置,则可以这样写 //div//p
对应的自动化程序如下:
elements=driver.find_elements(By.XPATH,"//div//p")
如果使用CSS选择器,对应代码如下:
elements=driver.find_elements(By.CSS_SELECTOR,"div p")
如果要选择所有div中的 直接子节点 p,xpath应该这么写:
//div/p
如果使用CSS选择器,则为 div>p
🐗通配符
xpath中如果要选择所有div节点的所有直接子节点,可以使用表达式:
//div/*
"*"是一个通配符,对应任意节点名的元素,等价于CSS选择器的
div>*
示例:
elements = driver.find_elements(By.XPATH,"//div/*")for element in elements:print(element.get_attribute('outerHTML'))#打印html信息
根据属性选择
Xpath 可以根据属性来选择元素。
根据属性来选择元素 是通过 这种格式来的 [@属性名=‘属性值’]
🌋根据id属性选择
选择id为west的元素:
//*[@id='west']
属性名前要有@,属性值一定要用引号
🎠根据class属性选择
选择所有 select 元素中 class为 single_choice 的元素,可以这样
//select[@class='single_choice']
如果一个元素class有多个,比如
<pid="beijing"class='capital huge-city'>
北京
</p>
对应的xpath就是:
//p[@class="capital huge-city"]
不能只写一个属性
🚣根据其他属性
同样的道理,我们也可以利用其它的属性选择
比如选择 具有multiple属性的所有页面元素 ,可以这样:
//*[multiple]
🦊属性值包含字符串
- 要选择style属性值包含color字符串的页面元素
//*[contains(@style,'color')]
- 要选择style属性值以color字符串开头的页面元素
//*[starts-with(@style,'color')]
目前浏览器不支持以某字符串结尾的页面元素的方法
按次序选择
xpath也可以根据次序选择元素。 语法比css更简洁,直接在方括号中使用数字表示次序
🌏某类型第几个子元素
选择p类型的第二个子元素:
//p[2]
选取父元素为div的p类型的第2个子元素
//div/p[2]
📫第几个子元素
选取父元素为div的所有元素的第二个子元素
//div/*[2]
👒某类型倒数第几个元素
选取p类型倒数第一个子元素
//p[last()]
选取p类型倒数第2个子元素
//p[last()-1]
选取父元素为div中p类型倒数第三个子元素
//div/p[last()-2]
🍹范围选择
xpath还可以选择子元素的次序范围
选取option类型第1到2个子元素
//option[position()<=2]
或者
option[position()<3]
选择class属性为multi_choice的前三个子元素
//*[@class='multi_choice']/*[position()<=3]
选取class属性为multi_choice的后三个子元素
//*[@class='multi_choice']/*[position()>=last()-2]
last() 本身代表最后一个元素
last()-1 本身代表倒数第2个元素
last()-2 本身代表倒数第3个元素
组选择,父节点,兄弟节点
👾组选择
xpath中组选择使用竖线隔开多个表达式
所有的option元素和所有的h4元素:
//option|//h4
等同于CSS选择器:
option,h4
再比如,要选所有的 class 为 single_choice 和 class 为 multi_choice 的元素:
//*[@class='single_choice']|//*[@class='multi_choice']
等同与CSS选择器
.single_choice,.multi_choice
🍭选择父节点
xpath可以选择父节点,某个元素的父节点用“/. .”表示
选择id为china的节点的父节点:
//*[@id='china']/..
当某个元素没有特征可以直接选择,但是它有子节点有特征, 就可以采用这种方法,先选择子节点,再指定父节点。
还可以继续找上层父节点:
//*[@id='china']/../../..
🚟兄弟节点选择
CSS中选择某个节点的后续兄弟节点,用波浪线~
xpath选择后续兄弟节点,用following-sibling::
比如,要选择class为single_choice的元素的所有后续兄弟节点:
//*[@class='single_choice']/following-sibling::*
xpath还可以选择前面的兄弟节点,
语法: prceding-sibling::
比如,要选择 class 为 single_choice 的元素的所有前面的兄弟节点
//*[@class='single_choice']/preceding-sibling::*
CSS选择器目前还不能选择器前面的兄弟节点
selenium注意点
要在某个元素内部使用xpath,需要在xpath表达式最前面加个点
例如:
# 先寻找id是china的元素
china = wd.find_element(By.ID,'china')# 再选择该元素内部的p元素
elements = china.find_elements(By.XPATH,'.//p')# 打印结果for element in elements:print('----------------')print(element.get_attribute('outerHTML'))
版权归原作者 鸡蛋灌饼侠 所有, 如有侵权,请联系我们删除。