一節(jié),我們介紹一下頁(yè)面元素定位的八種方式和如何通過(guò)火狐和谷歌瀏覽器獲取元素定位信息.
html頁(yè)面是有一個(gè)個(gè)的標(biāo)簽組成的,我們定位元素其實(shí)就是定位這些標(biāo)簽。
首先來(lái)看一下有哪兒幾種定位方式:
id
name
class name
tag name
link text
partial link text
xpath
css selector
一共八種定位方式,其實(shí)常用的定位方式也有:xpath、css selector,至少要熟練掌握一種......
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_id("wd1").send_keys("python")
id定位
代碼的意思就是定位id為:“wd1”的輸入框并輸入了“python”這個(gè)數(shù)據(jù)
<input id="wd1" class="search_ipt search_inp_border j_search_input tb_header_search_input" name="kw1" value="" autocomplete="off" size="42" tabindex="1" maxlength="100" x-webkit-grammar="builtin:search" x-webkit-speech="true" type="text">
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_name("kw1").send_keys("python")
我們通過(guò)觀察這個(gè)<input>標(biāo)簽的屬性,通過(guò)name也可以成功定位這個(gè)元素
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_class_name("search_ipt.search_inp_border.j_search_input.tb_header_search_input").send_keys("python")
結(jié)果我們發(fā)現(xiàn)系統(tǒng)報(bào)錯(cuò)了,由于這個(gè)輸入框的class中有四個(gè)class,
所以當(dāng)我們同點(diǎn)來(lái)分割時(shí),報(bào)錯(cuò):Unable to locate element:;當(dāng)我們用空格分割時(shí),報(bào)錯(cuò): Compound class names not permitted
而當(dāng)我們用其中一個(gè)class時(shí),比如:search_ipt
這時(shí)我們才可以成功的定位元素(一般不建議用這個(gè)class name來(lái)定位)
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_tag_name("input").send_keys("python")
我們直接定位這個(gè)元素的標(biāo)簽名,可以成功定位,但是由于實(shí)際中tag name有很多相同的標(biāo)簽,可能會(huì)在運(yùn)行時(shí)定位不準(zhǔn)確,所以不建議使用這個(gè)
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_link_text("地圖").click()
然后我們通過(guò)鏈接的名字找到元素,并進(jìn)行click()點(diǎn)擊操作,進(jìn)入到了地圖頁(yè)
第6種:Partial link text定位
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_partial_link_text("地").click()
同樣的,我們通過(guò)鏈接的部分文字信息來(lái)定位到這個(gè)元素,依舊可以成功定位
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_xpath(".//*[@id='wd1']").send_keys("python")
xpath定位
xpath是比較常用的定位,由于定位比較準(zhǔn)確,一般是百發(fā)百中,但是缺點(diǎn)是絕對(duì)路徑的xpath根據(jù)元素標(biāo)簽的相對(duì)位置來(lái)定位,如果頁(yè)面的UI元素有所改動(dòng),結(jié)構(gòu)路徑變化的話,也會(huì)導(dǎo)致我們無(wú)法定位元素,不過(guò)這是針對(duì)我們用firepath自動(dòng)獲取時(shí)的定位,我們完全可以根據(jù)層級(jí)關(guān)系和元素屬性自己來(lái)寫(xiě)xpath路徑,這樣的話,即使其他路徑結(jié)構(gòu)變化,對(duì)于xpath定位的準(zhǔn)確度還有一定的保障
比如:
1.我們把xpath的父級(jí)路徑添加上
//form/input[@id='wd1']
2.我們還可以對(duì)所查找元素標(biāo)簽里的屬性進(jìn)行組合
//form/input[@id='wd1' and @name='kw1']
3.我們對(duì)文本進(jìn)行匹配
driver.find_element_by_xpath("//*[contains(text(),'網(wǎng)頁(yè)')]").click()
可以看出xpath簡(jiǎn)直是神器啊,有沒(méi)有,可以通過(guò)標(biāo)簽的各種屬性來(lái)定位,等于說(shuō)是包含了class name、name、id、link_text這些定位的方法。
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_css_selector("#wd1").send_keys("python")
通過(guò)css selector 定位
其實(shí)這個(gè)css selector定位的強(qiáng)悍和xpath不相上下,也非常之強(qiáng)大,比如在css selector里:
我用class來(lái)定位:driver.find_element_by_css_selector(".search_ipt")
用id來(lái)定位:driver.find_element_by_css_selector("#wd1")
用標(biāo)簽名來(lái)定位(tag name):driver.find_element_by_css_selector("input")
用父子關(guān)系來(lái)定位:driver.find_element_by_css_selector("form>input")
用標(biāo)簽和屬性來(lái)定位:driver.find_element_by_css_selector("input[id='wd1']")
以及綜合上邊的超級(jí)組合查詢:driver.find_element_by_css_selector("form.clearfix>input[id='wd1']") #代表著class為clearfix的父級(jí)標(biāo)簽和自己id屬性為wd1的input標(biāo)簽.
這些就是定位元素的方法,很常用也非常重要,值得收藏!
ebDriver API提供了內(nèi)置方法來(lái)查找基于不同屬性的WebElement,例如ID,Name,Class,XPath,CSS Selectors,鏈接Text等。下面我們就針對(duì)這些方法進(jìn)行元素查找定位。
打開(kāi)Chrome瀏覽器,按F12出現(xiàn)開(kāi)發(fā)者工具選項(xiàng),選擇Elements,優(yōu)先選擇Chrome的原因就是因?yàn)闉g覽器比較好用。
1. 鼠標(biāo)點(diǎn)擊下圖彈框中左上角的箭頭,再點(diǎn)擊頁(yè)面上要定位的元素
2. 對(duì)應(yīng)的html頁(yè)面上會(huì)顯示對(duì)應(yīng)的數(shù)據(jù),并顯示灰色背景
3. 按Ctrl+F顯示出來(lái)搜索框,此處手寫(xiě)元素標(biāo)簽定位
如果你手寫(xiě)元素技能還有待提高的話,可以使用輔助工具來(lái)幫助你,Chrome有一個(gè)神器插件,可代替你手寫(xiě)元素的困擾
ChpoPath插件下載地址:
https://pan.baidu.com/s/1FCoSQHC1YdBBpETF71Ldfw ; 99tk
ID定位
driver.find_element_by_id("kw").send_keys('你好')
NAME定位
driver.find_element_by_name("wd").send_keys('name')
CLASS_NAME定位
driver.find_element_by_class_name("s_ipt").send_keys('class_name')
TAG_NAME定位
這個(gè)是行不通的,因?yàn)橹貜?fù)的標(biāo)簽太多了,無(wú)法定位準(zhǔn)確
from selenium import webdriver
from selenium.webdriver.common.by import By
driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')
try:
driver.find_element_by_tag_name("input").send_keys('tag——name')
print('找到了')
except Exception as e:
print(f'么找到{e}')
我們使用tag_name定位,加了異常捕獲,運(yùn)行結(jié)果如下:
F:\virtualEnvironment\venv\Scripts\python.exe F:/git/AuomationTest/AuomationTestProject/webTestAuomation/element_localization.py
么找到Message: element not interactable
(Session info: chrome=89.0.4389.72)
Process finished with exit code 0
實(shí)踐檢驗(yàn)了使用tag_name來(lái)定位是不靠譜的。
文本定位,link_text只針對(duì)含a標(biāo)簽的,不含a標(biāo)簽的使用,會(huì)拋錯(cuò)。
driver.find_element_by_link_text("新聞").click()
部分文本定位,partial_link_text也是只針對(duì)含a標(biāo)簽的使用,元素的部分文本內(nèi)容定位,不含a標(biāo)簽的使用,會(huì)拋錯(cuò)
driver.find_element_by_partial_link_text("吃喝").click()
萬(wàn)能元素定位,也就是xpath和css定位,css定位后的代碼運(yùn)行起來(lái)的速度相對(duì)來(lái)說(shuō)比xpath代碼運(yùn)行起來(lái)要快很多。
XPATH用法:
driver.find_element_by_xpath("xpath表達(dá)式")
xpath表達(dá)式有絕對(duì)路徑和相對(duì)路徑,通常我們都是使用相對(duì)路徑
1. 絕對(duì)路徑:/html/body/div[3]/div[1]/div[1]/div[1]/ul/li[9]/a
2. 相對(duì)路徑://*[text()="吃喝玩樂(lè)"]
我們不推薦絕對(duì)路徑,因?yàn)榍岸舜a稍微更改就會(huì)影響到定位,推薦使用相對(duì)路徑
xpath 基本語(yǔ)法 | 注釋信息 |
/ | 絕對(duì)定位,如果是選擇當(dāng)前p標(biāo)簽下的子級(jí)的話,可以使用 |
// | 相對(duì)定位,當(dāng)前p標(biāo)簽下的所有節(jié)點(diǎn),不考慮它們的位置 |
@ | 選取屬性,//*[@id="xxx"],//*[@class="xxx"] |
* | 通配符,匹配所有 //* |
@* | 通配符,匹配所有屬性 //input[@*="xxx"] |
//a[@class="header-title"]
//ul[@class="api-main"][1]/li/a[@class="list-con"]
盡量能不使用下標(biāo)就不要使用下標(biāo)定位,前端稍微修改代碼也會(huì)影響頗大
//ul[@class="api-main"]/li/a[contains(@class, "list-con")]
當(dāng)然模糊定位還有一些表達(dá)式:
//*[contains(text(), 文本元素屬性)] | 獲取含文本信息的元素 |
//*[contains(@id, 元素屬性)] | id也可以是class、name |
//*[starts-with(@id, 元素屬性)] | 匹配什么開(kāi)頭 |
//*[ends-with(@id, 元素屬性)] | 匹配什么結(jié)尾 |
//*[matchs(text(), 文本元素屬性)] | 正則匹配含文本的元素 |
//*[text()="吃喝玩樂(lè)"]
//ul[@class="api-main"]//*[@class="list-con" and text()="金融科技"]
//ul[@class="api-main"]//*[text()="交通地理"]/parent::li//following-sibling::li//a
CSS用法:
driver.find_element_by_css_selector("css表達(dá)式")
.api-main-list
#password-o
[class="api-main"]
[id="s-top-left"]>[target="_blank"]
a[href^="https"]
a[href$="com"]
a[href*="baidu"]
[target~="_blank"]
.api-main:first-child:父級(jí)元素下第一個(gè)元素
.api-main:last-child:父級(jí)元素下最后一個(gè)元素
.api-main:only-child:父級(jí)元素下唯一一個(gè)子元素
.api-main:nth-child(下標(biāo)):父級(jí)元素下第幾個(gè)元素
關(guān)于css的元素定位,后面實(shí)操后再給補(bǔ)上,以上總結(jié)或許能幫助到你,或許幫助不到你,但還是希望能幫助到你,如有疑問(wèn)、歧義,評(píng)論區(qū)留言會(huì)及時(shí)修正發(fā)布,謝謝
未完,待續(xù)...
一直都在努力,希望您也是!
.id定位
HTML規(guī)定id屬性在HTML文檔中必須是唯一的。
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_id("kw")
2.name定位
HTML規(guī)定name屬性指定元素名稱,在當(dāng)前頁(yè)面可以不唯一。
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_name("wd")
3.class定位
HTML規(guī)定class指定元素類(lèi)名。
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_class_name("s_ipt")
4.tag定位
HTML本質(zhì)是通過(guò)tag來(lái)定義實(shí)現(xiàn)不同的功能,每個(gè)元素本質(zhì)是一個(gè)tag。因tag用來(lái)定義一類(lèi)功能,所以通過(guò)tag識(shí)別某個(gè)元素概率很低。
find_element_by_tag_name("input")
find_element_by_tag_name("div")
find_element_by_tag_name("a")
5.link定位
專(zhuān)門(mén)用來(lái)定位文本鏈接。如:
find_element_by_link_text("新聞")
find_element_by_link_text("hao123")
find_element_by_link_text("地圖")
6.partial link定位
是對(duì)link定位的補(bǔ)充,有些鏈接很長(zhǎng),我們可以通過(guò)這個(gè)定位取文本鏈接的一部分。
如:
<a class="aaa" name="bbb" href="#">你好啊,我有一條很長(zhǎng)名稱的文本鏈接</a>
find_element_by_partial_link_text("你好啊")
find_element_by_partial_link_text("很長(zhǎng)名稱")
find_element_by_partial_link_text("文本鏈接")
7.XPath定位
XPath是一種在XML文檔中定位元素的語(yǔ)言。HTML可看作XML的一種實(shí)現(xiàn)。
7.1絕對(duì)路徑定位
黏貼:/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input
find_element_by_xpath("/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input")
7.2元素屬性定位
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_xpath("//input[@id='kw']")
//表示當(dāng)前頁(yè)面某個(gè)目錄下
input表示定位元素的標(biāo)簽名
[@id='kw']表示這個(gè)元素的id屬性值等于kw
---還可以通過(guò)name和class屬性來(lái)定位,其他任意屬性都可以使用。
find_element_by_xpath("//input[@name='wd']")
find_element_by_xpath("//input[@class='s_ipt']")
find_element_by_xpath("//*[@name='wd']")
注:不想指定標(biāo)簽名,可以用*號(hào)代替。
7.3層級(jí)與屬性結(jié)合定位
如果一個(gè)元素沒(méi)有唯一標(biāo)識(shí)的屬性值,可以找上一級(jí)元素可以唯一標(biāo)識(shí)的屬性值使用。
假設(shè)輸入框沒(méi)有唯一標(biāo)識(shí)的屬性值,我們可以查找它上一級(jí)屬性。
find_element_by_xpath("//span[@id='s_kw_wrap']/input")
find_element_by_xpath("//span[@class='bg s_ipt_wr new-pmd quickdelete-wrap']/input")
或者再往上級(jí)找:
find_element_by_xpath("//form[@id='form']/span/input")
或者找第二個(gè)span的input(百度一下按鈕):
find_element_by_xpath("//form[@id='form']/span[2]/input")
7.4使用邏輯運(yùn)算符
......
<input id="kw" class="su" name="ie">
<input id="kw" class="aa" name="ie">
<input id="bb" class="su" name="ie">
........
如上代碼通過(guò)id或class屬性去定位元素都會(huì)存在重復(fù)。
如果一個(gè)屬性不能唯一區(qū)分一個(gè)元素,我們可以使用邏輯運(yùn)算符“and”來(lái)連接兩個(gè)條件去定位元素。
find_element_by_xpath("//input[@id='kw' and class='su']/span/input")
8.CSS定位
CSS(Cascading Style Sheets)是一種語(yǔ)言,用來(lái)描述HTML和XML文檔的表現(xiàn)。CSS使用選擇器來(lái)為頁(yè)面元素綁定屬性。
8.1通過(guò)class屬性定位
.號(hào)表示通過(guò)class屬性來(lái)定位元素
find_element_by_css_selector(".s_ipt")
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。