一雷则、windows下安裝及環(huán)境配置
- Python安裝月劈,本文中安裝的是2.x版本藤乙。去下載
- 配置環(huán)境變量:我的電腦-屬性-高級系統(tǒng)設置-環(huán)境變量惭墓,將以下變量加入Path中
C:\Python27;C:\Python27\Scripts
- 檢查python是否正確安裝和配置:
Win+R輸入cmd或powershell,命令行輸入“python”檢查划咐,出現(xiàn)Python 2.7.x...等字樣表示安裝配置完成 - 安裝selenium:使用pip命令(最新版python 2.7或3.6都默認帶有pip)吭狡,命令行輸入以下命令即可
pip install selenium
- 下載webdriver划煮,解壓后放在path環(huán)境變量的路徑下缔俄,或者與python腳本放在同一文件夾下
Chrome驅動,各版本的文件夾中notes.txt標注了支持的Chrome版本蟹略,根據(jù)自己安裝的Chrome版本選擇即可
Firefox驅動遏佣,直接下載最新版本使用
Edge驅動
Safari驅動
二、知識儲備
- html+css基礎
- javascript基礎意敛,需要在腳本中執(zhí)行js
- python基礎膛虫,以及unittest框架
三稍刀、簡介
最基礎的用法如下:
from selenium import webdriver #導入webdriver
driver = webdriver.Firefox() #創(chuàng)建實例并打開瀏覽器,此處為Firefox
driver.get("www.google.com") #get(url)方法打開指定URL
assert “Google” in driver.title #斷言檢測頁面title是否為期望值
driver.close() #關閉當前瀏覽器窗口
driver.quit() #關閉瀏覽器并退出webdriver
利用unittest的test suite方式:
1综膀、針對待測事物寫test case局齿,繼承TestCase類,定義test_xxx方法
2担平、在各test代碼后面構造測試集,并調用runner執(zhí)行測試面褐,如:
if __name__ == "__main__":
suite = unittest.TestSuite()
suite.addTest(test_xxx())
...
runner = unittest.TextTestRunner()
runner.run(suite)
3取胎、創(chuàng)建一個執(zhí)行所有用例的文件,例如:
import unittest
import testCaseA, testCaseB...
suite = unittest.TestSuite()
suite.addTest(testCaseA.testXxx())
suite.addTest(testCaseB.testXxx())
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite)
四闻蛀、元素的定位
1.基礎定位方式有如下幾種:
- find_element_by_id —— 通過id定位
- find_element_by_name —— 通過name定位
- find_element_by_class_name —— 通過class name定位
- find_element_by_link_text —— 通過link text定位
- find_element_by_partial_link_text —— 通過匹配部分link text定位
- find_element_by_tag name —— 通過tag name定位
- find_element_by_xpath —— 通過xpath定位
- find_element_by_css selector —— 通過CSS選擇器定位,推薦
2.定位元素組
使用find_elements_by_xxx方法役衡,常用于批量操作對象薪棒,如勾選所有checkbox,例:
# 選擇所有的checkbox并全部勾上
checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
for checkbox in checkboxes:
checkbox.click()
# 選擇頁面上所有的input棵介,然后從中過濾出所有的checkbox并勾選之
inputs = dr.find_elements_by_tag_name('input')
for input in inputs:
if input.get_attribute('type') == 'checkbox':
input.click()
# 把頁面上最后1個checkbox的勾給去掉
dr.find_elements_by_css_selector('input[type=checkbox]').pop().click()
3.層級定位
層級定位:實際項目中有很多個屬性基本相同的元素邮辽,需要具體定位到其中的一個贸营,這時需要先定位父元素,然后再定位到子孫元素锐极,如:find_element_by_id('parent').find_element_by_id('child')
4.button group按鈕組
定位思路是先找到button group的div芳肌,然后通過層級定位,用index或者屬性去定位具體的按鈕翎迁,例:
# 定位text是second的按鈕
buttons = dr.find_element_by_class_name('btn-group').find_elements_by_class_name('btn')
for btn in buttons:
if btn.text == 'second': print 'find second button'
5.button dropdown
button dropdown按鈕把按鈕和下拉菜單放在一起净薛,處理思路是先點擊這個按鈕肃拜,等待下拉菜單顯示后雌团,通過層級定位獲取下拉菜單中的選項士聪,例:
#點擊下拉菜單
dr.find_element_by_link_text('Info').click()
#找到dropdown-menu父元素
WebDriverWait(dr,10).until(lambda the_driver: the_driver.find_element_by_class_name('dropdown-menu').is_displayed())
#找到better than
menu = dr.find_element_by_class_name('dropdown-menu').find_element_by_link_text('better than')
6.navs
navs用于簡單的tab導航欄剥悟,通常先定位ul再層級定位到li即可,或者直接根據(jù)link_text定位
7.面包屑
面包屑一般來說當前層級都沒有鏈接区岗,而副層級基本是鏈接慈缔,所以思路基本上是:先找到面包屑所在div或ul,再找到其下所有鏈接颅拦,這些鏈接就是父層級教藻,最后不是鏈接的就是當前層級了
8.分頁
一般分頁需要知道的是:總共的頁數(shù)右锨,當前頁數(shù),是否可以上下翻頁悄窃,或者直接跳轉
分頁通常使用ul來實現(xiàn)蹂窖,當前頁一般是沒有鏈接的瞬测,通過class name = active定位,其它2個信息按頁面情況獲取
四月趟、元素的操作:
1.獲取對象的屬性及內容
通過webdriver的element.attribute()方法獲取dom元素屬性
獲取css屬性:element.value_of_css_property()
2.獲取對象的狀態(tài)
通常需要獲取對象的四種狀態(tài):
- 是否顯示——使用element.is_displayed()
- 是否存在——使用find_element_by_xxx方法孝宗,捕獲拋出的一場,如果存在異常則不存在
- 是否被選中——一般是判斷表單元素是否被選中问潭,如radio或checkbox,通過element.is_selected()方法
- 是否enable——使用element.is_enabled()
3.一些基本的操作
- click() 點擊對象
- send_keys() 在對象上模擬按鍵輸入或往文本框賦值(需要
form selenium.webdrive.common.keys import Keys
) - clear() 清除對象內容
- submit() 用于提交表單两芳,特別用于沒有提交按鈕的情況去枷,比如搜索框輸入關鍵字后按回車搜索的(也可以通過模擬回車鍵來實現(xiàn))
4.執(zhí)行js
通常需要在頁面上或者定位的元素上執(zhí)行js删顶,而webdriver就提供了execute_script()接口來執(zhí)行js
js = "some javascripts"
driver.execute_script(js)
5.等待
在頁面進行操作致使一些元素隱藏或出現(xiàn)時,或者等待ajax執(zhí)行完成時特咆,需要用到WebDriverWait的until方法等待(顯式等待)录粱,需要用到的是selenium.webdriver.support.ui.WebDriverWait類,until方法會一直等下去菜职,直到
- 代碼塊中的內容為true(不為false或沒有拋出異常)
- 超時旗闽,即超過timeout設定的時間
例如等待直到某元素顯示
wait = selenium.webdriver.support.ui.WebDriverWait(driver, 10)
wait.until(lambda driver: driver.element.isdisplayed()) #lambda為Python創(chuàng)建匿名函數(shù)的關鍵字
隱式等待适室,是指通過一定的時長等待頁面所有元素加載完成,如果超出了設置的時長而元素還沒有被加載則拋出NoSuchElementException異常蔬螟。WebDriver提供了implicitly_wait()方法來實現(xiàn)隱式等待汽畴,默認設置為0.
6.復雜的操作
1. ActionChains模擬鼠標操作
- perform() 執(zhí)行所有ActionChains中存儲的行為
- context_click() 右擊
- double_click() 雙擊
- drag_and_drop() 拖動
- move_to_element() 鼠標懸停
2.frame切換
頁面嵌套frame時整袁,若要定位frame中的元素,需要通過switch_to_frame(id/name)方法先將定位主體切換到frame里绳匀。
如果iframe沒有id或name可以定位,則先通過其它方式先定位到frame疾棵,再將定位對象傳給switch_to_frame()方法是尔。
如果完成了在當前frame上的操作,可以通過switch_to_default_content()方法返回上一層表單薪铜。
3.多窗口切換
通過switch_to_window()方法切換到任意窗口恩溅。
current_window_handle——獲得當前窗口句柄
window_handles——返回所有窗口的句柄到當前會話
switch_to_window(handle)——根據(jù)給的句柄切換到相應窗口
4.警告框處理
處理JS生成的alert、confirm以及prompt做法是通過switch_to_alert()方法定位到alert/confirm/prompt蜒滩,然后使用text/accept/dismiss/send_keys執(zhí)行對應操作
- text 返回提示框中的文字信息
- accept 點擊確認按鈕
- dismiss 點擊取消按鈕(當存在取消按鈕時可用)
- send_keys 輸入值(僅prompt可用)
5.文件上傳
- 對于用過input標簽實現(xiàn)的上傳俯艰,可以將其看作一個輸入框锌订,通過send_keys()傳入本地文件路徑從而模擬上傳功能。
- 借助Autolt實現(xiàn)上傳涩搓。首先通過AutoIt寫好腳本并轉換成exe可執(zhí)行文件劈猪,然后在python中良拼,打開上傳文件對話框庸推,再調用os.system('xxx.exe')運行exe來實現(xiàn)上傳。
6.文件下載
- 通過編輯配置文件將文件下載到默認路徑
- 通過AutoIt腳本實現(xiàn)
7.操作cookie
- get_cookies() 獲得所有cookie信息
- get_cookie(name) 返回有特定name值得cookie信息
- add_cookie(cookie_dict) 添加cookie聋亡,必須有name和value值
- delete_cookie(name) 刪除特定部分的cookie信息
- delete_all_cookies() 刪除所有的cookie信息
8.窗口截圖
webdriver提供了截圖函數(shù)get_screenshot_as_file()來截取當前窗口
五际乘、遇到的一些坑
- 使用Chrome,登陸后總是彈出記住密碼提示框——解決辦法:打開Chrome時設置option選項:
options = webdriver.ChromeOptions()
prefs = {"":""}
prefs["credentials_enable_service"] = False
prefs["profile.password_manager_enable"] = False
options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options = options)
根據(jù)關鍵詞搜索結果的斷言罪塔,思路是
獲取搜索結果集征堪,遍歷判斷對應列的text是否包含關鍵詞,包含則count++庸娱,最后判斷count與搜索結果總數(shù)是否相等(這個想法太蠢了谐算,用循環(huán)遍歷每個搜索結果,并assert判斷是否等于或包含臣樱,一個用例可以包含多個斷言的腮考,每個斷言是并行的,所有assert都通過棚放,結果才是通過的)
問題一:搜索結果較多馅闽,分頁怎么獲取正確數(shù)量遇到一個案例,瀏覽器點擊當前頁面A元素局骤,打開了新的標簽頁B之后暴凑,實際的window句柄還是在當前A頁面,而我想當然以為是新標簽頁B凯傲,然后定位B中的元素發(fā)現(xiàn)死都找不到嗦篱。。诫欠。所以如果有打開新的頁面,還是需要通過switch_to.window(handler)切換到新的頁面