上一篇我們花了許多篇幅在說明顯性等待,此篇會提到實際上的應用,一樣是以readmoo這個電子書城的網站為例,因為習慣從這個地方看書,打開來看時就會拿來玩一下,另外,此篇會假設是實際測試產品,增加些檢查頁面元素。
之前在運行自動化登入時,拿readmoo這個網站當例子,其實如果等待一些時間時,網站會出現這個畫面:
這次我們試著等待此網頁出來,將它關掉並點擊登入,先抓元素,與此不同的是,我們假設這個網頁會是重複使用的,為方便管理,會將一些可調整的位置「變數化」,首先我們先把需要用到的套件導入:
#selenium套件
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
#顯性等待
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
#上一篇提到的例外錯誤,在設定的等待時間內仍找不到元素,有可能未加載完全或是其他原因導致。
from selenium.common.exceptions import TimeoutException
#既然是一個測試,那得需要時間,來記錄測試的時間
from datetime import datetime
接著,設定變數,變數可以放在程式碼比較好看見的地方,想調整東西就不用找來找去的:
#需要設定的變數有三個,分別是google搜尋欄位要輸入的部分、帳號、密碼
#帳號密碼是自定義的
google_keyword = "readmoo"
account = "******"
password = "******"
設定driver:
#一樣先關閉通知
chrome_options = Options()
chrome_options.add_argument("--disable-notifications")
#把瀏覽器設定套用到我們的driver
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.google.com/")
#設定顯性等待,把WebDriverWait放到driver,並設定等待時間跟檢查頻率
#由於我們要找的頁面需要等比較長的時間,所以設定為30秒
driver_wait = WebDriverWait(driver,timeout= 30, poll_frequency=0.5)
另外先設定時間,時間最先印,這樣我們在終端機上看到的時間才會是最上面:
#獲取當下時間
current_time = datetime.now()
#格式化當下時間並印出
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
#字串前面的f是用來將formatted_time這個變數字串化,\n換行,因為不想讓字擠在一起
print(f"\n請求時間:{formatted_time}\n")
接著我們會用到 try-except 的結構,它是用來處理可能引發錯誤的程式碼,這裡我們拿來處理可能性的情境,並將不同情境都印出來,元素都一樣,之前的頁面東西,就不一個一個講了:
#google搜尋,如果把相對應的訊息印出來
try:
search_box = driver_wait.until(EC.presence_of_element_located((By.NAME,"q")))
#google_keyword變數化,它將拿我們上面設定好的變數
search_box.send_keys(f"{google_keyword}")
search_box.send_keys(Keys.ENTER)
print("Google搜尋欄位點擊:成功")
#如果元素找超過顯性等待設定的時間,印出相對應的訊息
except TimeoutException:
print("Google搜尋欄位點擊:處理超時")
#找失敗印相對應的訊息
except:
print("Google搜尋欄位:點擊失敗")
#搜尋結果陣列
search_results = driver_wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div.g")))
#if-else夾著try-except if有結果執行try-except的內容,沒有搜尋結果的話印else
if search_results:
first_results = search_results[0]
try:
link = driver_wait.until(EC.presence_of_element_located((By.TAG_NAME,"h3")))
link.click()
print("Googlo搜尋結果點擊:成功")
except TimeoutException:
print("Googlo搜尋結果:處理超時")
except:
print("Googlo搜尋結果點擊:失敗")
else:
print("沒有搜尋結果")
#彈窗關閉
try:
link = driver_wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,".aiq-r_LBtE.qg-inweb-close")))
link.click()
print("首頁彈窗關閉:成功")
except TimeoutException:
print("首頁彈窗關閉:處理超時")
except:
print("首頁彈窗關閉:失敗")
#點擊登入按鈕
try:
login_button = driver_wait.until(EC.presence_of_element_located((By.LINK_TEXT,"登入")))
login_button.click()
print("點擊登入按鈕:成功")
except TimeoutException:
print("點擊登入按鈕:處理超時")
except:
print("點擊登入按鈕:失敗")
#帳號輸入,帳號變數字串化
try:
search_box = driver_wait.until(EC.presence_of_element_located((By.NAME,"email")))
search_box.send_keys(f"{account}")
print("帳號輸入:成功")
except TimeoutException:
print("帳號輸入:超時")
except:
print("帳號輸入:失敗")
#密碼輸入,密碼變數字串化
try:
search_box = driver_wait.until(EC.presence_of_element_located((By.NAME,"password")))
search_box.send_keys(f"{password}")
print("密碼輸入:成功")
except TimeoutException:
print("密碼輸入:超時")
except:
print("密碼輸入:失敗")
#用ENTER點擊按鈕
try:
search_box.send_keys(Keys.ENTER)
print("登入頁點擊登入按鈕:成功")
except:
print("登入頁點擊登入按鈕:失敗")
#登入成功後,預設會回到首頁,所以我們在首頁抓一個關鍵字,來判斷我們是不是回到首頁了
try:
search_box = driver_wait.until(EC.presence_of_element_located((By.LINK_TEXT,"版權到期")))
print("登入:成功")
except TimeoutException:
print("登入:超時")
except:
print("登入:失敗")
#測試結束,關閉瀏覽器並釋放資源
driver.quit()
執行後,我們可以在終端機或是VS code上看到這樣的結果: