天天看點

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

Selenium庫

用于web應用程式的測試工具

模拟手工操作浏覽器,進行自動化測試

特點

  1. 開源免費
  2. 多浏覽器支援 —Chrome、IE、FireFox等
  3. 多平台支援 — Windows、Linux都支援
  4. 支援分布式測試(Grid)
  5. 支援錄制回放和腳本生成(IDE)

Selenium三劍客

  1. WebDriver
  2. IDE 支援錄制回放和腳本生成
  3. Grid 支援分布式測試

官方文檔

  • https://selenium-python.readthedocs.io/index.html
  • https://seleniumhq.github.io/selenium/docs/api/py/api.html

webdriver工作原理

通過浏覽器的driver與浏覽器進行通信.(傳令兵,把我們的指令通過webdriver傳遞給浏覽器,同時把浏覽器的傳回結果進行定位、操作、擷取屬性資訊等)

配置環境

pip install selenium

下載下傳webdriver(與浏覽器的種類和版本比對)

Chrome:http://chromedriver.storage.googleapis.com/index.html

Firefox:https://github.com/mozilla/geckodriver/releases/

下載下傳好後解壓

1.放置到python的安裝目錄

2.放置在項目中的專門目錄

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

使用selenium

進入網址,進入到網站後顯示5秒鐘,5秒之後關閉浏覽器

# 想操作浏覽器導入webdriver的包就可以,不用導入selenium中所有的包
from selenium import webdriver
from time import sleep

# 初始化一個driver(要加括号)
driver = webdriver.Chrome()
# 通路樂博商城的網址
driver.get("http://shop.pro.17lebo.com")

#這時我就可以控制浏覽器了,能控制浏覽器就可以操縱要測試的軟體了
#……

# 沉睡5秒鐘 
sleep(5)
# 退出目前标簽頁
# driver.close()
# 退出整個浏覽器  不關閉浏覽器,浏覽器會越來越多
driver.quit()
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

webdriver的功能

  1. 能通路浏覽器
  2. 能設定浏覽器的視窗大小 無界面時也有效
# 最大化
driver.maximize_window()
# 最小化
driver.minimize_window()
# 設定視窗大小
driver.set_window_size(800, 600)
           
  1. 控制前進、後退
from selenium import webdriver
from time import sleep

# 初始化一個driver(要加括号)
driver = webdriver.Chrome()
# 通路樂博商城的網址
driver.get("http://shop.pro.17lebo.com")

# 設定浏覽器的大小
# 最大化
driver.maximize_window()
# 控制前進。後退
# 打開樂博官網
driver.get("http://www.17lebo.com")
sleep(3)
# 後退  去上一個頁面
driver.back()
sleep(3)

# 前進  去下一個頁面
driver.forward()
sleep(3)
           
  1. 截圖
# 浏覽器截圖
driver.get_screenshot_as_file("浏覽器截圖3.png")
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫
  1. 重新整理頁面
# 重新整理頁面
driver.refresh()
           
  1. 關閉浏覽器
  1. 關閉目前頁面
  1. 擷取頁面屬性
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

浏覽器的無界面操作

每次運作的時候都會出現浏覽器,有的時候不想讓浏覽器出現,就用到無界面操作

無界面模式下預設不是全屏,預設大小是800*600

# 浏覽器的無界面操作
# 用來儲存各種webdriver的配置項
opt = webdriver.ChromeOptions()
opt.headless = True
# 初始化一個driver(要加括号)
driver = webdriver.Chrome(options=opt)
           

Selenium定位頁面元素

UI自動化測試,從定位頁面元素開始

8大定位方法

  1. id
  2. name
  3. class name:class的名
  4. tag name:标簽名
  5. link text:連結的文字内容
  6. partial link text:這個link text包含的一部分内容
  7. xpath
  8. css selector

find_element()和find_elements()

name定位

UI自動化之Selenium介紹、Selenium定位方法Selenium庫
item = driver.find_element_by_name("wd")
item.send_keys("手機")
           

可以看到是定位成功并且已經輸入我想要搜尋的内容了

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

但是提示了最好不要使用find_element_by_*,selenium4.0以後就無法使用了

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

是以用find_element()代替

from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# 通路樂博商城的網址
driver.get("http://shop.pro.17lebo.com")
item = driver.find_element(By.NAME, "wd")
item.send_keys("手機")
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

By.name實際就是傳的name,同理,By.id就是傳的id

是以可以直接傳name

item = driver.find_element("name", "wd")
item.send_keys("手機")
           

id定位

item = driver.find_element("id", "search-input")
item.send_keys("手機")
           

class定位

我想定位百寶箱,然後點選

UI自動化之Selenium介紹、Selenium定位方法Selenium庫
item = driver.find_element("class name", "navigation-main-quick")
item.click()
           

點選百寶箱後底部彈框,說明點選成功

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

tag name定位

多少有點不靠譜,因為重名的太多了

标簽名定位,需要确認這個頁面隻有一個這個标簽,才用标簽定位,否則定位出來的就不止一個了

item = driver.find_element("tag name", "input")
item.send_keys("手機")
           

如果目前頁面有多個同樣的标簽,就要用find_elements(),這時,傳回的就是一個清單了,如果要引用其中的一個元素,就要加索引

比如:

item = driver.find_elements("tag name", "input")
item[1].send_keys("手機")
           

link text定位

link是通過連結的文字定位,點一下會跳轉到另外的頁面

UI自動化之Selenium介紹、Selenium定位方法Selenium庫
item = driver.find_element("link text", "登入")
item.click()
           

partial link text定位

和link text差不多,隻是這個是通過連結的文字内容的一部分進行定位,而不是全部内容

還是點選登入跳轉,我隻要連結中的“錄”字就可以定位到了

item = driver.find_element("partial link text", "錄")
item.click()
           

id、 name、 class name、tag name、 link text、partial link text這些定位方法都是理想的情況下,能通過這些定位,都是有要求的,有局限性。如果标簽中沒有這些屬性,就沒法通過這些來定位了。

xpath和css selector定位是萬能定位,功能強大,css selector比xpath的速度快

xpath定位

xpath就是XML path language

專門在xml文檔中對元素和屬性進行周遊

xpath是可以拷貝的

相對定位://*[@id=“search-input”]

絕對定位(嚴重不推薦):/html/body/div[3]/div/div[3]/form/div/input

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

xpath的文法結構:xpath = //tagname[@Attribute = ‘value’]

  1. 斜線/雙斜線 查找範圍或查找方式

    /表示絕對定位

    //表示相對定位

  2. tagname 标簽名稱

    *代表所有标簽

    具體的标簽名稱:h、p、input、div、button、a…

    當标簽名不足以唯一的選擇出來時,後面可以加條件[ ]

  3. [ ]選擇條件

    @Attribute 用屬性進行選擇 id、name、class…

    用函數選擇

    屬性+函數

隻用标簽名後面不跟選擇條件

# xpath的選擇條件隻用标簽名定位
items = driver.find_elements("xpath", "//p")
for i in items:
    print(i.text)
           

xpath的選擇條件隻用标簽名定位的執行結果,隻用标簽名一般都會定位到很多東西

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

選擇條件用id

# 選擇條件用id
item = driver.find_element("xpath", "//input[@id='search-input']")
item.send_keys("找到一個//input[@id=search-input]")
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

選擇條件用name

# 選擇條件用name
item = driver.find_element("xpath", "//input[@name='wd']")
item.send_keys("找到xpath為//input[@name='wd']的元素")
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

選擇條件用class+層級關系

# 選擇條件用class
# 這個元素的class不是唯一的,是以可以用層級關系來輔助定位
# 因為要定位的是一個input 而input的class不是唯一的,是以找到input上一級的class,input上一級是一個div,把這個div寫出來,然後後面再加一個input
# 這個class在整個頁面中不是唯一的,但是在這個div中是唯一的
item = driver.find_element("xpath", "//div[@class='search-group']/input")
item.send_keys("找到xpath為//div[@class='search-group']/input的元素")
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

text() 函數

用屬性前面有@符,用函數前面沒有@符

# text屬性
# 先找到輸入框元素
item = driver.find_element("xpath", "//div[@class='search-group']/input")
# 在輸入框中輸入手機
item.send_keys("手機")
# 找到搜尋按鈕(已經精确到文字内容了,是以前面标簽名可以用通配符*)
search = driver.find_element("xpath", "//*[text()='搜尋']")
# 點選搜尋
search.click()
           

這時已經進到手機頁了

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

使用索引

沒有辦法唯一定位的時候可以使用索引

item = driver.find_element("xpath", "//div[@class='search-group']/input")
item.send_keys("手機")
item = driver.find_elements("xpath", "//button")
item[0].click()
           

多條件組合

當中括号中一個條件已經不足以确定元素的時候,就可以輸入多個條件

# 多條件組合
item = driver.find_element("xpath", "//input[@type = 'text' and @placeholder = '其實搜尋很簡單^_^ !']")
item.send_keys("電腦")
           
UI自動化之Selenium介紹、Selenium定位方法Selenium庫

常用函數

contains() 包含XXX

# 常用函數之包含XXX——contains()
item = driver.find_element("xpath", "//input[contains(@placeholder,'^_^')]")
item.send_keys("電腦")
           

starts-with() 以XXX開頭

# 以XXX開頭——starts-with()
item = driver.find_element("xpath", "//input[starts-with(@placeholder,'其實')]")
item.send_keys("電腦")
           

……

軸 (相對查找. 找 父節點,祖父節點)

文法:

軸名稱::節點測試[謂語]

軸名稱 結果
ancestor 選取目前節點的所有先輩(父、祖父等)。
ancestor-or-self 選取目前節點的所有先輩(父、祖父等)以及目前節點本身。
attribute 選取目前節點的所有屬性。
child 選取目前節點的所有子元素。
descendant 選取目前節點的所有後代元素(子、孫等)。
descendant-or-self 選取目前節點的所有後代元素(子、孫等)以及目前節點本身。
following 選取文檔中目前節點的結束标簽之後的所有節點。
namespace 選取目前節點的所有命名空間節點。
parent 選取目前節點的父節點。
preceding 選取文檔中目前節點的開始标簽之前的所有節點。
preceding-sibling 選取目前節點之前的所有同級節點。
self 選取目前節點。

css selector定位

css定位是selenium首推的定位方式,因為css定位的速度快。項目小的時候無所謂,項目大的時候速度快是很重要的。

幾乎很難發現找到某一個元素沒有class沒有樣式的,所有網頁裡顯示的都系幾乎都會有樣式,沒有樣式會特别醜。是以css選擇器定位很友善,總會定位出來想要的元素。

css和xpath的比較:

  1. 速度比xpath快
  2. 文法簡潔

css選擇器用id定位

# css selector定位
# 用id定位   #代表id
item = driver.find_element("css selector", "#search-input")
item.send_keys("手機")
           

用name定位

# 用name定位  input是我要定位元素的标簽
item = driver.find_element("css selector", "input[name='wd']")
item.send_keys("手機")
           

用class name定位

class name定位的一般都會出現一堆,而不是一個,是以要通過索引定位

# class name定位  .代表class
items = driver.find_elements("css selector", ".outer")
items[2].click()
           

要定位的元素有多個class時

# 多個class
item = driver.find_element("css selector", "[class='am-text-truncate name']")
item.click()
           

用其他屬性定位

# 用其他屬性定位 三種都可以
# item = driver.find_element("css selector", "input[placeholder='其實搜尋很簡單^_^ !']")
# item = driver.find_element("css selector", "*[placeholder='其實搜尋很簡單^_^ !']")
item = driver.find_element("css selector", "[placeholder='其實搜尋很簡單^_^ !']")
item.send_keys("手機")
           

多個屬性組合

item = driver.find_element("css selector", "input[placeholder='其實搜尋很簡單^_^ !'][autocomplete='off']")
item.send_keys("手機")
           

部分屬性定位

包含 *=

# 包含  *=
item = driver.find_element("css selector", "input[placeholder *= '很簡']")
item.send_keys("手機")
           

以XXX開始 ^=

# 以XXX開始   ^=
item = driver.find_element("css selector", "input[placeholder ^= '其實']")
item.send_keys("手機")
           

以XXX結束 $=

# 以XXX結束  $=
item = driver.find_element("css selector", "input[placeholder $= '!']")
item.send_keys("手機")
           

層級關系 >

上下一級關系,頂頭上司

# 層級關系 >    div是父級,input是子級
item = driver.find_element("css selector", "div[class='search-group']>input")
item.send_keys("電腦")
           

後代關系 用空格

上下多級關系,越級上司

UI自動化之Selenium介紹、Selenium定位方法Selenium庫
# 後代關系   用空格
item = driver.find_element("css selector", "div[class='am-container'] input")
item.send_keys("電腦")
           

兄弟選擇器

# 兄弟選擇器 找到div中class為word的元素,在這個元素裡面找到a标簽,冒号後面代表要找第幾個a标簽的元素
# 找第一個
# item = driver.find_element("css selector", "div[class='word']>a:first-child")
# 找第三個
# item = driver.find_element("css selector", "div[class='word']>a:nth-child(3)")
# 找最後一個
item = driver.find_element("css selector", "div[class='word']>a:last-child")
item.click()
           

層級與class組合

UI自動化之Selenium介紹、Selenium定位方法Selenium庫
# 層級與class組合
item = driver.find_element("css selector", "div.search-bar>form>div>input")
item.send_keys("電腦")
           

selenium官方文檔 CSS定位

css選擇器常用的文法

選擇器 例子 例子描述
.class .intro 選擇 class=“intro” 的所有元素。
#id #firstname 選擇 id=“firstname” 的所有元素。
* * 選擇所有元素。
element p 選擇所有 < p > 元素。
element,element div,p 選擇所有 < div> 元素和所有 < p> 元素。
element element div p 選擇 < div> 元素内部的所有 < p> 元素。
element>element div>p 選擇父元素為 < div> 元素的所有 < p> 元素。
element+element div+p 選擇緊接在 < div> 元素之後的所有 < p> 元素。
[attribute] [target] 選擇帶有 target 屬性所有元素。
[attribute=value] [target=_blank] 選擇 target=“_blank” 的所有元素。
[attribute~=value] [title~=flower] 選擇 title 屬性包含單詞 “flower” 的所有元素。
[attribute I= value] [lang I= en] 選擇 lang 屬性值以 “en” 開頭的所有元素。

多個元素的情況

在有些特殊情況就需要定位多個元素,然後挨個去進行操作

還有可能就是實在無法定位到唯一的元素了,找不到條件了,那就隻能定位多個元素然後通過索引定位到要用的元素

items = driver.find_elements("class name", "outer")
for item in items:
    # 列印出所有的元素
    print(item.text)
# 然後就可以根據對應的索引進行定位,然後操作了
items[1].click()
           

擷取頁面中元素的屬性值

items = driver.find_elements("class name", "outer")
# 擷取頁面元素的屬性值
print(items[2].get_attribute("name"))
print(items[2].get_attribute("type"))
print(items[2].get_attribute("class"))
           

有的有有的沒有,有值的會列印出來,沒有的會顯示為空

UI自動化之Selenium介紹、Selenium定位方法Selenium庫

頁面元素的互動操作

點選:click()

輸入:send_keys()

清除:clear()

等等……