selenium中的CSS定位
CSS是一种语言,它被用来描述HTML和XML文档的表现。CSS使用选择器来为页面元素绑定属性。这些选择器可以被selenium用作另外的定位策略。
CSS选择器的常见语法:
语法 | 说明 |
---|---|
* | 通用元素选择器,匹配任何元素 |
E | 标签选择器,匹配所有使用 E 标签的元素 |
.info class | 选择器,匹配所有 class 属性中包含 info 的元素 |
#footer | id 选择器,匹配所有 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) | 匹配不符合当前选择器的任何元元素 |
代码例子:
<div class="formdiv">
<form name="fnfn">
<input name="username" type="text"></input>
<input name="password" type="text"></input>
<input name="continue" type="button"></input>
<input name="cancel" type="button"></input>
<input value="SYS123456" name="vid" type="text">
<input value="ks10cf6d6" name="cid" type="text">
</form>
<div class="subdiv">
<ul id="recordlist">
<p>Heading</p>
<li>Cat</li>
<li>Dog</li>
<li>Car</li>
<li>Goat</li>
</ul>
</div>
</div>
通过CSS语法进行匹配的实例结果:
locator | 匹配 |
---|---|
css=div css=div.formdiv | <div class="formdiv"> |
css=#recordlist css=ul#recordlist | <ul id="recordlist"> |
css=div.subdiv p css=div.subdiv > ul > p | <p>Heading</p> |
css=form + div | <div class="subdiv"> |
css=p + li css=p ~ li | 二者定位到的都是 <li>Cat</li> ,但是 storeCssCount 的时候,前者得到 1,后者得到 4 |
css=form > input [name=username] | <input name="username"> |
css=input[name$=id] [value^=SYS] | <input value="SYS123456" name="vid" type="hidden"> |
css=input:not([name$=id] [value^=SYS]) | <input name="username" type="text"></input> |
css=li:contains(‘Goa’) | <li>Goat</li> |
css=li:not(contains(‘Goa’)) | <li>Cat</li> |
CSS中的结构性定位:
结构性定位就是根据元素的父子、同级中位置来定位,css3标准中有定义一些结构性定位伪类如
nth-of-type,nth-child,但是使用起来语法很不好理解,这里就不做介绍了。
语法 | 说明 |
---|---|
E:nth(n) ;E:eq(n) | 在其父元素中的 E 子元素集合中排在第 n+1 个的 E 元素 (第一个 n=0) |
E:first | 在其父元素中的 E 子元素集合中排在第 1 个的 E 元素 |
E:last | 在其父元素中的 E 子元素集合中排在最后 1 个的 E 元素 |
E:even | 在其父元素中的 E 子元素集合中排在偶数位的 E 元素 (0,2,4…) |
E:odd | 在其父元素中的 E 子元素集合中排在奇数的 E 元素 (1,3,5…) |
E:lt(n) | 在其父元素中的 E 子元素集合中排在 n 位之前的 E 元素 (n=2,则匹配 0,1) |
E:gt(n) | 在其父元素中的 E 子元素集合中排在 n 位之后的 E 元素 (n=2,在匹配 3,4) |
E:only-child | 父元素的唯一一个子元素且标签为 E |
E:empty | 不包含任何子元素的 E 元素,注意,文本节点也被看作子元素 |
例如以下代码:
<div class="subdiv">
<ul id="recordlist">
<p>Heading</p>
<li>Cat</li>
<li>Dog</li>
<li>Car</li>
<li>Goat</li>
</ul>
</div>
匹配示例:
locator | 匹配 |
---|---|
css=ul > li:nth(0) | <li>Cat</li> |
css=ul > *:nth(0) css=ul > :nth(0) | <p>Heading</p> |
css=ul > li:first | <li>Cat</li> |
css=ul > :first | <p>Heading</p> |
css=ul > *:last css=ul > li:last | <li>Goat</li> |
css=ul > li:even | Cat, Car |
css=ul > li:odd | Dog, Goat |
css=ul > :even | <p>Heading</p> |
css=ul > p:odd | [error] not found |
css=ul > li:lt(2) | <li>Cat</li> |
css=ul > li:gt(2) | <li>Goat</li> |
css=ul > li:only-child css=ul > :only-child css=ul > *:only-child | [error] not found (ul 没有 only-child) |
css=div.subdiv > :only-child | <ul id="recordlist"> |
XPath和CSS的类似定位功能比较(可能会有偏差)
定位方式 | XPath | CSS |
---|---|---|
标签 | //div | div |
By id | //div[@id=‘eleid’] | div#eleid |
By class | //div[@class=‘eleclass’] //div[contains(@class,‘eleclass’)] | div.eleclass |
By 属性 | //div[@title=‘Move mouse here’] | div[title= Move mouse here] div[title^=Move] div[title$=here] div[title*=mouse] |
定位子元素 | //div[@id=‘eleid’]/* //div/h1 | div#eleid >* div#eleid >h1 |
定位后代元素 | //div[@id=‘eleid’]//h1 | div h1 |
By index | //li[6] | li:nth(5) |
By content | //a[contains(.,‘Issue 1164’)] | a:contains(Issue 1164) |
通过对比,我们可以看到,CSS 定位语法比 XPath 更为简洁,定位方式更多灵活多样;不过对 CSS 理解起来要比 XPath 较难;但不管是从性能还是定位更复杂的元素上,CSS 优于 XPath.