Selenium的WebDriver API元素定位中的XPath和CSS

測試玉米君發表於2020-08-23

元素的定位和操作是自動化測試的核心部分,其中操作又是建立在定位的基礎上的。
本文以百度頁面為例子,帶入深入瞭解XPath和CSS定位的所有方法,程式碼較多,文字只提示重點關注的地方!!!

瀏覽器的常規操作

import time
from selenium import webdriver

# 開啟瀏覽器
driver = webdriver.Chrome()

# 載入網頁
driver.get("https://www.baidu.com")
# 休息3秒
time.sleep(3)

# 設定瀏覽器最大化
driver.maximize_window()
time.sleep(2)

# 設定瀏覽器最小化
driver.minimize_window()
time.sleep(2)

# 設定瀏覽器視窗大小
driver.set_window_size(1200, 700)
time.sleep(2)

# 重新整理
driver.refresh()
time.sleep(2)

# 返回
driver.back()
time.sleep(2)

# 前進
driver.forward()
time.sleep(2)

# 截圖
driver.save_screenshot('baidu.png')
driver.get_screenshot_as_file('baidu2.png')

# 獲取瀏覽器當前url
# print(driver.current_url)
print(f'瀏覽器當前URL:{driver.current_url}')  # https://www.baidu.com/

# 獲取瀏覽器的標題title
# print(driver.title)
print(f'瀏覽器的標題:{driver.title}')  # 百度一下,你就知道

# 獲取頁面原始碼
print(driver.page_source)

# 關閉當前視窗
driver.close()

# 退出driver,關閉所有視窗
driver.quit()

八大元素定位方法

1、id定位
2、name定位
3、class_name定位
4、link_text定位(針對a標籤)
5、partial_link_text定位(針對a標籤)
6、tag_name標籤名定位
7、xpath定位
(1)絕對路徑(絕對路徑使用"/")
(2)相對路徑(相對路徑使用"//")
(3)索引定位
> 1)具體格式://標籤名[@屬性="屬性值"]
> 2)支援使用and和or關鍵字,多個屬性一起定位元素。
(4)屬性定位
(5)部分的屬性值
(6)通過文字定位
(7)各種xpath組合
(8)萬用字元*
8、css選擇器定位
(1)絕對路徑
(2)相對路徑
(3)通過屬性定位
(4)通過部分屬性值(也稱為模糊方法定位)
(5)通過查詢子元素
(6)查詢兄弟元素

id定位

# driver.find_element_by_id("kw").send_keys("測試玉米君")
# 輸出獲取到的元素的id屬性內容
# print(driver.find_element_by_id("kw").get_attribute("id"))
print(f'1、id定位 獲取到的元素的id屬性內容:{driver.find_element_by_id("kw").get_attribute("id")}')  # kw

name定位

# driver.find_element_by_name('wd').send_keys("測試玉米君")
# 輸出獲取到的元素的name屬性內容
# print(driver.find_element_by_name("wd").get_attribute("name"))
print(f'2、name定位 獲取到的元素的name屬性內容:{driver.find_element_by_name("wd").get_attribute("name")}')  # wd

class_name定位

# driver.find_element_by_class_name("s_ipt").send_keys("測試玉米君")
# 輸出獲取到的元素的class屬性內容
# print(driver.find_element_by_class_name("s_ipt").get_attribute("class"))
print(f'3、class_name定位 獲取到的元素的class屬性內容:{driver.find_element_by_class_name("s_ipt").get_att
ribute("class")}')  # s_ipt
# driver.find_element_by_link_text("新聞").click()
# 輸出獲取到的元素的文字內容
print(driver.find_element_by_link_text("新聞").text)
print(
f'4、link_text定位 獲取到的元素的文字內容:{driver.find_element_by_link_text("新聞").text}')  # 新聞
# driver.find_element_by_partial_link_text("聞").click()
# 輸出獲取到的元素的文字內容
# print(driver.find_element_by_partial_link_text("聞").text)
print(f'5、partial_link_text定位 獲取到的元素的文字內容:{driver.find_element_by_partial_link_text("聞").text}')  # 新聞

tag_name標籤名定位

# 輸出獲取到的元素的action屬性內容
# print(driver.find_element_by_tag_name("form").get_attribute("action"))
print(
    f'6、tag_name標籤名定位 獲取到的元素的action屬性內容:{driver.find_element_by_tag_name("form").get_attribute("action")}')  # https://www.baidu.com/s

xpath定位

(1)絕對路徑(絕對路徑使用"/")

# 舉例:定位搜尋框輸入搜尋內容"測試玉米君"
# driver.find_element_by_xpath("/html/body/div/div/div/div/div/form/span/input").send_keys("測試玉米君")
print(
    f'7.1、xpath絕對路徑定位 獲取到的元素的id屬性內容:{driver.find_element_by_xpath("/html/body/div/div/div/div/div/form/span/input").get_attribute("id")}')  # kw

(2)相對路徑(相對路徑使用"//")

# 舉例:定位搜尋框輸入搜尋內容"測試玉米君"
# driver.find_element_by_xpath("//form/span/input").send_keys("測試玉米君")
# 輸出獲取到的元素的id屬性內容
print(f'7.2、xpath相對路徑定位 獲取到的元素的id屬性內容:{driver.find_element_by_xpath("//form/span/input").get_attribute("id")}')  # kw

(3)索引定位

索引從"1"開始,預設不填寫就是"1"

# 舉例:定位 百度一下 按鈕
# driver.find_element_by_xpath("//form/span[2]/input").click()
# 輸出獲取到的元素的value屬性內容
print(
    f'7.3.1、xpath索引定位 取到的元素的value屬性內容:{driver.find_element_by_xpath("//form/span[2]/input").get_attribute("value")}')  # 百度一下
# 舉例:定位百度hao123連結
# driver.find_element_by_xpath("//div[3]/a[2]").click()
# 輸出標籤文字內容
print(f'7.3.2、xpath索引定位 取到的元素的文字內容:{driver.find_element_by_xpath("//div[3]/a[2]").text}')  # hao123
# 舉例:定位百度hao123連結
# driver.find_element_by_xpath("//div[@id='s-top-left']/a[2]").click()
# 輸出標籤文字內容
print(
    '7.3.3、xpath索引定位 取到的元素的文字內容:{}'.format(driver.find_element_by_xpath('//div[@id="s-top-left"]/a[2]').text))  # hao123

(4)屬性定位

使用"@"符號呼叫屬性

# driver.find_element_by_xpath("//input[@autocomplete='off']").send_keys("測試玉米君")
print('7.4.1、xpath屬性定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_xpath("//input[@autocomplete='off']").get_attribute("id")))  # kw
# driver.find_element_by_xpath("//input[@autocomplete='off' and @name='wd']").send_keys("測試玉米君")
print('7.4.2、xpath屬性定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_xpath("//input[@autocomplete='off' and @name='wd']").get_attribute("id")))  # kw

(5)部分的屬性值

也稱為模糊方法定位

# 元素屬性值開頭包含內容:starts-with()
# driver.find_element_by_xpath("//input[starts-with(@autocomplete,'of')]").send_keys("測試玉米君")
print('7.5.1、xpath部分的屬性值定位 取到的元素的autocomplete屬性內容:{}'.format(
    driver.find_element_by_xpath("//input[starts-with(@autocomplete,'of')]").get_attribute("autocomplete")))  # off
# 元素屬性值結尾包含內容:substring()
# driver.find_element_by_xpath("//input[substring(@class,3)='ipt']").send_keys("測試玉米君")
print('7.5.2、xpath部分的屬性值定位 取到的元素的class屬性內容:{}'.format(
    driver.find_element_by_xpath("//input[substring(@class,3)='ipt']").get_attribute("class")))  # s_ipt
# 元素屬性值包含內容:contains()
# driver.find_element_by_xpath("//input[contains(@class,'pt')]").send_keys("測試玉米君")
print('7.5.3、xpath部分的屬性值定位 取到的元素的class屬性內容:{}'.format(
    driver.find_element_by_xpath("//input[contains(@class,'pt')]").get_attribute("class")))  # s_ipt

(6)通過文字定位

# 元素文字在xpath中可以通過text()函式獲取,也可以用其來進行元素定位。
# driver.find_element_by_xpath("//a[text()='新聞']").click()
print('7.6.1、xpath文字定位 取到的元素的文字內容:{}'.format(driver.find_element_by_xpath("//a[text()='新聞']").text))  # 新聞
# driver.find_element_by_xpath("//span[text()='按圖片搜尋']").get_attribute("style")
print('7.6.2、xpath文字定位 取到的元素的style屬性內容:{}'.format(
    driver.find_element_by_xpath("//span[text()='按圖片搜尋']").get_attribute("style")))  # display: none

(7)各種xpath組合

# driver.find_element_by_xpath("//a[contains(text(),'新聞')]").click()
print('7.7.1、各種xpath組合 取到的元素的文字內容:{}'.format(driver.find_element_by_xpath("//a[contains(text(),'新聞')]").text))  # 新聞
# driver.find_element_by_xpath("//a[contains(text(),'新')]").click()
print('7.7.2、各種xpath組合 取到的元素的文字內容:{}'.format(driver.find_element_by_xpath("//a[contains(text(),'新')]").text))  # 新聞
# driver.find_element_by_xpath("//form[@id='form']/span[1]/input").send_keys("測試玉米君")
print('7.7.3、各種xpath組合 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_xpath("//form[@id='form']/span[1]/input").get_attribute("id")))  # kw

(8)萬用字元*

# driver.find_element_by_xpath("//*[@*='kw']").send_keys("測試玉米君")
print('7.8、xpath萬用字元*定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_xpath("//*[@*='kw']").get_attribute("id")))  # kw

css選擇器定位

html,javascript,css,h5+css3,通過.找class,通過#找id

(1)絕對路徑

# driver.find_element_by_css_selector("html body div div div div div form span input").send_keys("測試玉米君")
print('8.1.1、css絕對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("html body div div div div div form span input").get_attribute("id")))  # kw
# driver.find_element_by_css_selector("html>body>div>div>div>div>div>form>span>input").send_keys("測試玉米君")
print('8.1.2、css絕對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("html>body>div>div>div>div>div>form>span>input").get_attribute("id")))  # kw
# driver.find_element_by_css_selector("html body div.wrapper_new div#head div.head_wrapper.s-isindex-wrap.nologin div div form span input").send_keys("測試玉米君")
print('8.1.3、css絕對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector(
        "html body div.wrapper_new div#head div.head_wrapper.s-isindex-wrap.nologin div div form span input").get_attribute(
        "id")))  # kw

(2)相對路徑

通過class(.)和id(#)定位)可以和標籤名組合使用

# driver.find_element_by_css_selector("#kw").send_keys("測試玉米君")
print('8.2.1、css相對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("#kw").get_attribute("id")))  # kw
# driver.find_element_by_css_selector(".s_ipt").send_keys("測試玉米君")
print('8.2.2、css相對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector(".s_ipt").get_attribute("id")))  # kw
# driver.find_element_by_css_selector("input#kw").send_keys("測試玉米君")
print('8.2.3、css相對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("input#kw").get_attribute("id")))  # kw
# driver.find_element_by_css_selector("input.s_ipt").send_keys("測試玉米君")
print('8.2.4、css相對路徑定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("input.s_ipt").get_attribute("id")))  # kw

(3)通過元素屬性定位

# 具體格式:標籤名[屬性="屬性值"] 支援使用多個屬性一起定位元素
# driver.find_element_by_css_selector("input[autocomplete='off']").send_keys("測試玉米君")
print('8.3.1、css元素屬性定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("input[autocomplete='off']").get_attribute("id")))  # kw
# driver.find_element_by_css_selector("input[autocomplete='off'][name='wd']").send_keys("測試玉米君")
print('8.3.2、css元素屬性定位 取到的元素的id屬性內容:{}'.format(
    driver.find_element_by_css_selector("input[autocomplete='off'][name='wd']").get_attribute("id")))  # kw

(4)通過部分元素屬性值(也稱為模糊方法定位)

1)元素屬性值開頭包含內容:^=

2)元素屬性值結尾包含內容:$=

3)元素屬性值當中包含內容:*=

# driver.find_element_by_css_selector("input[autocomplete^='of']").send_keys("測試玉米君")
print('8.4.1、css部分屬性值定位 取到的元素的autocomplete屬性內容:{}'.format(
    driver.find_element_by_css_selector("input[autocomplete^='of']").get_attribute("autocomplete")))  # off
# driver.find_element_by_css_selector("input[autocomplete$='ff']").send_keys("測試玉米君")
print('8.4.2、css部分屬性值定位 取到的元素的autocomplete屬性內容:{}'.format(
    driver.find_element_by_css_selector("input[autocomplete$='ff']").get_attribute("autocomplete")))  # off
# driver.find_element_by_css_selector("input[autocomplete*='of']").send_keys("測試玉米君")
print('8.4.3、css部分屬性值定位 取到的元素的autocomplete屬性內容:{}'.format(
    driver.find_element_by_css_selector("input[autocomplete*='of']").get_attribute("autocomplete")))  # off

(5)通過查詢子元素(類似xpath中的索引的方法)

1)子元素:A>B

2)後代元素:A B(類似>)

3)第一個後代元素:first-child

4)最後一個後代元素:last-child[等同於 p:nth-last-child(1)]

5)第n個子元素:nth-child(N)[類同:nth-of-type(N)]

6)通過空格和>查詢子元素(只能一級一級找)

# driver.find_element_by_css_selector("div#s-top-left a:nth-child(1)").click()
print('8.5.1、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a:nth-child(1)").text))  # 新聞
# driver.find_element_by_css_selector("div#s-top-left a:first-child").click()
print('8.5.2、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a:first-child").text))  # 新聞
# driver.find_element_by_css_selector("div#s-top-left a:last-child").click()
print('8.5.3、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a:last-child").text))  #
# driver.find_element_by_css_selector("div#s-top-left a:nth-last-child(2)").click()
print('8.5.4、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a:nth-last-child(2)").text))  # 學術
# driver.find_element_by_css_selector("div#s-top-left a:nth-child(2)").click()
print('8.5.5、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a:nth-child(2)").text))  # hao123

(6)查詢兄弟元素

1)同層級下一個元素:+

2)選擇同層級多個相同標籤的元素:~

備註:

+號可以多次使用
~號一般返回的是多個元素,要用find_elements接收
# driver.find_element_by_css_selector("div#s-top-left a +a").click()
print('8.6.1、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a +a").text))  # hao123
# driver.find_element_by_css_selector("div#u1 a +a +a").click()
print('8.6.2、css子元素定位 取到的元素的文字內容:{}'.format(
    driver.find_element_by_css_selector("div#s-top-left a +a +a").text))  # 地圖

自動化框架中封裝定位

from selenium.webdriver.common.by import By

driver.find_element(By.ID, "kw").send_keys("測試玉米君")

總結

定位元素的方式有8種,寫法有兩種

id定位

driver.find_element_by_id("kw")
driver.find_element(By.ID, "kw")

name定位

driver.find_element_by_name("wd")
driver.find_element(By.NAME, "wd")

class定位

driver.find_element_by_class_name("s_ipt")
driver.find_element(By.CLASS_NAME, "s_ipt")

tag_name定位

driver.find_element_by_tag_name("form")
driver.find_element(By.TAG_NAME, "form")
driver.find_element_by_link_text("新聞")
driver.find_element(By.LINK_TEXT, "新聞")
driver.find_element_by_partial_link_text("新")
driver.find_element(By.PARTIAL_LINK_TEXT, "新")

XPath定位

driver.find_element_by_xpath("//input[@id='kw']")
driver.find_element(By.XPATH, "//input[@id='kw']")

CSS定位

driver.find_element_by_css_selector("#kw")
driver.find_element(By.CSS_SELECTOR, "#kw")

歡迎來跟博主討論自動化有關的問題。

相關文章