Python 使用 Selenium,xpath 和 css 对比,以及 xpath 模糊定位,适用于动态 id、class 变化的属性


css 定位方式相比 xpath 的优势

  • 优势 1:一般情况下定位速度要比 XPATH 快
  • 优势 2:语法要比 XPATH 更简洁

CSS

用法含义
*通用元素选择器,匹配任何元素
E标签选择器,匹配所有使用 E 标签的元素
.infoclass 选择器,匹配所有 class 属性中包含 info 的元素
#footerid 选择器,匹配所有 id 属性等于 footer 的元素
E,F多元素选择器,同时匹配所有 E 元素或 F 元素,E 和 F 之间用逗号分隔
E F后代元素选择器,匹配所有属于 E 元素后代的 F 元素,E 和 F 之间用空格分隔
E > F子元素选择器,匹配所有 E 元素的子元素 F
E + F毗邻元素选择器,匹配紧随 E 元素之后的同级元素 F (只匹配第一个)
E ~ F同级元素选择器,匹配所有在 E 元素之后的同级 F 元素
E[att=’val’]属性 att 的值为 val 的 E 元素 (区分大小写)
E[att^=’val’]属性 att 的值以 val 开头的 E 元素 (区分大小写)
E[att$=’val’]属性 att 的值以 val 结尾的 E 元素 (区分大小写)
E[att*=’val’]属性 att 的值包含 val 的 E 元素 (区分大小写)
E[att1=’v1’][att2*=’v2’]属性 att1 的值为 v1,att2 的值包含 v2 (区分大小写)
E:contains(‘xxxx’)内容中包含 xxxx 的 E 元素
E:not(s)匹配不符合当前选择器的任何元素

举例

匹配(去掉#)locator
<#div class=”formdiv”>css=div
css=div.formdiv
<#ul id=”recordlist”>css=#recordlist
css=ul#recordlist
<#p>Headingcss=div.subdiv p
css=div.subdiv > ul > p
<#div class=”subdiv”>css=form + div
<#li>Catcss=p + li
css=p ~ li
<#input name=”username”>css=form > input[name=username]
<#input value=”SYS123456” name=”vid” type=”hidden”>css=input[name$=id][value^=sys]
<#input name=”username” type=”text”>css=input:not([name$=id][value^=sys])
<#li>Goatcss=li:contains(‘Goa’)
<#li>Catcss=li:not(contains(‘Goa’))

CSS 和 xpath 对比

目标CSSXPath
所有元素*//*
所有的 P 元素p//p
所有的 p 元素的子元素p > *//p/*
根据 ID 获取元素#foo//*[@id=’foo’]
根据 Class 获取元素.foo//_[contains(@class,’foo’)]
//_[@class=’foo’]
拥有某个属性的元素*[title]//*[@title]
所有 P 元素的第一个子元素p > *:first-child//p/*[0]
所有拥有子元素 a 的 P 元素无法实现//p[a]
下一个兄弟元素p + *//p/following-sibling::*[0]
标签div//div
By iddiv#eleid//div[@id=’eleid’]
By classdiv.eleclass//div[contains(@class,’eleclass’)]
//div[@class=’eleclass’]
By 属性//div[@title=’Move mouse here’]div[title=Move mousehere]

div[title^=Move]
div[title$=here]
div[title=mouse] |
| 定位子元素 | div#eleid >_
div#eleid >h1 | //div[@id=’eleid’]/_
//div/h1 |
| 定位后代元素 | div h1 | //div[@id=’eleid’]//h1 |
| By index | li:nth(5) | //li[6] |
| By content | a:contains(Issue1164) | //a[contains(.,’Issue 1164’)] |
| 根据子元素回溯定位父元素 | li{a:contains(Issue1244)}
ul{a:contains(Issue1244)} | //li[a[contains(.,’Issue 1244’)]]
//\
[./a[contains(.,’Issue1244’)]]
//ul[.//a[contains(.,’Issue1244’)]] |
| 根据邻近元素定位 | css=li:contains(Issue1244) + li
css=ul{a:contains(Issue1244)} ~ ul | //li[preceding-sibling::li[contains(.,’Issue1244’)]]
//ul[preceding-sibling::ul[.//a[contains(.,’Issue1244’)]]] |

xpath 定位模糊搜索

#!/usr/bin/env python
#coding: utf-8

from selenium import webdriver
import time

"""

xpath 模糊匹配,类似find_by_partial_link

contains(属性名,字符串)  包含,
starts-with(属性名,字符串)  开始,
ends-with(属性名,字符串)  结束,
matchs(属性名,字符串)  匹配

"""

driver= webdriver.Firefox()
driver.get("http://www.baidu.com")

# xpath 模糊匹配
driver.find_element_by_xpath("//*[contains(@name,'tj_trhao123')]").click()

# xpath 模糊匹配某个属性
driver.find_element_by_xpath("//*[contains(@id,'search-input')]").send_keys(u"xpath 模糊搜索")

# xpath 模糊匹配以什么开头
driver.find_element_by_xpath("//*[starts-with(@id,'search-in')]").send_keys(u"-- 开头")

# xpath 模糊匹配以什么结束
driver.find_element_by_xpath("//*[ends-with(@id,'search-input')]").send_keys(u"-- 结束")

***
contains(a, b) 如果a中含有字符串b,则返回true,否则返回false

starts-with(a, b) 如果a是以字符串b开头,返回true,否则返回false

ends-with(a, b) 如果a是以字符串b结尾,返回true,否则返回false
***

# xpath 模糊匹配支持正则表达式
driver.find_element_by_xpath("//*[matchs(text(),'hao123')]").click()
driver.find_element_by_xpath("//*[contains(.,'hao123')]").click()

time.sleep(5)
driver.quit()

文章作者:   hongwei
版权声明:   本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hongwei !
评论
  目录