XPath介绍
XPath(XML Path Language)是一门解析XML文档的语言,可在XML文档中对元素和属性进行遍历。
因为XML和HTML语法类似,所以,XPath广泛用于解析HTML文档数据,HTML页面由标签构成,这些标签就像家族里的族谱一样,有明确的层级关系,正是基于这种层级关系,XPath语法才能选中所需的数据,在HTML文档中XPath通过元素(即HTML标签)和属性(即HTML标签的属性)进行定位。XPath常用于Selenium自动化测试中的元素定位和数据爬虫定位,使用路径表达式来选取XML和HTML文档中的节点或节点集
XPath语法
XPath语法大致可以分为四大类:层级、属性、函数和其它
1、层级
/ 后面直接跟子节点,在linux系统中很常见,如/html/body/div/div[2]/div[5]/div[1]/div/form/span[1]/input
// 全局查找,可以是任意位置,如//div//input,双斜杠可视为相对路径,单斜杠可视为绝对路径
parent 选取当前节点的父节点
child 选取当前节点的所有子节点
preceding 选取当前节点的开始标签之前的所有节点
following 选取当前节点的结束标签之后的所有节点
ancestor 选取当前节点的所有先辈节点 (父、祖父等)
descendant 选取当前节点的所有后代节点 (子、孙等)
descendant-or-self 选取当前节点的所有后代节点及当前节点本身
. 和在linux系统中一个意思,表示当前目录,即当前节点
.. 同样和在linux系统中一个意思,表示上一级目录,即当前节点的父节点
同级、兄弟节点定位//*/label[text()="业务状态"]/following-sibling::*//input
2、属性
@ 属性访问,选择带有某个属性的节点,如//input[@name],选取带有name属性的input标签;
//input[@*],选取所有带属性的input标签,可以直接通过元素的id、name和class属性定位,如//input[@id="kw"],选取id="kw"属性的input标签;
//input[@class="s_ipt"],选取class="s_ipt"属性的input标签,若id/name/class都没有,可以通过其它属性进行定位,但要确保此属性是不变的,
不能是下次请求时属性就消失或者有变化了,如:class="xh-highlight",高亮属性在选中时才会出现
3、函数
text() 文本定位,常和contains()函数一起使用,//div/a[contains(text(),“学”)]
last() 返回被处理节点的最后一个元素,//div[@id=“s-top-left”]/a[last()]
position() 匹配返回节点的索引位置,//div[@id=“s-top-left”]/a[position()=1]
contains() 匹配一个属性值中包含的字符串,用于模糊定位,比如匹配id属性中包含了“s-t”关键字的元素。//div[contains(@id,“s-t”)]/a[last()]
starts-with() 匹配一个属性值开始位置的关键字,用于模糊定位,//div[starts-with(@id,“s-t”)]/a[last()]
4、其它
=、!=、<、>、<=、>=、or、and 运算符,一目了然,不再做解释
* 通配符,匹配任意字符,如//div/*,选取div标签下的所有标签
| 与或符,双方条件都满足时都显示,否则只显示满足条件的一方,如://input|//title
[] 谓语和索引需要用[]括起来,谓语是用来查找某个特定节点或包含指定值的节点,如://input[position()<2],选择最前面的input标签;//div[@id="s-top-left"]/a[1],选择id="s-top-left"的div标签下的第一个a标签
示例
下面以百度首页为例,在百度页面按F12打开开发工具,在开发工具页面按住Ctrl + F,在搜索框内输入XPath语法即可定位元素,如下三种浏览器页面所示,注意输入框右侧的分数值,1/1、1of1才表示定位到唯一的元素,1of2表示定位到2个,目前选中的是第一个,一般情况下,使用Selenium做自动化时定位元素基本上都是要唯一,在进行数据爬虫时1of10之类的多元素定位使用较多
以下XPath语法都可在百度页面定位到唯一值,此处不再符百度HTML文档
以下XPath语法都可定位到“百度一下”按钮
//*[@id='su'] # 在HTML文档中查找所有id='su'的标签
//input[@id='su'] # 在HTML文档中查找id='su'的input标签
//input[@type='submit'] # 在HTML文档中查找type='submit'的input标签
//input[@value='百度一下'] # 在HTML文档中查找value='百度一下'的input标签
……
以下XPath语法都可定位到百度输入框
//*[@id='kw'] # 在HTML文档中查找所有id='kw'的标签
//input[@type='text'] # 在HTML文档中查找type='text'的input标签
//input[@class='s_ipt'] # 在HTML文档中查找class='s_ipt'的input标签
//input[@name='wd'] # 在HTML文档中查找name='wd'的input标签
//input[@id='kw'] # 在HTML文档中查找id='kw'的input标签
//input[starts-with(@class,'s')] # 在HTML文档中查找class属性值包含“s”的input标签
……
以下XPath语法都可定位到百度首页左上角“学术”链接按钮
//*[@id='s-top-left']/a[7] # 在HTML文档中查找所有id='s-top-left'的标签下的第7个a标签
//div[@id='s-top-left']/a[7] # 在HTML文档中查找id='s-top-left'的div标签下的第7个a标签
//div[@id='s-top-left']/a[position()=7] # 在HTML文档中查找id='s-top-left'的div标签下的索引值等于7的a标签
//div[@id='s-top-left']/a[position()>6] # 在HTML文档中查找id='s-top-left'的div标签下的索引值大于6的a标签
//div[@id='s-top-left']/a[last()] # 在HTML文档中查找id='s-top-left'的div标签下的最后一个a标签
//div[@id='s-top-left']/a[1]/@href # 获取页面中“新闻”的链接地址
//a[contains(text(),'学')] # 在HTML文档中查找文本信息包含“学”的a标签
……
以下XPath语法都可定位到百度首页左上角“新闻”链接按钮
//*[@id='s-top-left']/a[1] # 在HTML文档中查找所有id='s-top-left'的标签下的第1个a标签
//div[@id='s-top-left']/child::a[1] # 在HTML文档中查找id='s-top-left'的div标签下子标签的第1个a标签
//div[@id='s-top-left']/descendant::a[1] # 在HTML文档中查找id='s-top-left'的div标签后代中的第1个a标签
//div[@id='s_top_wrap']/following::a[1] # 在HTML文档中查找id='s_top_wrap'的div标签后的第1个a标签
//div[@class='mnav s-top-more-btn']/preceding::a[7] # 查找class='mnav s-top-more-btn'的div标签之前的第7个a标签
//a[contains(text(),'h')]/parent::*/a[position()=1] # 查找包含h的文本的a标签的父标签下索引值为1的a标签
//a[contains(text(),'h')]/ancestor::*/a[position()<2] # 查找包含h的文本的a标签的先辈标签下索引值小于2的a标签
……
对于如下图所示的情况,所需信息并没有在标签对中
可以使用下面的语法进行定位
//span[@class='pl'][3]/following::text()[1] # 获取class='pl'的第三个span标签后的第1个文本内容
//span[./text()='语言:']/following::text()[1] # 获取当前节点包含文本“语言:”的span标签后的第1个文本内容
还可以下载个Xpath Helper插件,如下图,//p[@class='lh'][position()<5]/a
得到4个结果并在页面高亮显示
以上只是学习XPath语法,了解XPath定位的一种方式
最为简单的方法还是选择元素后右键选择复制XPath,只是对于复杂页面复制出的语法可读性不太好
之后就可以在代码中使用啦,代码中注意引号的使用,内外不能同时使用单引或双引号
find_element_by_xpath("//input[@id='kw']").clear()
find_element_by_xpath('//*[@id="kw"]').send_keys("XPath")
find_element_by_xpath('//*[@id="su"]').click()
find_element(By.XPATH, '//a[@class="toindex"]').click()
————————————————
版权声明:本文为CSDN博主「小白典」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Q0717168/article/details/118819843