【python+selenium的web自動化】- 8種元素定位方式詳解


如果想從頭學起selenium,可以去看看這個系列的文章哦!

https://www.cnblogs.com/miki-peng/category/1942527.html

前言

​ 我們在做WEB自動化時,最根本的就是操作頁面上的各種元素,而操作的基礎便是元素的定位,只有准確地定位到唯一元素才能進行后續的自動化控制,下面將對各種元素定位方式進行總結歸納。

​ 說明:以下操作統一使用百度首頁<www.baidu.com>進行示例,鼠標右鍵然后點擊檢查(或按f12)可以查看具體的前端代碼。

單一屬性定位

​ 6種單一屬性定位 : id,name,class name,tag name,link,partial_link

2種多樣式定位:css、xpath(強烈推薦)

通過元素的id

# 通過id(id唯一)
ele = driver.find_element_by_id("kw")    # 類 WebElement - 屬性、方法
print(ele.get_attribute('class'))   # 獲取該id的class屬性值
ele.send_keys("selenium")   # 發送內容

​ 在前端頁面中,id是指頁面勻速的的屬性名id值,元素的id值在當前整個HTML頁面中是唯一的,因此可以通過id屬性來唯一定位一個元素,是首選的元素定位方式,但不是每個元素都有id屬性。此外,也有動態變化的id值,即每次進入頁面該元素的id值都不一樣,一般是由一串英文+數字組成的字符串,這種情況下就不要使用id去定位元素了(因為下一次很有可能就找不到它了)。

通過元素的name

# 通過name
driver.find_element_by_name("wd")   # 不一定唯一  # elements

​ 元素的name屬性,但name不一定是唯一的,就像大家的身份證號是唯一的,但是名字會有重復。driver.find_element_by_name只返回第一個匹配到的元素,如果想返回所有匹配到該name的元素,則使用driver.find_elements_by_name,區別就是element帶不帶s。這里特別說明一下,find_elements不管找到多少個,都會返回 一個list(找不到則返回空列表),列表當中的每一個元素就是一個 WebElement。

通過元素的class

# 通過class_name
driver.find_element_by_class_name('mnav c-font-normal c-color-t')   # 不一定唯一,只返回匹配到的第一個元素
driver.find_elements_by_class_name('mnav c-font-normal c-color-t')	# 返回元素列表,按照dom樹從上往下

​ 元素的class屬性,在前端,class一般是用來元素進行分組的,並對這一級元素設置相同的樣式,因此會存在多個元素會共用一個class,不一定是唯一值。與name一樣,elements時返回匹配到的元素列表。

通過元素的標簽名

# 通過tag_name
driver.find_element_by_tag_name('span')   # 不唯一   # elements

​ tag就是元素的標簽標識,不一定是唯一值,elements時返回匹配到的元素列表。

通過元素的超鏈接文本

# 通過link_text
driver.find_element_by_link_text('hao123')	   # 不是唯一   # elements

​ 精確匹配鏈接的文本值,不一定是唯一值,elements時返回匹配到的元素列表。

通過元素的部分超鏈接文本

# 通過partial_link_text
driver.find_element_by_partial_link_text('hao')	   # 不是唯一   # elements

​ 模糊匹配鏈接的文本值,elements時返回匹配到的元素列表。

XPTH定位

​ 以上介紹的6中定位方式,都是針對元素的單一特征來定位元素,但在實際應用中,一般都需要組合以上各種情況來定位一個元素。那么xpath和css定位就可以實現各種組合,基本可以覆蓋所有的元素定位。

​ xpath是一門在xml文檔中查找信息的語言,因為html與xml比較相似,用得比較廣泛,所以xpath也可以用於在html對元素進行定位。它是將整個html看成一個樹形結構,html為根節點,頁面當中節點與其他節點可以有祖先、父輩、兄弟、這樣的關系,類似一個族譜。

​ selenium提供的xpath定位的方法名:find_element_by_xpath(xpath表達式),表達式語法如下:

表達式 說明
/ 絕對定位,從根節點選取
// 相對定位,選擇匹配的節點
. 選擇當前節點
.. 選擇當前節點的父節點
@ 選擇屬性,如:@class="class值",@id="id值",屬性放在中括號[]中
* 通配符,匹配所有
@* 通配符,匹配所有屬性,如:@*="test"
  • 絕對定位(不建議) : /單斜杠開頭,嚴格按照層級、同級元素的位置,只要位置改變就無法定位,如:/html/body/div[2]/[form]/div[1]/input
  • 相對定位://雙斜杠開頭 ,在參照物之下只要符合條件的元素存在即可,表達式://標簽名[@屬性名=值] ,用*表示要匹配所有標簽 ,如://*[@id="kw"] 匹配所有標簽
  • 下標定位(不建議):路徑下相同標簽的下標,如://*[@id="th"]/a[2],意思是該路徑下第二個a標簽
  • 邏輯運算:表達式中可以使用and 、or 描述元素的多個屬性,表達式://標簽名[@屬性名=值 and @屬性名=值]
  • 層級定位:靠本身特性無法唯一定位的時候,使用層級去定位,如://div[@id="u1"]//a[@name="tj_login"]。/(單斜杠)表示在前一個元素的直系下, //(雙斜杠)表示在前個元素之下的所有范圍內
  • 文本定位: 通過標簽內的文本內容,表達式: //標簽名[text()="文本"]
  • 包含(部分屬性):標簽的部分屬性,表達式://標簽名[contains(@屬性名 , "部分屬性值")] ,如: //a[contains(@href,"Cource/homework")],部分文本也可以,//a[contains(text(), "部分文本")]
  • 軸定位:一般用於表格樣式的數據列,需要通過組合來進行定位,軸運算名稱為以下6種,使用語法:/軸名稱::節點名稱[@屬性=值],例: //div//table//td/preceding::td,只要后面接的是軸定位要用/(單斜杠)。
    • 👉ancestor:祖先節點,父
    • 👉parent:父節點
    • 👉preceding:當前元素節點標簽之前的所有節點(html頁面先后順序)
    • 👉preceding-sibling:當前元素節點標簽之前的所有兄弟節點
    • 👉following:當前元素節點標簽之后的所有節點(html頁面先后順序)
    • 👉following-sibling:當前元素節點標簽之后的所有兄弟節點
from selenium import webdriver
import time


driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

# 定位到輸入框並輸入搜索內容
driver.find_element_by_xpath("//input[@id='kw']").send_keys("selenium")
# 定位到百度按鈕,並點擊
driver.find_element_by_xpath("//input[@class='btn self-btn bg s_btn']").click()
time.sleep(5)

# 關閉瀏覽器
driver.quit()

CSS定位

​ css定位也可以較為靈活地選擇控件的任意屬性,一般情況下定位速度要比xpath要快,但比較復雜,這里只做簡單介紹。有興趣的可以深入了解。

選擇器 例子 描述
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"的所有元素。

​ 以百度輸入框和搜索框為例:

  • 🍄 find_element_by_css_selector(".s_ipt") #通過class屬性定位
  • 🍄 find_element_by_css_selector("#kw") #通過id屬性
  • 🍄 find_element_by_css_selector("input") #通過標簽名
  • 🍄 find_element_by_css_selector("span>input") #通過父子關系定位,查找span所有標簽名叫input的子元素
  • 🍄 find_element_by_css_selector("[name='kw']") #通過屬性定位
  • 🍄 find_element_by_css_selector("span.bg s_ipt_wr>input.s_ipt") #組合定位,父元素是span標簽名,class屬性是.bg s_ipt_wr,有一個子元素,標簽名為input,class屬性是s_ipt

輔助定位工具

​ 快捷鍵f12調出瀏覽器的開發者工具 —— elements,或通過右擊檢查調出,以chrome瀏覽器為例,如下圖,點擊左上角箭頭,再用鼠標點擊頁面中想要定位的元素,該元素所在代碼行會高亮顯示,crtl + f可以調出元素查找框,輸入表達式,在輸入框右邊可以看到該表達式定位的元素是否存在且唯一,可以通過組合定位或者更換更具代表性的屬性去保證定位到的元素是唯一的。

​ 在上圖的底部(搜索框對上一欄),選中元素后還可以看到元素的路徑,可以用此判斷元素是否在iframe表單中;而如果不確定元素是否在html里,可以利用字符串的元素查找,代碼如下:

test = driver.page_source.find("<p>hello</p>")
print(test)	# 返回-1就是不存在


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM