1. 程式人生 > >【基於Python的Selenium2自動化測試】02 -Webdriver之元素定位

【基於Python的Selenium2自動化測試】02 -Webdriver之元素定位

文章目錄


說明:

WebDriver屬於Selenium體系中用來操作瀏覽器的一套API,同時,WebDriver也是Python的一個用於實現Web自動化的第三方庫。

首先來看一下百度首頁的Web頁面,如下:
在這裡插入圖片描述

在這張web頁面上,我們看到有 輸入框、按鈕和文字連結,還有圖片、頁面底部的文字等。自動化要做的就是模擬滑鼠和鍵盤來操作這些元素,或單擊,或輸入,或滑鼠懸停等操作。

操作這些頁面元素的前提就是要找到它們,自動化工具不可能像人一樣可以通過肉眼就可以分辨這些元素,並且知道它們是幹什麼用的,那麼自動化工具如何找到它們呢?

接下來我們通過前端工具來看一下這些元素的真實面目。

對於谷歌瀏覽器,我們只需要按 F12 就可以啟用開發者工具檢視頁面元素,如下:
在這裡插入圖片描述
我們可以看到頁面上的元素都是由一行行的程式碼組成的,它們之間是層級關係組織起來的,每個元素有不同的標籤名和屬性值。WebDriver就是通過這些資訊來找到不同的元素的。

WebDriver提供了8種元素定位方法,在Python中,其對應的方法如下:

元素 方法
id name
class name tag name
link text partial link text
xpath css selector
find_element_by_id() find_element_by_name()
find_element_by_class_name() find_element_by_tag_name()
find_element_by_link_text() find_element_by_partial_tag_name()
find_element_by_xpath() find_element_by_css_selector()

下面是百度首頁的前端程式碼(Chrome開發者工具檢視所得)

<!--STATUS OK-->
<html>
   <head></head>
   <body link=”#0000cc”>
		<div data-for="result" id="swfEveryCookieWrap" style="width: 0px; height: 0px; overflow: hidden;">...</div>
		<script></script>
<div id="wrapper" style="display: block;">
			<script>
if(window.bds&&bds.util&&bds.util.setContainerWidth){bds.util.setContainerWidth();}
</script>
<div id=”head”>
	<div class=”head_wrapper”>
		<div class=”s_form”>
			<div class="s_form_wrapper soutu-env-nomac soutu-env-index">
				<div id="lg">
					<img hidefocus="true" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129">
							</div>
							<a href="/" id="result_logo" onmousedown="return c({'fm':'tab','tab':'logo'})">
								<img src="//www.baidu.com/img/baidu_jgylogo3.gif" alt="到百度首頁" title="到百度首頁">
							</a>
							<form id="form" name="f" action="/s" class="fm">
								<input type="hidden" name="ie" value="utf-8">
								<input type="hidden" name="f" value="8">
								<input type="hidden" name="rsv_bp" value="0">
								<input type="hidden" name="rsv_idx" value="1">
								<input type="hidden" name="ch" value="">
								<input type="hidden" name="tn" value="baidu">
								<input type="hidden" name="bar" value="">
								<span class="bg s_ipt_wr quickdelete-wrap"> 
									<span class="soutu-btn"></span>
									<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
									<a href="javascript:;" id="quickdelete" title="清空" class="quickdelete" style="top: 0px; right: 0px; display: none;"></a>
								</span>
								<span class="bg s_btn_wr">
									<input type="submit" id="su" value="百度一下" class="bg s_btn">
								</span>
……
	</body>
<html>

從上面的程式碼我們可以看到

  • 它們都是由標籤組成:
<html></html>
<body></body>
<div></div>
<form></form>
……
  • 標籤有各種屬性
<div id=”head” class=”s_down”>
<from class=”well”>
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">

就像人也會有各種屬性一樣,如身份證(id)、姓名(name)、職業(class)等

  • 標籤對之間可以有文字資料:
<a>新聞</a>
<a>地圖</a>
<a>視訊</a>
<a>貼吧</a>
  • 標籤有層級關係
<html>
	<body>
	</body>
</html>
<div>
	<form>
		<input />
	</form>
</div>

2.1 id定位

HTML規定id屬性在HTML文件中必須是唯一的,這類似於公民的身份證號,具有很強的唯一性。
Webdriver提供的id定位方法就是通過元素的id屬性來查詢元素。

例如:通過id定位百度輸入框與百度搜索按鈕,
在這裡插入圖片描述

用法如下:

find_element_by_id(“kw”)
find_element_by_id(“su”)

說明: find_element_by_id()方法通過id屬性來定位元素。

2.2 name定位

HTML規定name來指定元素的名稱,因此它的作用就像是人的姓名。
name的屬性值在當前頁中可以不唯一

例如:通過name定位百度輸入框,
在這裡插入圖片描述
用法如下:

find_element_by_name(“wd”)

說明: find_element_by_name()方法通過name屬性來定位元素。
注意:由於百度搜索按鈕並沒有提供name屬性,因此就不能通過name屬性來定位它。

2.3 class定位

HTML規定class用來指定元素的類名。
例如:通過class屬性來定位百度輸入框和搜尋按鈕,
在這裡插入圖片描述

用法如下:

find_element_by_class_name(“s_ipt”)
find_element_by_class_name(“bg s_btn”)

說明: find_element_by_class_name()方法通過class屬性來定位元素。

2.4 tag定位

HTML的本質就是通過tag來定義實現不同的功能,每個元素本質上就是一個tag
因為一個tag往往用來定義一類功能,所以通過tag識別某個元素的概率很低。

例如,我們開啟任意一個頁面,檢視前端都會發現有大量的<div>、<input>、<a>tag,所以很難通過tag name去區分不同的元素。

例如:通過tag name去定位百度的輸入框和搜尋按鈕,你會發現它們完全一樣
在這裡插入圖片描述

用法如下:

find_element_by_tag_name(input)

說明: find_element_by_tag_name()方法通過元素的tag name來定位元素。

2.5 link定位

link專門用來定位文字連結。

例如:百度首頁上的幾個文字連結如下
在這裡插入圖片描述

其文字連結的程式碼如下:

<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新聞</a>
<a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a>
<a href="http://map.baidu.com" name="tj_trmap" class="mnav">地圖</a>
<a href="http://v.baidu.com" name="tj_trvideo" class="mnav">視訊</a>
<a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">貼吧</a>
<a href="http://xueshu.baidu.com" name="tj_trxueshu" class="mnav">學術</a>

根據上面的程式碼,我們發現,其實通過name屬性來定位是一個更好的選擇。不過這裡為了演示link定位的使用,用法如下:

find_element_by_link_text(“新聞”)
find_element_by_link_text(“hao123”)
find_element_by_link_text(“地圖”)
find_element_by_link_text(“視訊”)
find_element_by_link_text(“貼吧”)
find_element_by_link_text(“學術”)

說明: find_element_by_link_text()方法通過元素標籤對之間的文字資訊來定位元素。

2.6 partial link定位

partial link定位是對link定位的一種補充,有些文字連結較長,這個時候可以取文字連結的一部分進行定位,只要這部分資訊可以唯一的標識這個連結即可。
例如:

<a class="mnav" name=”tj_long” href=”#”>一個很長的文字連結</a>

通過partial link定位如下:

find_element_by_partial_link_text(“一個很長的”)
find_element_by_partial_link_text(“文字連結”)

說明: find_element_by_partial_link_text()方法通過元素標籤對之間的部分文字資訊來定位元素。

2.7 XPath定位

XPath是一種在XML文件中定位元素的語言。因為HTML可以看做XML的一種實現,所以Selenium使用者可以使用XPath在web應用中來定位元素。

  • 方法1:絕對路徑定位
    參考前面的前端展示的程式碼,我們可以通過下面的方法來定位到百度輸入框和百度搜索按鈕
find_element_by_xpath(/html/body/div/div/div/div/div/form/span/input)
find_element_by_xpath(/html/body/div/div/div/div/div/form/span[2]/input)

說明: find_element_by_xpath()方法使用XPath語言來定位元素。

XPath主要用標籤名的層級關係來定位元素的絕對路徑,最外層的是html語言。然後在body文字內,一級一級往下查詢,如果一個層級下有多個相同的標籤名,那麼就按照上下順序確定是第幾個,例如span[2]表示當前層級下的第2個span標籤。

  • 方法2:利用元素屬性定位

同樣以百度輸入框和百度搜索按鈕為例,用法如下:

find_element_by_xpath(//input[@id=’kw’])
find_element_by_xpath(//input[@id=’su’])

說明:
//表示當前頁面下某個目錄,input表示定位元素的標籤名,[@id=’kw’]表示這個元素的id屬性值等於kw

下面通過idnameclass屬性值來定位,方法如下:

find_element_by_xpath(//input[@id=’kw’])
find_element_by_xpath(//input[@name=’wd’])
find_element_by_xpath(//input[@class=’s_ipt’])
find_element_by_xpath(//input[@class=’bg s_btn’])

說明: 如果不指定標籤名,則也可以使用星號(*)來代替。
使用XPath不侷限於idnameclass這三個屬性值,元素的任意屬性值都可以使用,只要它能唯一的標識這個元素。

例如:

find_element_by_xpath(//input[@maxlength=255])
find_element_by_xpath(//input[@autocomplete=’off’])
find_element_by_xpath(//input[@type=’submit’])
  • 方法3:層級與屬性結合

如果一個元素本身沒有可以唯一標識這個元素的屬性值,那麼我們可以找其上一級元素,如果它的上一級元素有可以唯一標識的屬性值,也可以拿來使用。

還是以定位百度輸入框和百度搜索按鈕為例,用法如下:

find_element_by_xpath(//span [@class=’bg s_ipt_wr’]/input)
find_element_by_xpath(//span [@class=’bg s_btn_wr’]/input)

說明: span [@class=’bg s_ipt_wr’]通過class元素定位到父元素,後面的/input就是父元素下面的子元素。如果父元素沒有可利用的屬性值,那麼可以繼續向上找“爺爺”元素,如:

find_element_by_xpath(//form [@id=’form’]/span/input)
find_element_by_xpath(//form [@id=’form’]/span[2]/input)
  • 方法4:使用邏輯運算子
    如果一個屬性不能唯一區分一個元素,我們可以使用邏輯運算子連線多個屬性來定位元素。
…….
		<input id=”kw” class=”su” name=”ie”>
		<input id=”kw” class=”aa” name=”ie”>
		<input id=”bb” class=”su” name=”ie”>
…….

如上面的三行元素,假設我們現在要定位第一行的元素,如果使用id將會與第二行元素重名,如果使用class將會與第三行元素重名,而如果同時使用idclass就會唯一的標識第一行元素,這個時候就可以通過邏輯運算子“and”來連線這兩個條件,用法如下:

find_element_by_xpath(//input[@id=’kw’ and class=’su’])

2.8 CSS定位

CSS(Cascading Style Sheets)是一種語言,它用來描述HTML和XML文件的表現。CSS使用選擇器來為頁面元素繫結屬性。

CSS選擇器的常見語法如下:

選擇器 例子 描述
.class .intro class選擇器,選擇class=“intro”的所有元素
#id #firstname id選擇器,選擇id=“firstname”的所有元素
* * 選擇所有元素
element P 元素所有 <p> 元素
element > element div > input 選擇父元素為<div>的所有<input>元素
element+ element div + input 選擇同一級中緊接在<div>元素之後的所有<input>元素
[attribute=value] [target=_blank] 選擇target=“_blank”的所有元素

下面同樣以百度輸入框和百度搜索按鈕為例介紹CSS定位的用法

……
     <span class="bg s_ipt_wr quickdelete-wrap"> 
			<span class="soutu-btn"></span>
			<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
			<a href="javascript:;" id="quickdelete" title="清空" class="quickdelete" style="top: 0px; right: 0px; display: none;"></a>
		</span>
		<span class="bg s_btn_wr">
			<input type="submit" id="su" value="百度一下" class="bg s_btn">
		</span>
……

1)通過class屬性定位
find_element_by_css_selector(“.s_ipt”) //選擇class=“s_ipt”的元素,即百度輸入框
find_element_by_css_selector(“.bg s_btn”) //選擇class=“bg s_btn”的元素,即百度搜索按鈕

2)通過id屬性定位
find_element_by_css_selector(“#kw”)//選擇id=“kw”的元素,即百度輸入框
find_element_by_css_selector(“#su”) //選擇id=“su”的元素,即百度搜索按鈕

3)