Ui自動化的基礎是頁面元素定位。
在python Selenium語句中定位方式主要有By.Id()、By.Name()、By.Xpath()、By.tagName()、By.className()、By.CssSelector()、By.linkText()、By.partialLinkText()這8類。由於現在的頁面元素不一定有Id、Name、tagName和className的屬性,所以最常用的是By.Xpath()、By.CssSelector(),如果是定位頁面上的超文本鏈接,用By.linkText()。
Xpath定位方法簡單直接且唯一,功能全面。但是頁面層級一旦變化,需要調整代碼,可維護性不好。
css定位方法代碼簡潔,性能好,但是語法復雜,某些瀏覽器不支持CSS定位方式。
谷歌、火狐瀏覽器的console控制台自帶驗證Xpath和css的工具,可以幫助我們定位和驗證頁面元素。
Xpath定位語法
以百度輸入框的絕對路徑“/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input “為例講解。
表達語句 |
描述 |
舉例 |
解釋 |
nodename |
選取此節點的所有同級節點 |
/html/body/div |
div節點下所有子節點 |
/ |
根節點選取 |
|
用於絕對路徑選擇 |
// |
不考慮位置 |
//body/div |
匹配到符合條件即可 |
. |
當前節點 |
/html/body/div/. |
與上面/html/body/div效果一致 |
.. |
當前節點的父節點 |
/html/body/div/.. |
匹配到body |
@ |
選取屬性 |
//input[@id='kw'] |
’@‘后面輸入屬性條件 |
[n] |
選取元素下第N個子元素 |
/html/body/div[2] |
body下第2個div子元素 |
[last()] |
選取元素下倒數第一個子元素 |
/html/body/div[last()] |
body下倒數第一個div子元素 |
* |
匹配任何節點 |
/html/body/* |
body下所有子節點 |
preceding-sibling::nodename[N] |
匹配前N位的類型為nodename的同級節點 |
//form/preceding-sibling::div[1] |
與from同級的前面一位的兄弟div節點 |
following-sibling::nodename[N] |
匹配后N位的類型為nodename的同級節點 |
//form/following-sibling::div[1] |
與from同級的后面一位的兄弟div節點 |
child::nodename[N] |
匹配上級節點的子節點類型為nodename的第N個節點 |
//form/span[1]/child::input[1] |
Form下第一個span節點的第一個input子節點 |
parent::nodename[N] |
匹配上級節點的nodename類型的第N個節點 |
//form/parent::span[1] |
Form元素的父級節點中第一個span元素 |
xpath中支持運算符計算,但是很少用到。
運算符 |
描述 |
實例 |
返回值 |
| |
計算兩個節點集 |
//book | //cd |
返回所有擁有 book 和 cd 元素的節點集 |
+ |
加法 |
6 + 4 |
10 |
- |
減法 |
6月4日 |
2 |
* |
乘法 |
6 * 4 |
24 |
div |
除法 |
8 div 4 |
2 |
= |
等於 |
price=9.80 |
滿足條件為ture,不滿足為false |
!= |
不等於 |
price!=9.80 |
滿足條件為ture,不滿足為false |
< |
小於 |
price<9.80 |
滿足條件為ture,不滿足為false |
<= |
小於或等於 |
price<=9.80 |
滿足條件為ture,不滿足為false |
> |
大於 |
price>9.80 |
滿足條件為ture,不滿足為false |
>= |
大於或等於 |
price>=9.80 |
滿足條件為ture,不滿足為false |
or |
或 |
/html//input[@name='wd'or @class='s_ipt'] |
滿足條件為ture,不滿足為false |
and |
與 |
/html//input[@name='wd'and @class='s_ipt'] |
滿足條件為ture,不滿足為false |
mod |
計算除法的余數 |
5 mod 2 |
1 |
xpath方法元素定位注意點:
1、屬性內容在python代碼中可以用雙引號包裹,也可以用單引號包裹,但是在瀏覽器中驗證的時候只能用單引號包裹。建議在代碼中也使用單引號包裹,語句外層用雙引號包裹,如下,text()='首頁'中文字字段用單引號包裹,完整定位語句用雙引號包裹。
WebDriverWait(browser, 15, 0.5).until(EC.presence_of_all_elements_located((By.XPATH, "//ul/div[1]/a/li/span[text()='首頁']")))
在瀏覽器console中驗證為“ $x("//input[@id='kw']") ”。注意全英文。
2、非屬性內容,不需要加“@”,例如代碼
定位語句為:“/html/body//span[2][text()='按圖片搜索']”。因為”按圖片搜索“不是span元素的屬性。
3、盡量避免使用絕對路徑來定位,而是使用屬性id、name、class、type等定位。如果子集節點沒有唯一屬性,可以找父級節點、祖父節點等。例如:百度頁面輸入框絕對路徑為:“/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input”,可以替換為“//form[@id='form']/span[1]/input”。這樣減輕了代碼量,同時減少元素層級變化帶來的代碼維護量。
4、xpath還提供contains()方法,實現模糊定位。contains()需要輸入2個屬性,一個是元素名稱,一個是元素內容,中間以逗號隔開。例如:“//form[@id='form']/span[1]/input”可以替換為“//*[contains(@id,'form')]/span[1]/input”;再例如“/html/body//span[2][text()='按圖片搜索']”可以修改為“/html/body//span[contains(text(),'按圖片搜索')]”。
5、child::與parent::如果加上*,則表示查找所有子節點或者父節點。
6、查找子節點中“//form/span[1]/child::input[1]”與“//form/span[1]/input[1]”效果一致。
7、查找父節點中,“//form/parent::*/parent::*”與“//form/../..”效果一致。
css定位語法
基本語法如下:css語法與與Xpath有諸多類似的地方。
表達語句 |
描述 |
舉例 |
解釋 |
nodename |
元素選擇,同時選擇多個元素可用逗號分隔 |
input |
選擇所有input元素 |
# |
id選擇器符號 |
#head |
選擇所有id=head的元素 |
>或者空格 |
上下級元素分隔符為>或者空格 |
html>body>div>div>div>div>div>form>span>input |
用於絕對路徑選擇 |
. |
class選擇器 |
form.fm>span>input.s_ipt |
選擇所有class=s_ipt的元素 |
* |
所有元素 |
form.fm>span>* |
符合span查找的當前等級下所有的下級節點 |
[表達式] |
元素內容篩選。以字符^指明從字符串的開始匹配,以字符以字符*指明在需要進行模糊查詢,以字符$指明在字符串的結尾匹配 |
input[name='wd'] |
查找name='wd'的input元素 |
:first-child |
第一個子節點 |
div#u1 a:first-child |
id為u1的div元素的第1個子a元素 |
:nth-child(N) |
第N個子節點 |
div#u1 a:nth-child(3) |
id為u1的div元素的第3個子a元素 |
:last-child |
最后一個子節點 |
div#u1 a:last-child |
id為u1的div元素的最后一個子a元素 |
css方法定位元素注意點:
1、css的絕對路徑不能省略。
2、css定位沒有有能夠獲取父節點的辦法,也不能獲取當前元素的所有子節點。
頁面元素定位語句編寫和調試
火狐瀏覽器和谷歌瀏覽器都很好的支持元素的查找、定位、調試。以谷歌瀏覽器為例:
1、F12打開開發者工具,進入到Elements查看器,查看頁面元素。
2、選擇被定位元素。
點擊Elements查看器上方定位按鈕。
選擇后鼠標停留在需要定位的元素內容上,元素的代碼部分就會突出顯示。
例如我們定位到百度頁面的輸入框內容如下:
3、編輯定位語句。
如果使用xpath語句定位元素,選中語句,右鍵--copy--copy Full Xpath 點擊。xpath層級就被復制到剪貼板,如下:“/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input”經過語法處理,可以為“//form[@id='form']/span[1]/input”。
如果使用css語句定位,根據語句id=‘kw‘,編輯定位語句為"#kw"。
4、定位語句調試。
定位語句編輯好之后往往需要驗證是否正確,是否唯一。
切換到Console控制台驗證定位語句。
驗證定位語句需要用Console中的屬性,如下:
- $():簡單理解就是 document.querySelector,可用於驗證css定位語句,但是只能在回車后才能看到匹配結果,不建議使用。
- $$():簡單理解就是 document.querySelectorAll ,可用於驗證css定位語句。編輯時可顯示匹配結果,建議使用。
- $x():Xpath選擇器,可用於驗證xpath定位語句。注意x必須小寫。編輯時可顯示匹配結果,很方便,建議使用。
- $_ // 是上一個表達式的值,等同於鍵盤的“向上”快捷鍵。連續使用上一個值時,建議用鍵盤快捷鍵。
定位語句需要以雙引號包裹。以xpath方式驗證如下:定位到唯一的正確元素后,就可以在python代碼中使用定位語句了。
5、使用定位語句
獲取的定位語句在python中可以直接使用。如下:
browser.find_element_by_xpath(“ //form[@id='form']/span[1]/input “).send_keys('UI自動化')