柚子快報(bào)激活碼778899分享:UI自動(dòng)化-Selenium
柚子快報(bào)激活碼778899分享:UI自動(dòng)化-Selenium
目錄
前言
只需安裝兩個(gè)庫
瀏覽器和驅(qū)動(dòng)
瀏覽器操作
定位元素
八大定位
特殊元素定位
① select下拉框定位及相關(guān)操作
② 彈窗定位及相關(guān)操作
③ iframe內(nèi)嵌框架定位及相關(guān)操作
④ 文件的上傳下載
上傳
絕對(duì)路徑上傳
相對(duì)路徑上傳
下載
firefox下載
chrome下載
元素操作
鼠標(biāo)&鍵盤事件
鼠標(biāo)操作
鍵盤操作
三大等待
文本驗(yàn)證碼識(shí)別
截屏
前言
我一直很喜歡它, 但總覺得用不上, 感覺它很沒用..., 因?yàn)樗催@個(gè)電腦本地的網(wǎng)速、瀏覽器、配置等等各種環(huán)境吧, 我一直覺得它很慢, 用起來很不爽, 體驗(yàn)比較差, 等待的時(shí)間還不如我直接去手動(dòng)操作?
只需安裝兩個(gè)庫
pip3 install selenium
pip3 install webdriver-manager
瀏覽器和驅(qū)動(dòng)
BB:
我可能是寫自己的記錄, 也想把自己當(dāng)時(shí)的想法寫出來, 所以經(jīng)常多BB兩句, 就當(dāng)是講故事了, 給以后的自己看也行:? 一開始呢做的WEB自動(dòng)化都用chrome、firefox瀏覽器, 這兩個(gè)瀏覽器我好奇到底都是誰在用? chrome還偶爾見, 火狐根本沒見過......?常見的都是些什么360、夸克、2345、QQ等瀏覽器, 不過那些瀏覽器都套chrome的內(nèi)核, 所以才自動(dòng)化都用chrome吧?? 我個(gè)人不喜歡chrome界面, 平時(shí)用Edge較多, 也省的下載了
瀏覽器驅(qū)動(dòng):
在Selenium4.0之前, 想要控制什么瀏覽器, 都得去找對(duì)應(yīng)瀏覽器版本的驅(qū)動(dòng), 算是比較麻煩, 現(xiàn)在方便了, 多安裝一個(gè)webdriver_manager的庫, 就可以自動(dòng)下載對(duì)應(yīng)的驅(qū)動(dòng)
# 導(dǎo)入selenium的web驅(qū)動(dòng)
from selenium import webdriver
# 導(dǎo)入selenium的chrome服務(wù)
from selenium.webdriver.chrome.service import Service
# 導(dǎo)入驅(qū)動(dòng)管理的chrome管理
from webdriver_manager.chrome import ChromeDriverManager
# 獲取chrome驅(qū)動(dòng)
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
"""
寫了這么多遍老是記不住, 我人麻了, 主要每次都不是自己手動(dòng)寫的
要么是直接復(fù)制改一下名字, 要么是編輯器快捷輸入....
官網(wǎng)是這么說的, 牛B的可以了解了解...
https://www.selenium.dev/documentation/selenium_manager/
大概就是說: 升級(jí)到selenium4之后, 可以用webdriver_manager直接下載對(duì)應(yīng)瀏覽器驅(qū)動(dòng),
避免了版本不同驅(qū)動(dòng)不兼容問題
Edge的話不一樣, 說selenium4自帶edge驅(qū)動(dòng)工具等等可以直接用, 所以我更喜歡用Edge..
參考地址: https://learn.microsoft.com/zh-cn/microsoft-edge/webdriver-chromium/?tabs=python
不過親測(cè): selenium4.0.0版本不支持, 盡量還是保持最新版本吧
"""
"""
更多瀏覽器例子看別人文章,
https://blog.csdn.net/weixin_47754149/article/details/128502965
"""
也附上一些下載地址吧, 可能用得上
1. chrome舊驅(qū)動(dòng) ? ??chrome新驅(qū)動(dòng)和瀏覽器 - 正式版、測(cè)試版、開發(fā)版
2. 火狐驅(qū)動(dòng)
瀏覽器操作
① webdriver內(nèi)置方法
from selenium import webdriver
from time import sleep
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開網(wǎng)址
driver.get("https://www.baidu.com")
sleep(2)
# 打開網(wǎng)址2
driver.get("https://cn.bing.com/")
sleep(2)
# 退回一個(gè)頁面
driver.back()
sleep(2)
# 前進(jìn)一個(gè)頁面
driver.forward()
sleep(2)
# 刷新頁面
driver.refresh()
sleep(2)
# 全屏
driver.fullscreen_window()
sleep(2)
# 最小化窗口
driver.minimize_window()
sleep(2)
# 最大化窗口
driver.maximize_window()
sleep(2)
# 獲取瀏覽器窗口大小
size = driver.get_window_size()
print("瀏覽器窗口大小: ",size)
sleep(2)
# 設(shè)置瀏覽器窗口大小
driver.set_window_size(1700,1000)
sleep(2)
# 獲取瀏覽器窗口位置
position = driver.get_window_position()
print("瀏覽器默認(rèn)位置",position)
# 設(shè)置瀏覽器窗口位置
driver.set_window_position(480,270)
sleep(2)
# 獲取當(dāng)前頁面的title
title = driver.title
print("當(dāng)前頁面的title",title)
# 獲取當(dāng)前URL
current_url = driver.current_url
print("當(dāng)前的當(dāng)前URL",current_url)
# 當(dāng)前頁面的源碼....
is_page_source = driver.page_source
# 進(jìn)入使用click()點(diǎn)擊超鏈接元素打開一個(gè)網(wǎng)址
driver.find_element("css selector","#trending_now_tile > li:nth-child(1) > a > span > img").click()
sleep(2)
# 生成所有句柄, 句柄可以理解為當(dāng)前所有已打開的網(wǎng)址
n = driver.window_handles
# 切換到當(dāng)前最新打開的網(wǎng)頁
driver.switch_to.window(n[-1])
# 關(guān)閉當(dāng)前窗口
driver.close()
sleep(2)
"""
還有一個(gè)是send_keys(str), 作用是定位到input輸入框之后,可以在里面輸入內(nèi)容
"""
#退出瀏覽器
driver.quit()
② 操作滾動(dòng)條
操作內(nèi)嵌iframe框架里的滾動(dòng)條 or?整個(gè)窗口的滾動(dòng)條
from time import sleep
from selenium import webdriver
# 獲取谷歌驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開網(wǎng)址
driver.get("http://sahitest.com/demo/iframesTest.htm")
# 隱式等待
driver.implicitly_wait(10)
# 進(jìn)入第一個(gè)內(nèi)嵌iframe
driver.switch_to.frame(0)
# 強(qiáng)制等待
sleep(2)
# 編寫js腳本滑動(dòng)向下和右200px
down_rit200 = "window.scrollTo(200,200)"
# 執(zhí)行腳本
driver.execute_script(down_rit200)
# 強(qiáng)制等待
sleep(2)
# 向上和左滑動(dòng)
up_lft200 = "window.scrollTo(-200,-200)"
driver.execute_script(up_lft200)
# 強(qiáng)制等待
sleep(2)
# 退出iframe
driver.switch_to.default_content()
"""
還有其他腳本定位方式, 喜歡哪個(gè)用哪個(gè), 我選簡(jiǎn)單的..
# 上下左右
down200 = "document.documentElement.scrollTop=200"
up200 = "document.documentElement.scrollTop=-200"
right200 = "document.documentElement.scrollLeft=200"
left200 = "document.documentElement.scrollLeft=-200"
"""
操作元素上的滾動(dòng)條,比如div的滾動(dòng)條, 懶得寫, 放個(gè)圖片吧
定位元素
八大定位
此處用百度首頁舉例, 定位百度首頁的'百度一下'按鈕
①使用ID定位
from selenium import webdriver
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開網(wǎng)址
driver.get("https://www.baidu.com")
# id定位
driver.find_element("id","su")
②使用xpath定位
# 根據(jù)元素屬性值定位
driver.find_element("xpath", "http://input[@id='su']")
# 根據(jù)元素文本值, 定位百度首頁的 '新聞'
driver.find_element("xpath", "http://a[text()='新聞']")
③使用link text定位, 這個(gè)只能定位帶文本的超鏈接元素
# 定位百度首頁的'新聞'鏈接
driver.find_element("link text", "新聞")
④使用partial link text定位, 這個(gè)可以模糊定位帶文本的超鏈接元素,
# 定位百度首頁的 hao123 文本超鏈接元素, 模糊定位, 輸入部分內(nèi)容就行
driver.find_element("partial link text", "a123")
⑤使用name定位, 和id一樣, 有name直接寫就行了
⑥使用tag name定位
# 定位第一個(gè)input元素
driver = find_element("tag name", "input")
"""
使用tag name定位, 很容易遇到很多個(gè)相同標(biāo)簽, 可以這么寫:
driver = find_elements("tag name", "input")
加個(gè)s代表復(fù)數(shù), 這樣就可以定位頁面所有的input標(biāo)簽,
可以使用for循環(huán)遍歷選擇對(duì)應(yīng)的...基本沒啥用, 幾乎沒用過...
沒錯(cuò), 如果有的話, 其他幾種定位方式也可以通過加s來定位多個(gè)...
八大定位 ×
十六定位 √
"""
⑦使用class name定位
# 定位百度首頁搜索框
driver.find_element("class name", "s_ipt")
⑧使用css selector定位
# 定位百度首頁的'百度一下'按鈕
driver.find_element("css selector", "#su")
"""
css選擇器定位就是要在前面加個(gè)#號(hào)
相對(duì)路徑: 可以先找到距離當(dāng)前元素最近的唯一屬性比如id, 然后根據(jù)層級(jí)定位
和xpath一樣, 也可以使用絕對(duì)路徑:從根目錄html開始, 不過應(yīng)該沒誰會(huì)這樣做吧, 太麻煩
"""
終于寫完了, 8個(gè)定位, 感覺有些不常用的都忘了, 還是百度了下才想起...
特殊元素定位
特殊元素也不是元素特殊, 只是有些元素是8種定位方式定位不到的......? select下拉框、alert / confirm / prompt三種彈窗定位、frame框架定位等
① select下拉框定位及相關(guān)操作
from selenium import webdriver
from time import sleep
# 導(dǎo)入定位select標(biāo)簽專用包
from selenium.webdriver.support.select import Select
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 進(jìn)入一個(gè)帶下拉框的網(wǎng)址
driver.get("https://sahitest.com/demo/selectTest.htm")
# 定位到select元素
selects = Select(driver.find_element("id","s4Id"))
# 元素判斷是否支持多選 is_multiple
print(selects.is_multiple) # 返回True
# 查看元素有幾個(gè)選項(xiàng)
print(selects.options) # 是個(gè)列表, 可以選擇print(len(selects.options))
# 既然支持多選,試試多選, 有多種選擇方式
selects.select_by_index(1) # 用索引選, 索引從0開始
sleep(1)
selects.select_by_value('o3val') # 用屬性value選
sleep(1)
selects.select_by_visible_text("") # 用頁面文本選
sleep(2)
#選擇后想取消選擇, 取消索引1的, 就是在 選中方法 的前面加上 de
selects.deselect_by_index(1)
sleep(2)
# 直接取消所有的
selects.deselect_all()
# 再定位一個(gè)單選的 select元素
select = Select(driver.find_element("css selector","#s2Id"))
# 判斷是否支持多選
print(select.is_multiple)
# 用索引選中第3個(gè)
select.select_by_index(2)
sleep(1)
# 取消選中的, 單選的不能被取消,只能重新?lián)Q選中位置
# 用文本選第一個(gè)
select.select_by_visible_text("")
sleep(2)
driver.quit()
② 彈窗定位及相關(guān)操作
彈窗的話js中常見的有3種彈窗
第一種:?alert() 警告窗
from selenium import webdriver
from time import sleep
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 進(jìn)入網(wǎng)址
driver.get("https://sahitest.com/demo/alertTest.htm")
# 獲取元素
alert = driver.find_element("name","b1")
# 點(diǎn)擊元素
alert.click()
sleep(2)
# 打印元素對(duì)象信息
print("彈窗元素對(duì)象信息", driver.switch_to.alert)
# 打印元素文本內(nèi)容
print("打印alert彈窗內(nèi)容:", driver.switch_to.alert.text)
# 點(diǎn)擊彈窗上的確定按鈕
driver.switch_to.alert.accept()
# # 點(diǎn)擊提示框的取消..雖然alert提示框沒有取消按鈕, 這里選擇取消也可以..
# driver.switch_to.alert.dismiss()
sleep(2)
第二種:?confirm() 確認(rèn)窗
from selenium import webdriver
from time import sleep
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 進(jìn)入 彈窗 確定取消 的網(wǎng)址
driver.get("https://sahitest.com/demo/confirmTest.htm")
# 獲取confirm彈窗按鈕
confirm = driver.find_element("name","b1")
# 點(diǎn)擊彈窗
confirm.click()
sleep(2)
# 點(diǎn)擊確定按鈕取消
driver.switch_to.alert.accept()
sleep(2)
# 再次點(diǎn)擊彈窗
confirm.click()
sleep(2)
# 點(diǎn)擊取消按鈕取消
driver.switch_to.alert.dismiss()
sleep(2)
第三種:?propmt() 輸入窗
遇到點(diǎn)問題..., 原本確實(shí)是用'switch_to.alert.send_keys()'方法給輸入框輸入內(nèi)容的, 不知為什么輸入不了..., 輸入到下一個(gè)input框了...
from selenium import webdriver
from time import sleep
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 獲取 輸入彈窗 的網(wǎng)址
driver.get("https://sahitest.com/demo/promptTest.htm")
# 獲取彈窗按鈕
prompt = driver.find_element("name","b1")
sleep(2)
# 點(diǎn)擊彈窗
prompt.click()
sleep(1)
# 輸入內(nèi)容
driver.switch_to.alert.send_keys("本次點(diǎn)擊的是確定按鈕,下次是取消")
sleep(2)
# 點(diǎn)擊確定按鈕
driver.switch_to.alert.accept()
sleep(1)
# 再次點(diǎn)擊輸入彈窗
prompt.click()
sleep(1)
# 輸入內(nèi)容
driver.switch_to.alert.send_keys("我要點(diǎn)擊取消按鈕了")
sleep(2)
# 點(diǎn)擊取消
driver.switch_to.alert.dismiss()
sleep(2)
③ iframe內(nèi)嵌框架定位及相關(guān)操作
from time import sleep
from selenium import webdriver
"""
有時(shí)定位一個(gè)元素, 比如用id, 明明沒輸錯(cuò), 但就是定位不到?
這就很奇怪了, 最直接的id都定位不到, 還有別的能定位到嗎?
這時(shí)可以看看元素上面的標(biāo)簽, 很可能是寫在iframe框架中的
這個(gè)一般在登錄窗口比較常見, 相當(dāng)于是打開了一個(gè)新的頁面
所以需要先進(jìn)入這個(gè)新頁面, 才能繼續(xù)定位這個(gè)頁面中的元素
操作完成后記得退出新頁面, 才能繼續(xù)操作之前頁面的元素哦
"""
# 定位iframe框架有三種方式, 分別是使用索引、id、web元素對(duì)象
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開網(wǎng)易郵箱首頁
driver.get("https://mail.163.com/")
# 使用索引的方式獲取并進(jìn)入iframe內(nèi)嵌框架
driver.switch_to.frame(0)
"""
其他方式:
# 直接填入iframe框架的id值
driver.switch_to.frame(id)
# 直接填入iframe框架的name值
driver.switch_to.frame(name)
# 也可以先用8大定位方式定位到iframe元素, 然后直接放入這個(gè)web元素
driver.switch_to.frame(driver.find_element('method', 'path'))
"""
sleep(1)
# 獲取登錄郵箱輸入框
driver.find_element(By.NAME,"email").send_keys("123")
# 獲取登錄密碼輸入框
sleep(1)
driver.find_element(By.NAME,"password").send_keys("哈哈")
# 假裝已經(jīng)點(diǎn)擊登錄按鈕
sleep(2)
# 退出iframe框架
driver.switch_to.default_content()
"""
也可以獲取當(dāng)前所有句柄, 然后進(jìn)行切換句柄..
# 獲取所有句柄
all_handles = driver_gl.window_handles
# 退出到第一個(gè)界面: 獲取所有句柄后返回的是個(gè)列表, 這里用切片的方式選擇第一個(gè)網(wǎng)頁窗口
driver.switch_to.window(all_handles[0])
"""
# 再嘗試定位底部的'網(wǎng)易首頁'超鏈接
driver.find_element(By.PARTIAL_LINK_TEXT,"易首頁").click()
sleep(2)
④ 文件的上傳下載
我一直在想把這個(gè)文件上傳下載歸類到 [瀏覽器操作] 還是放入 [元素定位] 里面...,? 既然寫到這里才想起來, 那就先放這吧
上傳
絕對(duì)路徑上傳
from selenium import webdriver
from time import sleep
"""文件上傳"""
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
driver.get("https://sahitest.com/demo/php/fileUpload.htm")
# 定位所有name為file的上傳按鈕
files_button= driver.find_elements("name","file")
# 使用for循環(huán)挨個(gè)上傳, 每上傳一個(gè), 等1秒
for i in files_button:
# 使用絕對(duì)路徑上傳 !!!send_keys只能對(duì)input元素有效!!!
i.send_keys(r"C:\Test\ALL\demo.py")
sleep(1)
sleep(3)
相對(duì)路徑上傳
from selenium import webdriver
from time import sleep
import os
"""文件上傳"""
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
driver.get("https://sahitest.com/demo/php/fileUpload.htm")
"""
相對(duì)路徑,需要采用os模塊里的path相關(guān)函數(shù)
語法說明:
os.path.join() 拼接路徑的,每級(jí)目錄之間用,隔開
os.path.dirname(os.getcwd()) 返回到當(dāng)前文件所在目錄的上一級(jí)
os.getcwd()
print(os.getcwd()) 打印 當(dāng)前文件所在的目錄
"""
# 設(shè)置文件及路徑
filepath = os.path.join(os.getcwd(), "demo.py")
# filepath = os.path.join(os.path.dirname(os.getcwd()), "230203.py")
driver.find_element("id","file").send_keys(filepath)
sleep(2)
sleep(2)
我覺得這個(gè)文件上傳下載比較雞肋? 因?yàn)槲募蟼鞯脑? 需要網(wǎng)頁用的是input元素才能上傳 而文件下載..確定可以讓他下載, 但是不知道到底有沒有下載完成?
下載
下載使用的是瀏覽器配置項(xiàng)進(jìn)行下載的, 每個(gè)瀏覽器不一樣
firefox下載
(這個(gè)沒具體試過, 因?yàn)槲也幌矚g火狐, 沒他的瀏覽器
from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.firefox.service import Service
from selenium import webdriver
from time import sleep
import os
"""
火狐瀏覽器
操作步驟:
1 創(chuàng)建Firefox瀏覽器配置信息對(duì)象
webdriver.FirefoxProfile()
2 設(shè)置Firefox瀏覽器下載相關(guān)的自定義配置信息
3 設(shè)置Firefox瀏覽器對(duì)象,并把自定義配置信息存儲(chǔ)到瀏覽器對(duì)象中
4 訪問下載網(wǎng)站進(jìn)行下載
"""
# 1. 創(chuàng)建火狐瀏覽器配置信息對(duì)象,用于存放自定義配置
options = webdriver.FirefoxOptions()
# 2. 配置Firefox下載相關(guān)信息
"""
2.1
指定自定義下載路徑,默認(rèn)只會(huì)自動(dòng)創(chuàng)建一級(jí)的目錄,
如果指定了多級(jí)不存在的目錄,就會(huì)下載到默認(rèn)路徑
"""
options.set_preference("browser.download.dir","D:\\FF_Download\\")
"""
2.2
將browser.download.folderList設(shè)置為:
設(shè)置成 0 表示下載到桌面
設(shè)置成 1 表示下載到瀏覽器默認(rèn)下載路徑
設(shè)置成 2 表示使用自定義下載路徑
和上面browser.download.dir配合使用, 如果設(shè)置成0或1,上面的自定義路徑配置基本無用
"""
options.set_preference("browser.download.folderList", 2)
"""
2.3
browser.helperApps.alwaysAsk.force:
對(duì)未知的 mime 類型文件會(huì)彈出窗口讓用戶處理
默認(rèn)值為true,
設(shè)定為False表示不會(huì)記錄打開未知 MIME 類型文件的方式
"""
options.set_preference("browser.helperApps.alwaysAsk.force",False)
"""
2.4
browser.download.manager.showWhenStarting
在開始下載時(shí)是否顯示下載管理器
設(shè)定為True,則在用戶啟動(dòng)下載的時(shí)候顯示Firefox瀏覽器的文件下載窗口
否則不顯示文件下載窗口
"""
options.set_preference("browser.download.manager.showWhenStarting",False)
"""
2.5
browser.download.manager.useWindow
設(shè)定為 False 會(huì)把下載框進(jìn)行隱藏
"""
options.set_preference("browser.download.manager.useWindow",False)
"""
2.6
browser.download.manager.focusWhenStarting
默認(rèn)值為True,表示獲取焦點(diǎn)
"""
options.set_preference("browser.download.manager.focusWhenStarting",False)
"""
2.7
browser.download.manager.alertOnEXEOpen
下載.exe文件彈出警告
默認(rèn)值是True,設(shè)置為False則不會(huì)彈出警告框
"""
options.set_preference("browser.download.manager.alertOnEXEOpen",False)
"""
2.8
browser.helperApps.neverAsk.openFile:
表示直接打開下載文件,不顯示確認(rèn)框
默認(rèn)值為空字符串,下行代碼行設(shè)定了多種的 MIME類型,
例如:
application/exe 表示 .exe 類型的文件,
application/execel 表示 Excel 類型的文件
"""
options.set_preference("browser.helperApps.neverAsk.openFile","application/zip")
"""
2.9
對(duì)所給出文件類型不再彈出框進(jìn)行詢問,直接保存到本地磁盤
"""
options.set_preference("browser.helperApps.neverAsk.saveToDisk",
"application/zip, application/octet-stream")
"""
其他可選文件類型:
application/a-gzip
application/x-gzip
application/zip
application/x-gtar
text/plain
application/x-compressed
application/octet-stream
application/pdf
"""
"""
2.10
browser.download.manager.showAlertOnComplete
設(shè)定下載文件結(jié)束后是否顯示下載完成提示框
默認(rèn)為True
設(shè)定為False表示下載完成后不顯示完成提示框
"""
options.set_preference("browser.download.manager.showAlertOnComplete",False)
"""
2.11
browser.download.manager.closeWhenDone:
設(shè)定下載結(jié)束后是否自動(dòng)關(guān)閉下載框,默認(rèn)值為True
設(shè)置為False,表示不關(guān)閉下載框
"""
options.set_preference("browser.download.manager.closeWhenDone",False)
# 創(chuàng)建瀏覽器對(duì)象
driver_ff = webdriver.Firefox(service=Service(GeckoDriverManager().install()),
options=options)
# 訪問網(wǎng)址
driver_ff.get("https://npm.taobao.org/mirrors/geckodriver/v0.20.0/")
sleep(3)
# 定位下載連接 , 點(diǎn)擊下載
file = driver_ff.find_element("link text","geckodriver-v0.20.0-win64.zip")
file.click()
sleep(3)
driver_ff.quit()
chrome下載
因?yàn)镋dge瀏覽器用的是chrome內(nèi)核, 所以我直接用Edge瀏覽器吧, 不習(xí)慣(喜歡)谷歌...
"""Chrome瀏覽器文件下載
"""
from selenium import webdriver
from time import sleep
import os
# 創(chuàng)建瀏覽器配置選項(xiàng)
options = webdriver.EdgeOptions()
# 定義加載項(xiàng)參數(shù)
prefs = {'profile.default_content_settings.popups': 0,
'download.default_directory': 'C:\\Users\\nn\Desktop\禁止點(diǎn)擊'}
"""
download.default_directory:指定路徑
profile.default_content_settings.popups:0 為屏蔽彈窗,1 為開啟彈窗
"""
# 將加載項(xiàng)參數(shù)添加到瀏覽器配置選項(xiàng)中
options.add_experimental_option("prefs", prefs)
# 獲取驅(qū)動(dòng), 傳入調(diào)試項(xiàng)
driver = webdriver.Edge(options=options)
# 打開頁面
driver.implicitly_wait(10)
driver.get("https://registry.npmmirror.com/binary.html?path=chromedriver/111.0.5563.19/")
# 點(diǎn)擊下載
driver.find_element("link text", "chromedriver_win32.zip").click()
# 給出下載時(shí)間.......10秒
"""
剛開始學(xué)的時(shí)候, 是使用sleep()給出指定的下載時(shí)間, 防止瀏覽器自動(dòng)關(guān)閉
這個(gè)我覺得不太智能, 萬一因?yàn)榫W(wǎng)絡(luò)或者什么環(huán)境問題, 下載時(shí)間到了, 文件卻沒下載完成,瀏覽器關(guān)閉了怎么辦?
之前也有考慮到這個(gè)問題, 但是沒想到解決辦法
"""
"""
現(xiàn)在這么多年會(huì)過來看看, 暫時(shí)想到的思路就是: 去讀取下載目錄: 是否存在下載的文件? 如果存在就退出讀取任務(wù)或關(guān)閉瀏覽器
操作步驟描述:
1. 因?yàn)槲乙膊恢谰唧w下載時(shí)間,所以這里使用while循環(huán), 為了性能考慮每2秒循環(huán)一次吧...
2. 因?yàn)榉祷氐膶?duì)象比較特殊,需要用for循環(huán)遍歷
3. 遍歷后使用if判斷指定文件是否已存在該目錄, 如果存在就跳出循環(huán)
"""
while True:
sleep(2)
for i in os.walk("C:\\Users\\nn\Desktop\禁止點(diǎn)擊"):
if "chromedriver_win32.zip" in i[2]:
print("已下載完成")
break
break
"""
os.walk(path)參數(shù)解讀:
就當(dāng)他可以遍歷一個(gè)指定的文件路徑
返回值是個(gè)generator對(duì)象, 需要用for循環(huán)遍歷, 遍歷后是元組, 有三個(gè)參數(shù):
root 保存當(dāng)前遍歷的文件夾的絕對(duì)路徑;
dirs 保存當(dāng)前文件夾下的所有子文件夾的名稱(僅一層,孫子文件夾不包括)
files 保存當(dāng)前文件夾下的所有文件的名稱
上面代碼用切片的形式, 直接返回第三個(gè)參數(shù)files,是個(gè)列表,
判斷這個(gè)列表是否包含指定名稱的文件
"""
元素操作
from time import sleep
from selenium import webdriver
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
search = driver .find_element("id","kw")
print("元素文本內(nèi)容",search.text)
print(f"元素名{search.tag_name}")
print("元素大小",search.size)
print("元素的css的width值",search.value_of_css_property("width"))
print("搜索框是否可見",search.is_displayed())
print("搜索框是否可用",search.is_enabled())
search.send_keys(123)
print("搜索框是否被選中",search.is_selected())
driver .quit()
鼠標(biāo)&鍵盤事件
鼠標(biāo)操作
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開控件網(wǎng)址
driver.get("http://sahitest.com/demo/clicks.htm")
# 給動(dòng)作鏈指定驅(qū)動(dòng)
ac = ActionChains(driver)
# 定位到鼠標(biāo)右鍵按鈕
right_click_btn = driver.find_element("css selector","body > form > input[type=button]:nth-child(13)")
# 定位到鼠標(biāo)雙擊按鈕
db_click_btn = driver.find_element("css selector","body > form > input[type=button]:nth-child(8)")
# 執(zhí)行鼠標(biāo)右擊右鍵按鈕
ac.context_click(right_click_btn)
sleep(1)
# 執(zhí)行鼠標(biāo)雙擊按鈕
ac.double_click(db_click_btn).perform()
sleep(5)
# 切換到拖拽控件頁面
driver.get("http://sahitest.com/demo/dragDropMooTools.htm")
# 給動(dòng)作鏈重新指定驅(qū)動(dòng)
ac = ActionChains(driver)
# 定位需要拖拽的元素和拖拽到的位置
drag_ele =driver.find_element("id","dragger")
drag_location = driver.find_element("css selector","body > div:nth-child(6)")
# 執(zhí)行拖拽動(dòng)作
ac.drag_and_drop(drag_ele,drag_location).perform()
sleep(5)
# 切換淘寶首頁
driver.get("https://www.taobao.com/")
# 給動(dòng)作鏈指定驅(qū)動(dòng)
ac = ActionChains(driver)
# 定位到需要鼠標(biāo)懸浮按鈕的元素
move_btn = driver.find_element("css selector","#J_SiteNavBdL > li.site-nav-menu.site-nav-switch.site-nav-multi-menu.J_MultiMenu > div.site-nav-menu-hd > span.site-nav-region")
# 執(zhí)行鼠標(biāo)懸浮操作
ac.move_to_element(move_btn).perform()
sleep(3)
"""
鼠標(biāo)操作:
固定寫法:
ActionChains.xxx(ele).perform()
# 鼠標(biāo)左擊不松手操作
ActionChains.click_and_hold(test_ele).perform()
# 鼠標(biāo)右擊操作
ActionChains.context_click(test_ele).perform()
# 鼠標(biāo)指針懸浮操作
ActionChains.move_to_element(test_ele).perform()
# 鼠標(biāo)拖操作
ActionChains.drag_and_drop(ele, target).perform()
注意:
1, 每次更換網(wǎng)頁后,都要重新給鼠標(biāo)指定驅(qū)動(dòng)
2, perform()是鼠標(biāo)事件的執(zhí)行方法,鼠標(biāo)事件剛寫上并不會(huì)被執(zhí)行,
會(huì)被放入到一個(gè)隊(duì)列,只有再調(diào)用perform()方法后,才會(huì)執(zhí)行這個(gè)隊(duì)列
(所以這個(gè)庫叫動(dòng)作鏈)
"""
鍵盤操作
from time import sleep
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
#
#
# 獲取谷歌驅(qū)動(dòng)
driver = webdriver.Edge()
# 進(jìn)入百度首頁
driver.get("https://www.baidu.com")
# 找到搜索框
search = driver.find_element("css selector","#kw")
# 搜索框內(nèi)輸入 !23
search.send_keys("!23")
sleep(2)
# 鍵盤事件 輸入框內(nèi)全選
search.send_keys(Keys.CONTROL,"a")
sleep(2)
# 鍵盤事件 輸入框內(nèi)剪切
search.send_keys(Keys.CONTROL,"x")
sleep(2)
# 鍵盤事件,按下回車搜索
search.send_keys(Keys.ENTER)
# 鍵盤事件,F11全屏,,試過了不行,會(huì)報(bào)異常, 電腦硬件有關(guān)系,每臺(tái)電腦不一樣
# search.send_keys(Keys.F11)
sleep(2)
三大等待
① 強(qiáng)制等待
就是python內(nèi)置的time包中的sleep()方法, 設(shè)置幾就強(qiáng)制等幾秒, 代碼才會(huì)繼續(xù)運(yùn)行
② 隱式等待
這個(gè)隱式等待啊, 當(dāng)時(shí)剛學(xué)的時(shí)候很喜歡, 每次獲取完驅(qū)動(dòng)都要加個(gè)隱式等待,? 隱式等待的作用域是全局的, 每有個(gè)打開的網(wǎng)址或者刷新什么的都會(huì)去有這個(gè)隱式等待 缺點(diǎn)是它實(shí)在是太慢了, 要等頁面所有元素都加載完成, 才會(huì)進(jìn)行下一個(gè)操作 selenium本來就慢, 再用這個(gè)....我真的...不要說我太著急, 我是吉吉國(guó)王, 我太吉了?
from time import sleep
from selenium import webdriver
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開網(wǎng)址
driver.get("http://sahitest.com/demo/iframesTest.htm")
# 隱式等待 設(shè)置10秒
driver.implicitly_wait(10)
"""
如果超時(shí)后還沒加載完全, 代碼會(huì)報(bào)異常...
"""
③ 顯示等待
顯示等待比隱式等待好點(diǎn), 可以設(shè)置等待指定元素加載出來后就繼續(xù)運(yùn)行, 超時(shí)報(bào)異常 但是寫起來麻煩, 導(dǎo)的包也多, 寫一次也只作用一次,?
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 獲取驅(qū)動(dòng)
driver = webdriver.Edge()
# 打開網(wǎng)址
driver.get("http://www.baidu.com")
# 先把驅(qū)動(dòng)加入到顯示等待, 再設(shè)置等待超時(shí)時(shí)間比如8秒,
wait = WebDriverWait(driver, 8)
# 定位方式 -- 定位的是搜索框
locator = ("id", "kw")
# 再檢查網(wǎng)頁上是否至少存在一個(gè)搜索框, 如果找到就可以繼續(xù)運(yùn)行, 不然超時(shí)報(bào)錯(cuò)...
ele = wait.until(EC.presence_of_element_located(locator))
"""
顯示等待更多使用時(shí)的判斷條件, 還是看別人寫的吧:
https://www.cnblogs.com/yongzhuang/p/15028052.html
"""
文本驗(yàn)證碼識(shí)別
這個(gè)需要新安裝一個(gè)庫ddddocr(帶帶弟弟ocr), Github地址:https://github.com/sml2h3/ddddocr, 或者直接使用命令:
pip3 install ddddocr
使用:
import ddddocr
import time
from selenium import webdriver
# 獲取驅(qū)動(dòng)
d = webdriver.Edge()
# 打開網(wǎng)址
d.get("https://support.huawei.com/enterprise/ecareWechat")
#
time.sleep(2)
# 處理內(nèi)嵌
d.switch_to.frame(0)
# 找到驗(yàn)證碼圖片
img = d.find_element("css selector","#imgObj")
# 獲取圖片的bytes數(shù)據(jù)
data = img.screenshot_as_png
# 初始化ocr
ocr = ddddocr.DdddOcr()
# 進(jìn)行驗(yàn)證碼識(shí)別
text = ocr.classification(data)
print("驗(yàn)證碼是:", text)
# 填寫到輸入框
d.find_element("css selector","#yzm").send_keys(text)
time.sleep(2)
d.quit()
運(yùn)行完成后會(huì)在控制臺(tái)發(fā)現(xiàn)他給自己打廣告了, 哈哈哈, 如果覺得有影響可以進(jìn)入DdddOcr()源碼
把 { if show_ad }下面的 { print(str) } 都刪了, 換成pass就行了
截屏
import time
from selenium import webdriver
# 獲取驅(qū)動(dòng)
d = webdriver.Edge()
# 打開網(wǎng)址
d.get("https://support.huawei.com/enterprise/ecareWechat")
#
time.sleep(2)
# 處理內(nèi)嵌
d.switch_to.frame(0)
# 找到確定按鈕的元素
img = d.find_element("css selector","#btnSearch")
# 截圖瀏覽器當(dāng)前窗口保存到本地, 保存格式為png
d.save_screenshot("C:\\Users\\nn\Desktop\禁止點(diǎn)擊\\123.png")
# 截圖元素保存本地
img.screenshot("C:\\Users\\nn\Desktop\禁止點(diǎn)擊\\789.png")
time.sleep(1)
d.quit()
總覺得這樣以圖片直接結(jié)束有點(diǎn)丑, 所以就給底部加了這么一行字。
柚子快報(bào)激活碼778899分享:UI自動(dòng)化-Selenium
相關(guān)閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。