实际项目中使用较多的是xpath定位和css定位。XPath是XML文档中查找结点的语法,换句话就是通过元素的路径来查找这个元素。xpath比较强大,而css选择器在性能上更优,运行速度更快,语法上更简洁。
以下分别用两种方法定位百度搜索框:
ID定位
XPATH中的元素id使用以下内容定义:[@id='kw']
,而在CSS中使用:#kw
。
XPATH:find_element_by_xpath("//input[@id='kw']")
CSS: find_element_by_css_selector("input#kw")
CLASS定位
对于class属性,XPATH写法类似id,而CSS中用一个点表示。
XPATH:find_element_by_xpath("//input[@class='s_ipt']")
CSS: find_element_by_css_selector("input.s_ipt")
元素包含某属性
XPATH:find_element_by_xpath("//input[@name]")
CSS: find_element_by_css_selector("input[name]")
属性值
我们可以根据任何属性值定位元素。
XPATH:find_element_by_xpath("//input[@name='wd']") # //input[@id='kw']
CSS: find_element_by_css_selector("input[name='wd']")
多个属性值
我们甚至可以通过多个属性来定位元素。
XPATH:find_element_by_xpath("//input[@name='wd'][@id='kw']") # //input[@name='wd' and @id='kw']
CSS: find_element_by_css_selector("input[name='wd'][id='kw']") # input[name='wd']#kw
直接子元素
XPATH中的直接子元素是使用/
定义的,而在CSS上,它是使用>
定义的。
XPATH:find_element_by_xpath("//form/span/input")
CSS: find_element_by_css_selector("form>span>input")
后代元素
如果一个元素在另一个元素的内部(子元素或者孙元素,是后代都行),则它在XPATH中使用//
定义,而在CSS中仅使用空格定义。
XPATH:find_element_by_xpath("//form//input[@id='kw']") # form的后代元素中标签为input且id=kw的元素
CSS: find_element_by_css_selector("form input#kw")
弟弟元素
页面中位于同一父节点内的下一个相邻元素。XPATH中用/following-sibling::
,css中用+号表示, 这对于表单元素非常有用。
XPATH:find_element_by_xpath("//span[@class='soutu-btn']/following-sibling::input")
CSS: find_element_by_css_selector("span.soutu-btn+input") # 先找到标签为span且class='soutu-btn'的元素,再找它的弟弟元素Input标签
哥哥元素
页面中位于同一父节点内的上一个相邻元素,XPATH中用/preceding-sibling::
(下标从1开始,且是从下往上数,如果没有下标则是最靠近父节点的元素),CSS无法实现。
XPATH:find_element_by_xpath("//a[@id='quickdelete']/preceding-sibling::input")
CSS: 无法实现
祖先元素
页面中位于一个节点的祖先元素,XPATH中用/ancestor::
(下标从1开始,且是从下往上数,如果没有下标则是最上层节点的元素),CSS无法实现。
XPATH:find_element_by_xpath("//a[@id='quickdelete']/ancestor::span/input")
CSS: 无法实现
父节点元素
页面中位于一个节点的上级元素,XPATH用 /..
来表示,CSS无法实现。
XPATH:find_element_by_xpath("//input[@id='kw']/../input") # 这里我们先定位到搜索框,再去定位他的父节点,最后通过父节点的直接子元素方法回来
CSS: 无法实现
下面我们换张图,定位百度右上角那些链接。
text值定位
页面中有text值的元素,XPATH用text()='***'
来表示,CSS无法实现。
XPATH:find_element_by_xpath("//a[text()='hao123']")
CSS: 无法实现
第一个元素
页面中符合条件的第一个元素,XPATH中用[1]
,CSS中用:first-child
。
定位"新闻"
XPATH:find_element_by_xpath("//div[@id='u1']/a[1]")
CSS: find_element_by_css_selector("div#u1 a:first-child")
第二个元素
页面中符合条件的第二个元素,XPATH中用[2]
,CSS中用:nth-child(2)
。
定位"hao123"
XPATH:find_element_by_xpath("//div[@id='u1']/a[2]")
CSS: find_element_by_css_selector("div#u1 a:nth-child(2)")
最后一个元素
页面中符合条件的最后一个元素,XPATH中用last()
,CSS中用:last-child
。
定位"更多产品"
XPATH:find_element_by_xpath("//div[@id='u1']/a[last()]")
CSS: find_element_by_css_selector("div#u1 a:last-child")
模糊匹配
selenium中允许进行部分字符串匹配。xpath中使用starts-with()
、 ends-with()
、 contains()
,css中使用^=
、 $=
、 *=
表示
下面分别定位"hao123"
属性以某字段开头
XPATH: find_element_by_xpath("//a[starts-with(@name,'tj_trhao')]")
CSS: find_element_by_css_selector("a[name^='tj_trhao']")
属性以某字段结尾
XPATH: find_element_by_xpath("//a[ends-with(@name,'trhao123')]")
CSS: find_element_by_css_selector("a[name$='trhao123']")
属性包含某字段
XPATH:find_element_by_xpath("//a[contains(@name,'trhao')]")
CSS: find_element_by_css_selector("a[name*='trhao']")
关于XPATH的其他一些方法:
following
选取文档中当前节点的结束标签之后的节点
preceding
选取文档中当前节点的开始标签之前的节点
/body/div[last()-1]
选取body下倒数第二个div节点
and
且关系
or
或关系
not
否关系
!=
不等
//ul/li[position()>2][position()<5]
位置大于2,小于5的
/body/div[price>35.00]
选取body下price元素值大于35的div节点
//li[text()[normalize-space()='其他']]
去掉前后空格,中间空格留一个,剩下的多余空格全部去掉