Python之Selenium使用


(一)Selenium基礎

入門教程:Selenium官網教程

1.Selenium簡介

Selenium是一個用於測試網站的自動化測試工具,支持各種瀏覽器包括Chrome、Firefox、Safari等主流界面瀏覽器,同時也支持phantomJS無界面瀏覽器。

2.支持多種操作系統

如Windows、Linux、IOS、Android等。

3.安裝Selenium

pip install selenium

4.安裝瀏覽器驅動

Selenium3.x調用瀏覽器必須有一個webdriver驅動文件

  1. Chrome驅動文件下載:https://npm.taobao.org/mirrors/chromedriver/(需要下載和我們電腦中Chrome瀏覽器同樣的版本,如果沒有同樣的版本,下載距離最近的版本,電腦是64位,下載32位的是可以正常使用的),下載后,進入壓縮包,點擊【解壓到】,放到“Python”的【類似Python38】安裝目錄下
  2. Firefox驅動文件下載:https://github.com/mozilla/geckodriver/releases

5、與瀏覽器建立連接

Selenium原理:通過http接口請求的方式進行的數據的傳遞

from selenium import webdriver

browser = webdriver.Chrome()

#執行代碼時遇到報錯,找不到瀏覽器路徑,可加上參數、chromedriver路徑
browser= webdriver.Chrome(executable_path=r'user/xxxx/chromedriver')
browser.get(
"http://www.baidu.com") #打開百度

6、查找元素

對於操作瀏覽器中的頁面的自動化測試框架來說,肯定少不了 去發現網頁中的元素,你只有發現那些元素實時存在了才能做出下一步的操作。Selenium中提供了眾多的方法供我們去找到網頁中的元素,這給我們帶來了很大的便利,那么都有哪些方法了,我們可以通過Python快速獲取到這些方法:

#9種單數形式
find_element(‘id’,‘kw’)
#根據所需指定:如‘id’、‘xpath’等,第二個參數為:對應的屬性值——這個方法了常用,以下的其他都是通過這個方法封裝的,這個會靈活一點 find_element_by_class_name #通過Class name查找指定的一個元素 find_element_by_css_selector #通過CSS選擇器查找指定的一個元素(和xpath定位找到類似),優先使用,日后查找問題會方便快捷 find_element_by_id #通過ID查找指定的一個元素 find_element_by_link_text #通過a標簽鏈接文本獲取指定的一個超鏈接(精確匹配) find_element_by_name #通過Name查找指定的一個元素 find_element_by_partial_link_text #通過鏈接文本獲取指定的一個超鏈接(模糊匹配) find_element_by_tag_name #通過標簽名查找指定的一個元素(如:div、span),默認找到第一個頁面元素 find_element_by_xpath #通過Xpath語法來指定的一個元素
#9種復數形式:
find_elements #通過指定方法查找所有元素(需指定兩個參數) find_elements_by_class_name #通過Class name查找所有元素 find_elements_by_css_selector #通過CSS選擇器查找所有元素 find_elements_by_id #通過ID查找所有元素 find_elements_by_link_text #通過鏈接文本獲取所有超鏈接(精確匹配) find_elements_by_name #通過Name查找所有元素 find_elements_by_partial_link_text #通過鏈接文本獲取所有超鏈接(模糊匹配) find_elements_by_tag_name #通過標簽名查找所有元素 find_elements_by_xpath #通過Xpath語法來查找所有元素,前端是一個‘樹形’結構的頁面,xpath是以文件路徑的形式一級一級查找元素,如:/html/body/div[2],


單數形式:獲取到的是符合一個元素
復數形式:獲取到的是符合的所有元素,定位一個元素,可使用下邊的方式定位

Copy出有時候是“相對路徑”,有時候是“絕對路徑”,機器來獲取的不一定。

注:Copy_Copy full xpath——絕對路徑
因復制的,有時候會不盡人意,一般使用手寫xpath,如://*[@id='su'],屬性可以自定義,如:name、class,maxlens等都可以
如遇到,如有2個name是“wd”,我們可以加 and條件,可以這樣寫://*[@name=“wd” and id=“1”]
//: 獲取所有內容
* : 任意一個元素,可以替換為任意指定標簽屬性,如:div、input;例://span[@name=“wd”],這樣子會查找的不是所有元素,而是sapn標簽中的所有
@ : 表示篩選類型是【屬性】
id: 指定的元素key
su: 指定元素的value

 可以看到輸入框的ID為KW,Name為WD,這里我們選擇ID,選擇ID有三種方法,如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
c= webdriver.Chrome()
c.get('https://www.baidu.com')
kw1=c.find_element(By.ID,'kw')
kw2=c.find_element_by_id('kw')
kw3=c.find_elements_by_id('kw')[0]
print(kw1)
print(kw2)
print(kw3)

 可以看到我們成功使用三種方法獲取到了這個元素,其它方法差不多,都是一通百通,喜歡哪種方法就使用哪種方法。

  • a標簽中文本類型(text)怎么定位
//a[text()=“文本名稱”]#a可以為任意的標簽名稱
  • 只寫屬性名查詢,不寫屬性值
//input[@id]#查詢到input標簽中含有id的所有元素,默認在從上到下第一元素位置
  •  一切正常,元素無法定位到的主要原因:
  1. 等待時間不夠
  2. 等待的方式有問題(隱形等待、顯性等待、強制等待)
  3. 有iframe
  4. 句柄的切換(如:快捷登錄,點擊QQ登錄后,進入到了新的瀏覽器窗口,但我們所能識別的只是我們操作中的一個瀏覽器窗口,就需要切換句柄操作后,在切換回來)
  5. 頁面沒有聚焦(最大化),會導致有些元素沒被顯示出來,或是需要滑輪下滑后才可看到,或是有被其他的欄位遮擋
  6. 有重復元素,且被優先選中

7、瀏覽器操作

(1)獲取本頁面URL

c.current_url

 (2)獲取日志

c.log_types  #獲取當前日志類型
c.get_log('browser')#瀏覽器操作日志
c.get_log('driver') #設備日志
c.get_log('client') #客戶端日志
c.get_log('server') #服務端日志

##3.窗口操作
c.maximize_window()#最大化
c.fullscreen_window() #全屏
c.minimize_window() #最小化
c.get_window_position() #獲取窗口的坐標
c.get_window_rect()#獲取窗口的大小和坐標
c.get_window_size()#獲取窗口的大小
c.set_window_position(100,200)#設置窗口的坐標
c.set_window_rect(100,200,32,50)    #設置窗口的大小和坐標
c.set_window_size(400,600)#設置窗口的大小
c.current_window_handle   #返回當前窗口的句柄
c.window_handles         #返回當前會話中的所有窗口的句柄

 (3)設置延時

【等待的作用】: 在系統的功能運行過程中,所有的內容需要一定的時間來實現展示(需要從服務端獲取到返回回來)

  • 時間消耗的長短相關: 網絡速度、系統的框架設定、接口的復雜程度、sql語句的編寫等等。
  • 在自動化中,我們做UI測試,主要是基於系統的流程來實現自動化,往往一些下一步需要上一步的特定操作完成后才可以繼續執行(如:需要登錄后才可以進入首頁操作)。在下一步准備執行時,上一步必須是已經執行完,且已生成了實際結果。
  • 考慮到運行時間的問題,以及流程的步驟問題,所以我們在實際執行自動化的時候,需要設置下緩沖時間。如果沒有設置緩沖時間,會導致還沒等頁面加載完,就會操作,會找不到此元素,自然就會報錯了。
c.set_script_timeout(5) #設置腳本延時五秒后執行
c.set_page_load_timeout(5)#設置頁面讀取時間延時五秒

 三大等待時間:

1. 強制等待: 通過導入“time”模塊中的sleep方法,等待x秒以后,在繼續執行后續的代碼,無所謂當前處於什么階段,執行了什么操作,后續是否已經准備就緒,反正就是要等待x秒,一般是剛學習自動化的過程中使用,實際中基本不使用 

【缺點】: 無法精准的把握等待時間(無法判斷是否達到下一步可以操作/無法判定頁面是否已經加載完),如果一直使用強制等待,會嚴重影響自動化效率,浪費好多時間。

【優點】: 一般在調試的時候使用,簡單使用,可一下清楚是不是頁面緩沖需要加等待時間。

import time
sleep(5) #等待5秒

2. 隱式等待: 純粹基於webdriver進行調用的,每一個腳本執行時,都會調用隱式等待;不操作quit()釋放,隱式等待是一直起作用的,釋放后才會沒有了隱式等待。

設置一個隱形的等待,設置最長的等待時間,如果在這個時間內完成了頁面內容的全部加載,則進行下一步,否則一直等待到時間結束,再執行下一步

【優點】: 對整個Webdriver周期都會起到作用,只需要設置一次。

【缺點】必須要等待頁面全部加載完成,才可以進行下一步,有些時候特定的元素已經被加載出來,但是頁面本身還沒被加載完,就會等待到設置的等待時間完了,才會進行下一步,應用上會不太靈活

driver.implicitly_wait(10) #隱式等待10秒,設置到一開始的位置

3.顯示等待: 專門對於指定的條件進行等待,在設置的最大時長內,依照查找的時間頻率來進行搜索,查找指定的對象,until表示如果找到,則進行下一步,否則超時后的拋出異常信息,默認拋出NoSuchElementExeception異常。until_not()方法則相反。

如:百度關鍵字查詢出來后點擊第一個搜索內容,設置顯示等待后,只要第一個內容有被加載出來,就會點擊操作,不會繼續等待其他的加載內容了

from selenium.webdriver.support.wait import WebDriverWait #導入模塊

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
'''
driver:瀏覽器驅動
timeout:最長超時時間,默認以秒為單位
poll_frequency:檢測的間隔步長,默認為0.5s
ignored_exceptions:超時后的拋出的異常信息,默認拋出NoSuchElementExeception異常。
與until()或者until_not()方法結合使用
WebDriverWait(driver,10).until(method,message="")
調用該方法提供的驅動程序作為參數,直到返回值為True

WebDriverWait(driver,10).until_not(method,message="")
調用該方法提供的驅動程序作為參數,直到返回值為False

在設置時間(10s)內,等待后面的條件發生。如果超過設置時間未發生,則拋出異常。在等待期間,每隔一定時間(默認0.5秒),調用until或until_not里的方法,直到它返回True或False.

WebDriverWait與expected_conditions結合使用
'''

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver,10,0.5)
element =wait.until(EC.presence_of_element_located((By.ID,"kw")),message="")
# 此處注意,如果省略message=“”,則By.ID外面是三層()

(4)關閉

c.close() #關閉當前標簽頁,不會關閉“webdrive”進程,有多個標簽頁時,只會關閉當前標簽頁
c.quit() #關閉瀏覽器並關閉驅動,腳本最后加上,不加上“webdriver”進程一直是沒關閉的狀態,再次執行腳本會再次新打開一個webdriver進程

(5)打印網頁源代碼

c.page_source

 (6)屏幕截圖操作

c.save_screenshot('1.png')#截圖,只支持PNG格式
c.get_screenshot_as_png() #獲取當前窗口的截圖作為二進制數據
c.get_screenshot_as_base64() #獲取當前窗口的截圖作為base64編碼的字符串 
driver.get_screenshot_as_file('1.png') #獲取當前窗口截圖保存在當前運行路徑下

 實操:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://baidu.com')
driver.save_screenshot('./test.png')

結果:

(7)前進后退刷新

c.forward() #前進
c.back()  #后退
c.refresh()#刷新

 (8)執行JS代碼

在Selenium中也可以自定義JS代碼並帶到當前頁面中去執行,如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
c
=webdriver.Chrome() c.get('https://www.baidu.com') kw1=c.find_element(By.ID,'kw') c.execute_script("alert('hello')") time.sleep(3) c.quit()
driver.execute_script('window.scrollTo(0,0)')  #滾動條到頂部

 

這里我使用一個JS中的函數來執行屏幕提示的功能,成功被執行。

(9)Cookies操作

c.get_cookie('BAIDUID') #獲取指定鍵的Cookies
c.get_cookies()         #獲取所有的Cookies
for y in c.get_cookies():
   x=y
   if x.get('expiry'):
       x.pop('expiry')     
   c.add_cookie(x) #添加Cookies  
c.delete_cookie('BAIDUID') #刪除指定鍵的Cookies內容
c.delete_all_cookies() #刪除所有cookies

(10)獲取瀏覽器窗口標題名稱

c.title

 (11)獲取當前瀏覽器名

c.name

 (12)全局超時時間

c.implicitly_wait(5)

 (13)鼠標懸停

——基於Actionchains類實現懸停,操作時,不要手動鼠標

el = driver.find_element('id','kw')
ActionChains(driver).move_to_element(el).perform()

(14)自定義瀏覽器窗口大小(一般不會使用,會影響性能,有可能會導致報錯)

driver.set_window_size(1500,800)#自定義設置窗口大小
driver.maximize_window() #窗口最大化
driver.get.window_size() #獲取當前窗口大小

(15)不自動關閉瀏覽器

option = webdriver.ChromeOptions()
option.add_experimental_option(
"detach",True) driver = webdriver.Chrome(chrome_options=option)

(二)元素操作

對我們找到的元素進行二次操作,不僅可以再次選擇子元素還可以進行其它操作。如下:

kw1.clear()        #清除元素的值(單元框、復選框也可用)
kw1.click()        #點擊元素(下拉框中,使用select類,只能用於select標簽,其他的用不了)
clickAndWait()     #點擊並等待
kw1.id             #Selenium所使用的內部ID
kw1.get_property('background') #獲取元素的屬性的值
kw1.get_attribute('id') #獲取元素的屬性的值
kw1.location       #不滾動獲取元素的坐標
kw1.location_once_scrolled_into_view  #不滾動且底部對齊並獲取元素的坐標
kw1.parent         #父元素
kw1.send_keys('')  #向元素內輸入值
kw1.size           #大小
kw1.submit         #提交
kw1.screenshot('2.png') #截取元素形狀並保存為圖片
kw1.tag_name       #標簽名
kw1.text           #內容,如果是表單元素則無法獲取
kw1.is_selected()  #判斷元素是否被選中
kw1.s_enabled()   #判斷元素是否可編輯
kw1.is_displayed   #判斷元素是否顯示
kw1.value_of_css_property('color') #獲取元素屬性的值
kw1._upload('2.png')             #上傳文件
kw1.send.keys(r'c:/圖片.jpg'#上傳文件(只能基於“input”標簽操作,非input標簽,需要用到autoIT庫)
  •  Select類操作

select = Select(driver_find_element('xpsth','//*[@id='kw']))
select.select_by_value(標簽會有一個value屬性,基於這個屬性進行選擇)
select.select_by_index(基於option的下標進行選擇)
select.select_by_visible_text(基於option的文本信息進行選擇)
  • 句柄操作

  1. selenium默認是聚焦在第一個頁面
  2. 在selenium體系中不同的標簽頁,被認定為不同的句柄,如果要切換頁面,本質上就是切換句柄,可以理解為每個頁面有id,我們切換到第二個id頁面
  3. 當你在測試執行中,需要操作新的標簽頁執行業務流程時,就需要切換句柄,在進行操作
  4. 切換原則:永遠是標簽頁最多保留2個,特殊情況最多是3個(因標簽頁名稱是被處理過密文,過多時或有刪除時不利於管理,)
handles = driver.window_handles #獲取到頁面所有句柄
driver.switch_to.window(handles[1]) #指定切換到第幾個句柄(0代表當前頁面,1是第二個頁面)
  • 根據屬性獲取頁面文案
element = driver.element('id','kw')  #定位到元素
data = element.get_attribute('innerText') #根據標簽屬性獲取到文案
  • 判斷CheckBox值是否勾選
driver.find_element('id','kw').is_selected()  #返回布爾值,勾選:True,不勾選:False 
  • 判斷頁面display隱藏欄是否顯示
driver.find_element('id','kw').is_displayed() #返回布爾值,顯示: True 不顯示: False
  • Selenium4

(1)相對定位器

——不太好用,比較出名,Selenium4新出的定位方法,依據人的習慣來定位(根據上下左右和附近五種方法定位,一般用於表單填寫會好點)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

driver = webdrive.Chrome()
driver.get('http://www.baidu.com')
el = driver.elment('id','kw')
#相對定位器,定位是有距離限制,是50px還是多少,具體參考官方文檔
driver.find_element(locate_with(By.TAG_NAME,'input').to_right_of(el)).click #點擊 id ='input' 右邊的元素
 
driver.find_element(locate_with(By.TAG_NAME,'input').to_left_of(el)).click #點擊 id ='input' 左邊的元素
 
driver.find_element(locate_with(By.TAG_NAME,'input').above(el)).click #點擊 id ='input' 上邊的元素
 
driver.find_element(locate_with(By.TAG_NAME,'input').above(el)).below #點擊 id ='input' 下邊的元素
 
driver.find_element(locate_with(By.TAG_NAME,'input').near(el)).click #點擊 id ='input' 附近的元素

 (2)頁面加載策略:normal/eager/none

from selenium import webdriver

chrome_options = webdriver.ChromeOptions()

#normar: 頁面正常加載模式,整個頁面全部加載完,會打開頁面的靜態文件,包括:css樣式、js函數等全部加載完,才會繼續執行
chrome_options.page_load_strategy = 'normal'

#eager: 會放棄加載頁面的“樣式”、“靜態資源”等,減少了一些不必要的加載,只會加載基本的html,其他的靜態資源不會加載了
chrome_options.page_load_strategy = 'eager'

#none: 只把初始頁面加載完就會操作
chrome_options.page_load_strategy = 'none'


driver = webdriver.Chrome(options=chrome_options)
try:
    driver.get("http://www.baidu.com")
finally:
    driver.quit()

(3)創建新的標簽頁和瀏覽器,創建新的標簽頁、瀏覽器之后,都會把句柄切換過去

#打開新的標簽頁
driver.switch_to.new_window('tab')

#打開新的瀏覽器頁
driver.switch_to.new_window('window')

(4)Selenium 4.0版本重大改變:

——selenium grid 4.0完全翻新了原有的自動化分布式部署實現的框架技術體系。

 • 3.0 版本:是基於MS形態實現的自動化測試框架部署

• 4.0 版本:原有基礎上新增event_bus、session queue等一系列內容,優化成了一個偏向於“分布式異步”形態處理的框架架構體系的自動化易用技術。

 • 分布式技術體系:如幾萬條自動化測試用例,可拆分成幾千條為一組,每幾千條為一組的放到一台機器上執行,同步開啟多台機器來執行,變成了不同組數的測試用例,在不同的電腦進行,原本要很多個小時執行完的,幾個小時甚至更快就可以執行完了。

(三)鍵盤鼠標操作

 1.模擬鍵盤輸入和按鍵

from selenium.webdriver.common.keys import Keys
c.find_element(By.ID,'kw').send_keys('python')#輸出Python
c.find_element(By.ID,'kw').send_keys(Keys.ENTER)#回車鍵
c.find_element(By.ID,'kw').click()#點擊

 這里列舉出了一個最簡單的鍵盤輸入和鼠標點擊的例子,不過我們在Selenium中可以使用更為高逼格的操作,那么是什么了?當然是咱們的鼠標鍵盤監聽事件來觸發事件啦,而且它里面的方法的確也很多樣化,滿足小編日常的騷操作不在話下,如下所示:

click(on_element=None)                 #鼠標左鍵單擊
click_and_hold(on_element=None)        #單擊鼠標左鍵,不松開
context_click(on_element=None)         #單擊鼠標右鍵
double_click(on_element=None)          #雙擊鼠標左鍵
drag_and_drop(source,target)           #拖拽到某個元素然后松開
drag_and_drop_by_offset(source,xoffset,yoffset) #拖拽到某個坐標然后松開
key_down(value,element=None)     #按下鍵盤上的某個鍵
key_up(value, element=None)      #松開鍵盤上的某個鍵
move_by_offset(xoffset, yoffset)  #鼠標從當前位置移動到某個坐標
move_to_element(to_element)        #鼠標移動到某個元素
move_to_element_with_offset(to_element, xoffset, yoffset) #移動到距某個元素(左上角坐標)多少距離的位置
pause(seconds)                  #暫停所有輸入(指定持續時間以秒為單位)
perform()                       #執行所有操作
reset_actions()                 #結束已經存在的操作並重置
release(on_element=None)       #在某個元素位置松開鼠標左鍵
send_keys(*keys_to_send)        #發送某個鍵或者輸入文本到當前焦點的元素
send_keys_to_element(element, *keys_to_send) #發送某個鍵到指定元素

 以上就是咱們鼠標和鍵盤的全部操作了,小編將用一個例子帶大家零基礎入門。如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
c=webdriver.Chrome()
c.get('https://www.baidu.com')
a=ActionChains(c)
kw1=c.find_element(By.ID,'kw')
tj=c.find_element(By.ID,'su')
tj.send_keys(Keys.CONTROL,'c') #復制
a.drag_and_drop(kw1,tj).perform()#從輸入框拖動到搜索按鈕
kw1.send_keys(Keys.CONTROL,'v')#粘貼
tj.send_keys(Keys.ENTER)
time.sleep(3)
c.close()
c.quit()

 這里我們通過對事件的監控,進行復制和粘貼,這里涉及到一個組合鍵的知識,大家注意。

 (四)、選項操作

我們可以通過給當前操作的對象一些選項來增強交互能力,如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.chrome.options import Options
o=Options()
o.add_argument('--headless')#無界面瀏覽
c=webdriver.Chrome(executable_path=r'C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe',chrome_options=o)
c.get('https://www.baidu.com')
kw1=c.find_element(By.ID,'kw')
print(c.title)
time.sleep(3)
c.close()
c.quit()

 這個時候就實現了咱們的無界面瀏覽了,也就是不用打開瀏覽器即可自動返回執行的結果。不過你可別以為選項就那么一兩個,那可是多到你懷疑人生的,例如:

o.add_argument('--window-size=600,600') #設置窗口大小
o.add_argument('--incognito') #無痕模式
o.add_argument('--disable-infobars') #去掉chrome正受到自動測試軟件的控制的提示
o.add_argument('user-agent="XXXX"') #添加請求頭
o.add_argument("--proxy-server=http://200.130.123.43:3456")#代理服務器訪問
o.add_experimental_option('excludeSwitches', ['enable-automation'])#開發者模式
o.add_experimental_option("prefs",{"profile.managed_default_content_settings.images": 2})#禁止加載圖片
o.add_experimental_option('prefs',
{'profile.default_content_setting_values':{'notifications':2}}) #禁用瀏覽器彈窗
o.add_argument('blink-settings=imagesEnabled=false')  #禁止加載圖片
o.add_argument('lang=zh_CN.UTF-8') #設置默認編碼為utf-8
o.add_extension(create_proxyauth_extension(
           proxy_host='host',
           proxy_port='port',
           proxy_username="username",
           proxy_password="password"
       ))# 設置有賬號密碼的代理
o.add_argument('--disable-gpu')  # 這個屬性可以規避谷歌的部分bug
o.add_argument('--disable-javascript')  # 禁用javascript
o.add_argument('--hide-scrollbars')  # 隱藏滾動條
o.binary_location=r"C:\Users\Administrator\AppData\Local\Google\Chrome\Application" #指定瀏覽器位置
o.add_argument('--no-sandbox')  #解決DevToolsActivePort文件不存在的報錯

 其實選項的添加無非就是分為以下這幾種,如下:

o.set_headless()          #設置啟動無界面化
o.binary_location(value)  #設置chrome二進制文件位置
o.add_argument(arg)               #添加啟動參數
o.add_extension(path)                #添加指定路徑下的擴展應用
o.add_encoded_extension(base64)      #添加經過Base64編碼的擴展應用
o.add_experimental_option(name,value)         #添加實驗性質的選項
o.debugger_address(value)                #設置調試器地址 
o.to_capabilities()                    #獲取當前瀏覽器的所有信息 

 雖然選項很多,但是我們真正能用到的不多,一般就是無痕模式或者禁用JavaScript和圖片來快速獲取到相關信息。雖然我們上面使用的是Options方法,但是在實際應用中建議大家使用的ChromeOptions方法。

(五)、框架操作(Frame/IFrame)

我們還可以操作框架里的東西,比如IFrame,Frame等等,雖然都是框架,但是這兩者操作起來還是有很大差別的。下面我們就來看看吧,如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
c=webdriver.Chrome(executable_path=r'C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe')
c.implicitly_wait(10)
c.get('https://hao.360.com/?a1004')
#ss=c.find_element(By.CLASS_NAME,'NEWS_FEED_VIDEO_1595850774217HPA70')#不容易找到標簽
c.switch_to.frame(0)#索引
c.switch_to.frame('NEWS_FEED_VIDEO_1595850774217HPA70-VideoIframe') #ID
c.switch_to.frame('NEWS_FEED_VIDEO_1595850774217HPA70')#Class
c.switch_to.frame(c.find_element_by_tag_name("iframe"))#標簽
time.sleep(3)
c.close()
c.quit()

這里小編是以360瀏覽器的主頁為例子,對它里面的IFrame進行訪問,最有效的方法一般就是我上面提到的四種了。這里我們有時候因為這個框架需要加載才可以出來,所以很多時候是無法獲取到的,因此我們只有使用滑動加載到出現這個標簽或者ID,Class為可以獲取到,這在剛才小編是說了的,大家可以往前看看,不過這個方法不推薦使用,為啥?因為開發者文檔上是這樣寫的。我們的Frame由於是IFrame里的子集,所以上面的方法便是可以層層遍歷的好方法,但是如果我們遍歷到最后了如何返回主框架了,可以這樣做,如下所示:

c.switch_to.default_content()

這樣就可以回到主框架繼續進行操作了。如果我們由里往外遍歷的話,那么可以這樣來做,如下:

c.switch_to.parent_frame()
#iframe,當你遇到方法用盡還是定位不到元素,檢查下是否有iframe

driver.swith_to.frame(id/name/webElement) #定位方法

#iframe操作完成后,需要切換回默認窗體

driver.switch_to.default.content()

(六)、Alert

在彈窗處理中,我們會遇到三種情況,如下:

瀏覽器彈出框
新窗口彈出框
人為彈出框

那么我們該怎么分辨了?下面跟我一起看看吧。

1.瀏覽器彈出框

首先說說瀏覽器彈出框,想必大家對JavaScript中的Alert,Confirm,Prompt應該不是很陌生,就是彈出框,確認框,輸入框;基本方法我們來看下,如下:

from selenium.webdriver.common.alert import Alert
c=webdriver.Chrome(executable_path=r'C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe')
c.implicitly_wait(10)
c.get('https://www.baidu.com')
a1=Alert(c)
a1.accept() #確定
a1.dismiss() #取消
a1.authenticate(username,password) #用戶身份驗證
a1.send_keys('') #輸入文本或按鍵
a1.text  #獲取彈窗內容

 這里我們應對每種情況它上面的方法的對應位置都是會有所變化的,所以我們需要根據具體情況來進行操作,而且還可以使用另一種方法,如下:

c=webdriver.Chrome(executable_path=r'C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe')
c.implicitly_wait(10)
c.get('https://www.baidu.com')
a1=c.switch_to_alert()
a1.accept() #確定
a1.dismiss() #取消
a1.authenticate(username,password) #用戶身份驗證
a1.send_keys('') #輸入文本或按鍵
a1.text  #獲取彈窗內容

 注:該類方法必須在有彈框的情況下才有作用,如沒有會報錯。

2.新窗口彈出框

上面就是瀏覽器彈出框的處理方法了,如果是新窗口彈出的話那么就不一樣了,我們需要通過句柄來定位,前面我們提到過這兩個方法。下面我們來看看它們的具體用法,如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
c=webdriver.Chrome(executable_path=r'C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe')
c.implicitly_wait(10)
c.get('https://www.baidu.com')
kw1=c.find_element(By.ID,'kw')
tj=c.find_element(By.ID,'su')
hwnd=c.window_handles #所有窗口句柄
for h in hwnd:
   if h !=c.current_window_handle:  #如果句柄不是當前窗口句柄則切換                          c.switch_to_window(h)  #切換窗口
   else:
       print('無需切換窗口') 
time.sleep(3)
c.close()
c.quit()

 注:如果有多個窗口,當你關閉了當前窗口想切換到另一個窗口,你需要把沒關閉的窗口切換成當前活動窗口,因為Selenium是不會為你做這件事的。

3.人為彈出框

這類彈出框是我們自己開發的,一般都是使用Div包裹一些其它的元素標簽然后形成一個整體,當我們觸發某個事件的時候就會出現,否則消失。這種彈出框使用我們的眾多Find前綴的方法就能遍歷到,很方便,這里不一一細說。

(七)、判斷

在Selenium中我們在做自動化測試時常無法判斷一個元素是否真的顯示出來了,因此會各種報錯,接下來我們對這些操作進行判斷,如果顯示出了我們預期的值,那么就進行下一步操作,否則就關閉或者暫停幾秒然后再判斷,這里我要跟大家說Selenium中的一個模塊-----Expected_Conditions,簡稱為EC,如下所示:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time
c=webdriver.Chrome()
c.implicitly_wait(10)
c.get('https://baidu.com')
t=EC.title_is('百度一下,你就知道')
print(t(c))
time.sleep(3)
c.close()
c.quit()

 這里其實就是判斷當前頁面的標題是否是我們給定的文本,可以看出這里為True,說明是。它不光就一個方法哦,還有其它的,小編在這里大致說下,如下所示:

EC.title_contains('')(c)#判斷頁面標題是否包含給定的字符串
EC.presence_of_element_located('')(c) #判斷某個元素是否加載到dom樹里,該元素不一定可見
EC.url_contains('')(c) #判斷當前url是否包含給定的字符串
EC.url_matches('')(c) #匹配URL
EC.url_to_be('')(c)  #精確匹配
EC.url_changes('')(c) #不完全匹配
EC.visibility_of_element_located('')(c) #判斷某個元素是否可見,可見代表元素非隱藏元素
EC.visibility_of('')(c)   #跟上面一樣,不過是直接傳定位到的element
EC.presence_of_all_elements_located('')(c) #判斷是否至少有1個元素存在於dom樹中
EC.visibility_of_any_elements_located('')(c) #判斷是否至少一個元素可見,返回列表
EC.visibility_of_all_elements_located('')(c) #判斷是否所有元素可見,返回列表
EC.text_to_be_present_in_element('')(c) #判斷元素中的text是否包含了預期的字符串
EC.text_to_be_present_in_element_value('')(c)#判斷元素中value屬性是否包含預期的字符串
EC.frame_to_be_available_and_switch_to_it('')(c) # 判斷該frame是否可以switch進去
EC.invisibility_of_element_located('')(c) #判斷某個元素是否不存在於dom樹或不可見
EC.element_to_be_clickable('')(c) #判斷某個元素中是否可見並且可點擊
EC.staleness_of('')(c)  #等某個元素從dom樹中移除
EC.element_to_be_selected('')(c)  #判斷某個元素是否被選中了,一般用在下拉列表
EC.element_located_to_be_selected('')(c) #判斷元組中的元素是否被選中
EC.element_selection_state_to_be('')(c) #判斷某個元素的選中狀態是否符合預期
EC.element_located_selection_state_to_be('')(c) #跟上面一樣,只不過是傳入located
EC.number_of_windows_to_be('')(c)  #判斷窗口中的數字是否符合預期
EC.new_window_is_opened('')(c)  #判斷新的窗口是否打開
EC.alert_is_present('')(c)  #判斷頁面上是否存在alert

 這就是它全部的方法了,簡直不要多簡單。

(八)、選擇

剛剛講過判斷,現在我們來說說選擇,選擇無非就是挑好的扔爛的,順着思路來不會錯,總體來講還是挺簡單的,如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
import time
c=webdriver.Chrome()
c.implicitly_wait(10)
c.get('http://www.juliwz.cn/forum.php')
s=Select(c.find_element_by_id('ls_fastloginfield'))#實例化
res=s.all_selected_options#全部選中子項
res1=s.options#全部子項
print(res)
print(res1)
time.sleep(3)
c.close()
c.quit()

發覺主流網站都沒有Select這個標簽,於是找了個很冷門的網站,就一個Select。Select里面的方法也是相當多的,如下:

s.first_selected_option  #第一個選中的子項
s.select_by_index(index) #根據索引選擇
s.select_by_value(value)   #根據值來選擇
s.select_by_visible_text(text)  #根據選項可見文本
s.deselect_by_index(index)   #根據索引來取消選擇
s.deselect_by_value(value)   #根據值來取消選擇
s.deselect_by_visible_text(text)  #根據可見文本來取消選擇
s.deselect_all()                #取消所有選擇

 (九)、顯示等待和隱式等待

 想必大家應該聽過這個概念,顯示等待就是瀏覽器在我們設置的時間內不斷尋找,等到元素后才繼續執行,如果沒在規定時間內找到,也會拋異常;而隱式等待則是我們設置時間,然后程序去找元素,期間會不斷刷新頁面,到了時間仍然沒找到就拋異常。這里有個常用的模塊專門用來實現顯示等待和隱式等待的,它就是”wait“,我們來看看吧。如下:

from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
c=webdriver.Chrome()
c.get('https://www.baidu.com/')
su=WebDriverWait(c,10).until(lambda x:x.find_element_by_id('su')) 
su.location_once_scrolled_into_view
print(su.get_attribute('value'))
time.sleep(3)
c.close()
c.quit()

隱式等待很簡單,就一行代碼,如下:

c.implicitly_wait(10)

它的等待時間適用於全局的環境,也就是任何地方找不到某個元素,它都將發揮作用,如果找得到,則不會產生作用。

(十)斷言

斷言assertion:

驗證應用程序的狀態是否同所期望的一致。

常見的斷言包括:驗證頁面內容,如標題是否為X或當前位置是否正確,或是驗證該復選框是否被勾選。

selenium 提供了三種模式的斷言:assert 、verify、waitfor

  • Assert 失敗時,該測試將終止。
  • Verify 失敗時,該測試將繼續執行,並將錯誤記入日顯示屏 。也就是說允許此單個 驗證通過。確保應用程序在正確的頁面上
  • Waitfor 用於等待某些條件變為真。可用於 AJAX 應用程序的測試。

 如果該條件為真,他們將立即成功執行。如果該條件不為真,則將失敗並暫停測試。直到超過當前所設定的超過時間。一般跟setTimeout時間一起使用

assertLocation(判斷當前是在正確的頁面)、

assertTitle(檢查當前頁面的 title 是否正確)、
assertValue(檢查 input 的值, checkbox 或 radio,有值為”on”無為”off”)、
assertSelected(檢查 select 的下拉菜單中選中是否正確)、
assertSelectedOptions(檢查下拉菜單中的選項的是否正確)、
assertText(檢查指定元素的文本)、
assertTextPresent(檢查在當前給用戶顯示的頁面上是否有出現指定的文本)、
assertTextNotPresent(檢查在當前給用戶顯示的頁面上是否沒有出現指定的文本)、
assertAttribute(檢查當前指定元素的屬性的值)、
assertTable(檢查 table 里的某個 cell 中的值)、
assertEditable(檢查指定的 input 是否可以編輯)、

assertNotEditable(檢查指定的 input 是否不可以編輯)、
assertAlert(檢查是否有產生帶指定 message 的 alert 對話框)、
verifyTitle (檢查預期的頁面標題)
verifyTextPresent (驗證預期的文本是否在頁面上的某個位置)
verifyElementPresent(驗證預期的UI元素,它的HTML標簽的定義,是否在當前網頁上)
verifyText(核實預期的文本和相應的HTML標簽是否都存在於頁面上)
verifyTable(驗證表的預期內容)
waitForPageToLoad(暫停執行,直到預期的新的頁面加載)
waitForElementPresent (等待檢驗某元素的存在。為真時,則執行。)

驗證和斷言的區別:驗證失敗后不影響腳本的繼續執行,斷言失敗后將停止腳本的執行。

異常類型
AssertionError:assert語句失敗

AttributeError:試圖訪問一個對象沒有的屬性

IOError:輸入輸出異常,基本是無法打開文件

ImportError:無法引入模塊或者包,基本是路徑問題

IndentationError:語法錯誤,代碼沒有正確的對齊

IndexError:下標索引超出序列邊界

KeyError:試圖訪問字典里不存在的鍵

KeyboadrInterrupt:Ctrl+c被按下

NameError:使用一個還未賦值對象的變量

SyntaxError:python代碼邏輯語法錯誤,不能執行

TypeError:傳入的對象類型與要求不符

UnboundLocalError:試圖訪問一個還未設置的全局變量,基本上是由於另有一個同名的全局變量,導致你以為在訪問

ValueError:傳入一個不被期望的值,即使類型正確

(十一)、總結

Selenium的內容其實還是挺豐富的,它還有手機端的自動化測試框架,不過小編先把WEB端講完就可以了,畢竟也寫了這么多了,日后有時間再慢慢了解。大家如果是對觸摸活動事件感興趣的也可以看看“touch_actions"這個模塊。這個模塊里集成的都是關於觸摸屏的操作,里面也有很多的方法,小編之所以能把Selenium一天學完,還是Selenium模塊中的文檔比較給力,主要是介紹的比較好,讓人能輕松聯想到方法的使用,感激開源作者的無私奉獻。

 


 


免責聲明!

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



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