網(wǎng)站顏色搭配哪里有免費的網(wǎng)站推廣軟件
全篇大概10000字(含代碼),建議閱讀時間30min
一、等待機(jī)制
如果有一些內(nèi)容是通過Ajax加載的內(nèi)容,那就需要等待內(nèi)容加載完畢才能進(jìn)行下一步操作。
為了避免人為操作等待,會遇到的問題, selenium將等待轉(zhuǎn)換為機(jī)器去等待,去判斷在什么時間去進(jìn)行下一步操作。
1.1 頁面級等待機(jī)制
定義等待頁面加載完畢的超時時間,默認(rèn)設(shè)置為0表示等待時間不限。
set_page_load_timeout(最長等待秒數(shù))
設(shè)置等待超時時間,全局設(shè)置,在WebDriver 生命周期內(nèi)生效
from selenium import webdriverdriver = webdriver.Chrome()
driver.set_page_load_timeout(3)
driver.get("https://www.selenium.dev/")
driver.quit()
等待時間設(shè)置為3秒,如果加載時間超過3秒,就會拋出異常。如果在3秒內(nèi)加載完成,則執(zhí)行下一行代碼。
1.2元素級等待機(jī)制強(qiáng)制等待
也就是說有一些元素需要觸發(fā)特定區(qū)域后才會顯示,才能進(jìn)行下一步操作。
這樣就可以使用強(qiáng)制等待方式,通過 time庫來進(jìn)行等待。
from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
driver.get("https://www.baidu.com")driver.find_element(By.LINK_TEXT, "登錄").click()
time.sleep(3)
driver.find_element(By.LINK_TEXT, "立即注冊").click()
driver.quit()
不建議使用!
1.3 素級等待機(jī)制隱式等待
它是在執(zhí)行函數(shù)時增加一些寬限時間,設(shè)置一個最長超出時間,如果在一定時間內(nèi)元素還是沒有出現(xiàn),直接拋出異常、
implicitly_wait(等待秒數(shù))
隱式等待
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.implicitly_wait(10)driver.get("https://www.baidu.com")
driver.find_element(By.LINK_TEXT, "登錄").click()
driver.find_element(By.LINK_TEXT, "立即注冊").click()driver.quit()
負(fù)作用:
- 檢查某元素是否不存在,等待隱式等待中設(shè)置最大時長,減緩測試速度。
- 干擾顯式等待。
1.4 元素及等待機(jī)制 顯式等待
指定條件判斷函數(shù),每隔一定時間檢測該條件是否成立。成立就執(zhí)行下一步,直到超過最大等待時間。
from selenium.webdriver.support.wait import WebDriverWait
導(dǎo)入
WebDriverWait(WebDriver實例, 超時秒數(shù), 檢測時間間隔(可選), 可忽略異常集合(可選))
實例化方法
檢測時間間隔: 調(diào)用until 或until_not 中傳入判斷函數(shù)的間隔時間,默認(rèn)0.5秒。
可忽略異常集合:調(diào)用until或until_not 中傳入判斷函數(shù),如果拋出集合中定義的異常,代碼不會執(zhí)行失敗,會繼續(xù)正常執(zhí)行。默認(rèn)異常是 NoSuchElementException。
until
等待直到條件判斷函數(shù)的返回值不為False。
until_not
等待直到條件判斷函數(shù)返回值為False,如果拋出可忽略異常,會當(dāng)做False處理。
使用自定義等待條件函數(shù)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWaitdef registerLinkDisplayed(webDriver):# 檢測是否已經(jīng)顯示立即注冊鏈接return webDriver.find_element(By.LINK_TEXT, "立即注冊").is_displayed()driver = webdriver.Chrome()
driver.get("https://www.baidu.com")driver.find_element(By.LINK_TEXT, "登錄").click()
# 每間隔0.5秒 去調(diào)用判斷函數(shù),條件滿足執(zhí)行下一行代碼。
WebDriverWait(driver, 10).until(registerLinkDisplayed)
driver.find_element(By.LINK_TEXT, "立即注冊").click()
driver.quit()
使用預(yù)定義等待條件函數(shù)
from selenium.webdriver.suport import expected_conditions
預(yù)定義等待函數(shù)
visibility_of_element_located()
判斷目標(biāo)元素是否處于可見狀態(tài)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditionsdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")driver.find_element(By.LINK_TEXT, "登錄").click()
targetLocator = (By.LINK_TEXT, "立即注冊")
WebDriverWait(driver, 10).until(expected_conditions.visibility_of_all_elements_located(targetLocator))driver.find_element(By.LINK_TEXT, "立即注冊").click()driver.quit()
預(yù)定義所有條件等待函數(shù)
類別 | 函數(shù)名稱 | 參數(shù) | 功能 |
判斷元素的可見性 | visibility_of_element_located | locator(目標(biāo)元素定位) | 判斷目標(biāo)元素是否已顯示,如果已顯示,則返回該WebElement對象 |
visibility_of | webElement(目標(biāo)元素) | 判斷目標(biāo)元素是否已顯示,如果已顯示,則返回該WebElement對象 | |
visibility_of_all_elements_located | locator(目標(biāo)元素定位) | 判斷頁面上是否存在一個或多個符合定位的元素,且是否已全部顯示,如果是,則返回WebElement集合 | |
visibility_of_any_elements_located | locator(目標(biāo)元素定位) | 根據(jù)定位判斷頁面上是否存在一個或多個符合定位的元素,元素中是否至少有一個已先睡,如果是,則返回其中已顯示的WebElement集合 | |
invisibility_of_element_located | locator(目標(biāo)元素定位) | 根據(jù)定位判斷目標(biāo)元素是否未顯示 | |
判斷元素的狀態(tài)、文本、值 | element_to_be_clickable | locator(目標(biāo)元素定位) | 根據(jù)定位判斷目標(biāo)元素是否處于可單擊狀態(tài) |
element_located_to_be_selected | locator(目標(biāo)元素定位) | 根據(jù)定位判斷目標(biāo)元素是否處于已選中狀態(tài) | |
element_to_be_selected | webElement(目標(biāo)元素) | 判斷目標(biāo)元素是否處于已選中狀態(tài) | |
element_located_selection_state_to_be | locator(目標(biāo)元素定位),is_selected(期望狀態(tài)) True(選中) False(未選中) | 根據(jù)定位判斷選中狀態(tài)是否符合預(yù)期 | |
element_selection_state_to_be | webElement(目標(biāo)元素),is_selected(期望狀態(tài)) True(選中) False(未選中) | 判斷目標(biāo)元素選中狀態(tài)是否符合預(yù)期 | |
text_to_be_present_in_element | locator(目標(biāo)元素定位), text(期望包含的文本) | 判斷目標(biāo)元素的文本是否包含期望的文本 | |
text_to_be_present_in_element_value | locator(目標(biāo)元素定位),text(期望包含的文本) | 判斷目標(biāo)元素的value屬性是否已包含期望文本 | |
判斷元素是否存在 | presence_of_element_located | locator(目標(biāo)元素定位) | 根據(jù)定位判斷頁面上是否存在首個符合定位元素,如果有,則返回該WebElement |
presence_of_all_elements_located | locator(目標(biāo)元素定位) | 根據(jù)定位判斷頁面上是否存在一個或多個符合定位元素,如果有,則返回WebElement集合 | |
staleness_of | webElement(目標(biāo)元素) | 判斷目標(biāo)元素是否已經(jīng)從DOM結(jié)構(gòu)上完全消失 | |
判斷瀏覽器窗口、彈框及內(nèi)嵌網(wǎng)頁 | new_window_is_opened | current_handles(當(dāng)前的窗口句柄集合) | 判斷是否有新窗口打開,句柄數(shù)量是否會在當(dāng)前句柄集合的基礎(chǔ)上有所基礎(chǔ) |
number_of_windows_and_switch_to_it | locator(目標(biāo)元素(IFrame/Frame)定位) | 根據(jù)定位判斷是否可以切換到目標(biāo)元素,如果可以切換,則會直接切換到指定元素(IFrame/Frame)上 | |
alert_is_present | - | 判斷是否已出現(xiàn)瀏覽器彈窗 | |
判斷網(wǎng)頁標(biāo)題或URL | title_contains | title(期望包含的標(biāo)題) | 判斷網(wǎng)頁標(biāo)題是否已包含期望的標(biāo)題(即是否模糊匹配) |
title_is | title(期望相等的標(biāo)題) | 判斷網(wǎng)頁標(biāo)題是否完全等于期望的標(biāo)題(即是否完全匹配) | |
url_changes | url(當(dāng)前URL) | 判斷URL是否發(fā)生變化,即與當(dāng)前的URL不相同 | |
url_contains | url(期望包含的URL) | 判斷URL是否已包含期望的URL(即是否模糊匹配) | |
url_matches | pattern(格式表達(dá)式) | 判斷URL是否匹配格式表達(dá)式(例如正則表達(dá)式) | |
url_to_be | url(期望相等的URL) | 判斷URL是否已包含期望的URL(即是否完全匹配) |
3. 其他可選參數(shù)設(shè)置
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common import exceptionsdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")WebDriverWait(driver, 30, 2, [exceptions.NoSuchElementException, ZeroDivisionError])\.until(lambda p : 3/0, "很明顯, 3是不能除以0的")
1.5 腳本級等待機(jī)制
driver.set_script_timeout(最長等待秒數(shù))
為JavaScript設(shè)置超時時間
二、對鍵盤和鼠標(biāo)進(jìn)行精準(zhǔn)模擬
ActionChains 偏向底層的自動化交互方式,實現(xiàn)鼠標(biāo)移動、單擊、右擊、雙擊、鼠標(biāo)按下或松開、懸停拖拽、按鍵按下或松開、按組合鍵等復(fù)雜的操作。
2.1 ActionChains 操作鏈
from selenium.webdriver.common.action_chains import ActionChains
引入模塊使用庫
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChainsdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")ActionChains(driver).click(driver.find_element(By.LINK_TEXT, "登錄")).perform()
# .click(...) 對操作進(jìn)行設(shè)置,在操作鏈中預(yù)約了一個單擊操作,操作對象是登錄。
# .perform() 執(zhí)行操作鏈中所有操作
driver.quit()
案例:鼠標(biāo)懸停在設(shè)置菜單上,然后再彈出的菜單中選擇搜索設(shè)置。最后在彈出的設(shè)置面板中按順序進(jìn)行不顯示、僅繁體中文、顯示、保存設(shè)置操作。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()driver.get("https://www.baidu.com")
# move_to_element會將鼠標(biāo)指針放置在"設(shè)置"鏈接上,實現(xiàn)懸停效果
# pause(3) 等待秒
ActionChains(driver).move_to_element(driver.find_element(By.XPATH, "//span[text()='設(shè)置']"))\.pause(3).perform()
ActionChains(driver).click(driver.find_element(By.LINK_TEXT, "搜索設(shè)置"))\.pause(3).perform()
ActionChains(driver).click(driver.find_element(By.ID, "s1_2"))\.click(driver.find_element(By.ID, "SL_2"))\.click(driver.find_element(By.ID, "sh_1"))\.click(driver.find_element(By.LINK_TEXT, "保存設(shè)置"))\.pause(3).perform()driver.quit()
2.2 ActionChains 鼠標(biāo)與鍵盤操作設(shè)置
類別 | 函數(shù)名 | 參數(shù) | 功能 |
鼠標(biāo)按鈕操作設(shè)置 | click | element(目標(biāo)元素,可選) | 單擊目標(biāo)元素,如果沒有傳入目標(biāo)元素參數(shù),會單擊當(dāng)前鼠標(biāo)指針位置 |
context_click | element(目標(biāo)元素,可選) | 右擊目標(biāo)元素,如果沒有傳入目標(biāo)元素,會右擊鼠標(biāo)指針位置 | |
double_click | element(目標(biāo)元素,可選) | 雙擊目標(biāo)元素,如果沒有傳入目標(biāo)元素,會雙擊當(dāng)前鼠標(biāo)位置 | |
click_and_hold | element(目標(biāo)元素,可選) | 在目標(biāo)元素長按鼠標(biāo)按鈕。如果沒有傳入目標(biāo)元素,會在當(dāng)前鼠標(biāo)位置按下鼠標(biāo)左鍵 | |
release | element(目標(biāo)元素,可選) | 在目標(biāo)元素松開鼠標(biāo)按鈕。如果沒有傳入目標(biāo)元素,則會在當(dāng)前鼠標(biāo)指針位置按下鼠標(biāo)左鍵 | |
鼠標(biāo)移動操作設(shè)置 | move_to_element | element(目標(biāo)元素) | 將鼠標(biāo)指針移動到目標(biāo)元素中間 |
move_to_element_with_offset | element(目標(biāo)元素) ,x坐標(biāo),y坐標(biāo) | 將鼠標(biāo)指針移動到相對目標(biāo)元素的坐標(biāo)(x,y) | |
move_by_offset | x坐標(biāo),y坐標(biāo) | 將鼠標(biāo)移動到相對于目標(biāo)元素的坐標(biāo)(x,y) | |
鼠標(biāo)綜合性操作 | drag_and_drop | sourceElement(被拖放的元素), targetElement(要拖放到的目的地元素) | 在被拖放元素上按下鼠標(biāo)按鈕,然后移動到目標(biāo)元素上松開鼠標(biāo) |
drag_and_drop_by_offset | sourceElement(被拖放的元素), targetElement(要拖放到目的地元素),x坐標(biāo),y坐標(biāo) | 在被拖放元素上按下鼠標(biāo)按鈕,然后移動到相距目標(biāo)元素坐標(biāo)x,y,并松開鼠標(biāo)按鈕 | |
鍵盤按鍵操作設(shè)置 | send_keys | keys_to_send(要按的鍵鈕) | 在當(dāng)前焦點處輸入 |
send_keys_to_element | element(目標(biāo)元素),keys_to_send(要按的鍵鈕) | 對目標(biāo)元素按指定鍵 | |
key_down | key(鍵),element(目標(biāo)元素,可選) | 對目標(biāo)元素按下指定鍵,如果沒有傳入目標(biāo)元素,會在當(dāng)前焦點位置按下指定鍵 | |
key_up | key(鍵),element(目標(biāo)元素,可選) | 對目標(biāo)元素松開指定鍵,如果沒有傳入目標(biāo)元素,則會在當(dāng)前焦點位置松開指定鍵 | |
等待設(shè)置 | pause | seconds(等待秒) | 在指定時間內(nèi)暫停所有后續(xù)操作 |
reset_actions()
清空操作鏈中全部設(shè)置
2.3 模擬復(fù)雜鍵盤操作
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import timedriver = webdriver.Chrome()
driver.get("https://www.baidu.com")
baiduSearchInput = driver.find_element(By.ID, "kw")baiduSearchInput.send_keys("python")
time.sleep(3)baiduSearchInput.send_keys(Keys.CONTROL, "a")
time.sleep(3)
baiduSearchInput.send_keys(Keys.CONTROL, "x")
time.sleep(3)
baiduSearchInput.send_keys(Keys.CONTROL, "v")
time.sleep(3)
baiduSearchInput.send_keys(Keys.BACKSPACE)
time.sleep(3)
baiduSearchInput.send_keys(Keys.ENTER)
三、操作瀏覽器 Cookie
get_cookies()
獲取所有cookie對象集合
get_cookie(cookie名稱)
根據(jù)名稱獲取cookie
from selenium import webdriverdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")# 獲取全部cookies
pageCookies = driver.get_cookies()
for cookie in pageCookies:print(cookie)# 根據(jù)名稱獲取cookie
print(driver.get_cookie("BD_HOME"))
3.1 新增和刪除cookie
driver.add_cookie(cookie對象)
新增cookie
from selenium import webdriverdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.add_cookie({'name': 'MockCookie', 'value': '小那同學(xué)'})
可以在瀏覽器F12調(diào)試工具中 Application查看當(dāng)前添加的cookie
delete_all_cookies()
刪除全部 cookie
delete_cookie(cookie名稱)
按名稱刪除指定 cookie
from selenium import webdriverdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")driver.delete_all_cookies()
3.2 對瀏覽窗口或元素截圖
save_screenshot(截圖文件保存路徑)
對瀏覽器截圖
from selenium import webdriverdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")driver.save_screenshot("保存路徑")
3.3 對元素截圖
screenshot(截圖文件路徑)
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get("https://www.baidu.com")driver.find_element(By.ID, "su").screenshot("圖片地址")
3.4 Selenium操作附加自定義事件
from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver
操作添加事件
EventFiringWebDriver(WebDriver實例,AbstractEventListener實例)
AbstractEventListener 抽象類,使用EventFiringWebDriver 需要設(shè)定自定義時間監(jiān)聽器類。
類需要繼承 AbstractEventListener類。
類別 | 函數(shù)名 | 參數(shù) | 描述 |
瀏覽器級別 | before_navigate_to(url, driver) | url:跳轉(zhuǎn)的目標(biāo)URL driver:當(dāng)前WebDriver實例 | 導(dǎo)航前事件,定義頁面發(fā)生跳轉(zhuǎn)前需要執(zhí)行的代碼 |
after_navigate_to(url, driver) | url: 跳轉(zhuǎn)的目標(biāo)URL driver:當(dāng)前WebDriver實例 | 導(dǎo)航后事件,定義頁面發(fā)生跳轉(zhuǎn)后需要執(zhí)行的代碼 | |
before_navigate_back(driver) | driver:當(dāng)前WebDriver實例 | 瀏覽器后退前事件,定義瀏覽器在執(zhí)行后退后需要執(zhí)行的代碼 | |
after_navigate_forward(driver) | driver: 當(dāng)前WebDriver實例 | 瀏覽器前進(jìn)事件,定義瀏覽器在執(zhí)行前進(jìn)操作后需要執(zhí)行的代碼 | |
after_navigate_forward(driver) | driver: 當(dāng)前WebDriver實例 | 瀏覽器前進(jìn)后事件,定義瀏覽器在執(zhí)行關(guān)閉操作前需要執(zhí)行的代碼 | |
before_close(driver) | driver: 當(dāng)前WebDriver實例 | 瀏覽器關(guān)閉后事件,定義瀏覽器在執(zhí)行關(guān)閉操作后需要執(zhí)行的代碼 | |
元素級 | before_find(by, value, driver) | by: 當(dāng)前使用的查找條件類型 value:當(dāng)前使用的查找值 driver: 當(dāng)前WebDriver實例 | 查找元素前事件,定義Selenium在查找元素前需要執(zhí)行的代碼 |
after_find(by, value, driver) | by: 當(dāng)前使用的查找條件類型 value:當(dāng)前使用的查找值 driver: 當(dāng)前WebDriver實例 | 找到元素后事件,定義Selenium在找到元素后需要執(zhí)行的代碼 | |
before_click(element, driver) | element: 要操作的元素 driver: 當(dāng)前WebDriver實例 | 單擊元素前事件,定義Selenium在單擊元素前需要執(zhí)行的代碼 | |
after_click(element, driver) | element: 要操作的元素 driver:當(dāng)前WebDriver實例 | 單擊元素后事件,定義Selenium在單擊元素后需要執(zhí)行的代碼 | |
before_change_value_of(element, driver) | element: 要操作的元素 driver:當(dāng)前WebDriver實例 | 元素值變更前事件,定義Selenium更改元素需要執(zhí)行的代碼 | |
after_change_value_of(element, driver) | element: 要操作的元素 driver: 當(dāng)前WebDriver實例 | 元素值變更后事件,定義Selenium更改元素值后需要執(zhí)行的代碼 | |
腳本級 | before_execute_script(script, driver) | script: 要執(zhí)行的腳本 driver: 當(dāng)前WebDriver實例 | 腳本執(zhí)行前事件,定義腳本執(zhí)行前需要執(zhí)行的腳本 |
after_execute_script(script, driver) | script:要執(zhí)行的腳本 driver:當(dāng)前WebDriver實例 | 腳本執(zhí)行后事件,定義腳本執(zhí)行后需要執(zhí)行的代碼 | |
異?;蛲顺?/p> | on_exception(exception, driver) | exception: 拋出的異常 driver:當(dāng)前WebDriver實例 | 異常事件,定義在Selenium操作發(fā)生異常時需要執(zhí)行的代碼 |
before_quit(driver) | driver:當(dāng)前WebDriver實例 | WebDriver退出會話前事件,定義在退出會話前需要執(zhí)行的代碼 | |
after_quit(driver) | driver: 當(dāng)前webDriver實例 | WebDriver退出會話后事件,定義在退出會話后需要執(zhí)行的代碼 |
四、瀏覽器啟動參數(shù)設(shè)置
4.1 WebDriver 實例化參數(shù)
driver = webdriver.Chrome()
默認(rèn)實例化沒有參數(shù)
4.2 瀏覽器設(shè)置參數(shù)
options
啟動選項,用于設(shè)置瀏覽器
desired_capabilities
類似于options, 在遠(yuǎn)程運行系統(tǒng)補(bǔ)丁或瀏覽器不定的情況下使用 desired_capabilities,推薦使用 options參數(shù)
chrome_options
等同于options參數(shù),已過時不推薦使用
4.3 瀏覽器驅(qū)動程序設(shè)置參數(shù)
executable_path
瀏覽器驅(qū)動程序路徑,沒有指定,默認(rèn)使用環(huán)境變量中的路徑。
service_args
瀏覽器驅(qū)動程序參數(shù)。瀏覽器不同,參數(shù)也可能不相同。
port
驅(qū)動程序啟用端口號,默認(rèn)使用任意閑置端口號。
service_log_path
驅(qū)動程序存放日志文件地址。
4.4 selenium與瀏覽器驅(qū)動程序連接參數(shù)
keep-alive
表示與ChromeDriver連接時,是否帶上HTTP請求頭Connecton,默認(rèn)值為True。
4.5 JavaScript 進(jìn)行深度操作
雖然Selenium有豐富的操作,但是有一些場景可能需要使用JavaScript進(jìn)行擴(kuò)展。
webdriver.execute_script("js腳本", 自定義參數(shù)集(可選))
執(zhí)行同步腳本
webdriver.execute_async_script("js腳本", 自定義參數(shù)集(可選))
執(zhí)行異步腳本
不建議使用Js去執(zhí)行selenium已經(jīng)存在的內(nèi)容。