css 定位方式相比 xpath 的优势
- 优势 1:一般情况下定位速度要比 XPATH 快
- 优势 2:语法要比 XPATH 更简洁
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) | 匹配不符合当前选择器的任何元素 |
举例
匹配(去掉#) | locator |
---|
<#div class=”formdiv”> | css=div |
css=div.formdiv | |
<#ul id=”recordlist”> | css=#recordlist |
css=ul#recordlist | |
<#p>Heading | css=div.subdiv p |
css=div.subdiv > ul > p | |
<#div class=”subdiv”> | css=form + div |
<#li>Cat | css=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>Goat | css=li:contains(‘Goa’) |
<#li>Cat | css=li:not(contains(‘Goa’)) |
CSS 和 xpath 对比
目标 | CSS | XPath |
---|
所有元素 | * | //* |
所有的 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 id | div#eleid | //div[@id=’eleid’] |
By class | div.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 定位模糊搜索
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")
driver.find_element_by_xpath("//*[contains(@name,'tj_trhao123')]").click()
driver.find_element_by_xpath("//*[contains(@id,'search-input')]").send_keys(u"xpath 模糊搜索")
driver.find_element_by_xpath("//*[starts-with(@id,'search-in')]").send_keys(u"-- 开头")
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
***
driver.find_element_by_xpath("//*[matchs(text(),'hao123')]").click()
driver.find_element_by_xpath("//*[contains(.,'hao123')]").click()
time.sleep(5)
driver.quit()