Selenium 超时异常未按预期工作
Posted
技术标签:
【中文标题】Selenium 超时异常未按预期工作【英文标题】:Selenium Timeout Exception not working as intended 【发布时间】:2022-01-23 03:55:16 【问题描述】:我是 Python 新手,所以不确定这里出了什么问题。据我了解,当窗口没有聚焦时,Selenium 有时无法定位元素(因此我切换到无头)。所以我正在努力解决这个问题,让它 100% 的时间都有效。
这是错误的样子:
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x00986903+2517251]
Ordinal0 [0x0091F8E1+2095329]
Ordinal0 [0x00822848+1058888]
Ordinal0 [0x0084D448+1233992]
Ordinal0 [0x0084D63B+1234491]
Ordinal0 [0x00877812+1406994]
Ordinal0 [0x0086650A+1336586]
Ordinal0 [0x00875BBF+1399743]
Ordinal0 [0x0086639B+1336219]
Ordinal0 [0x008427A7+1189799]
Ordinal0 [0x00843609+1193481]
GetHandleVerifier [0x00B15904+1577972]
GetHandleVerifier [0x00BC0B97+2279047]
GetHandleVerifier [0x00A16D09+534521]
GetHandleVerifier [0x00A15DB9+530601]
Ordinal0 [0x00924FF9+2117625]
Ordinal0 [0x009298A8+2136232]
Ordinal0 [0x009299E2+2136546]
Ordinal0 [0x00933541+2176321]
BaseThreadInitThunk [0x770EFA29+25]
RtlGetAppContainerNamedObjectPath [0x77B47A9E+286]
RtlGetAppContainerNamedObjectPath [0x77B47A6E+238]
所以我试图找到一个解决方案,即重新运行/再次尝试,但是,它真的很乱:
2021-12-22 04:50:20.920372 Signed in
Password input crashed. Retrying now...
2021-12-22 04:50:31.234082 Loaded profile page
Username input crashed. Retrying now...
2021-12-22 04:52:12.192628 Signed in
Password input crashed. Retrying now...
2021-12-22 04:52:22.473065 Loaded profile page
2021-12-22 04:52:23.174232 Signed in
Password input crashed. Retrying now...
2021-12-22 04:52:33.452513 Loaded profile page
代码如下:
import tkinter as tk
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.common.exceptions import TimeoutException
import threading
import time
from time import sleep
import datetime
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("start-maximized")
root = tk.Tk()
app_width = 300
app_height = 320
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
root.geometry(f'app_widthxapp_height+int(x)+int(y)')
#
ser = Service("C:\Program Files (x86)\chromedriver.exe")
driver = webdriver.Chrome(service=ser, options=options)
wait = WebDriverWait(driver, 50)
testbtn_txt = tk.StringVar()
testbtn = tk.Button(root, textvariable=testbtn_txt, command=lambda:open_browser_func(), font="Arial", bg="#808080", fg="white", height=1, width=10)
testbtn_txt.set("Test")
testbtn.grid(row=10, column=0, columnspan=2, pady=5, padx=5)
def open_browser_func():
global driver
driver.get("https://twitter.com/i/flow/login")
sleep(5)
try:
loginuser = wait.until(EC.visibility_of_element_located((By.NAME, "text")))
loginuser.send_keys("Username", Keys.RETURN)
except TimeoutException:
def retry_sign_in():
print("Username input crashed. Retrying now...")
driver.quit
return open_browser_func()
retrytimer = threading.Timer(5, retry_sign_in)
retrytimer.start()
try:
loginPassword = wait.until(EC.visibility_of_element_located((By.NAME, "password")))
loginPassword.send_keys("Password", Keys.RETURN)
except TimeoutException:
def retry_sign_in2():
print("Password input crashed. Retrying now...")
driver.quit
return open_browser_func()
retrytimer2 = threading.Timer(5, retry_sign_in2)
retrytimer2.start()
ct = datetime.datetime.now()
print(ct, "Signed in")
def logged_in_shot():
driver.get_screenshot_as_file("logged_in_shot.png")
driver.get("https://twitter.com/Username")
ct2 = datetime.datetime.now()
print(ct2, "Loaded profile page")
logged_in_timer = threading.Timer(10, logged_in_shot)
logged_in_timer.start()
return driver
root.mainloop()
【问题讨论】:
所以你仍然拒绝Selenium's focus 您是否在比 Twitter 登录更无害的设置中解决了此方法?也许只是在 google.com 搜索栏上搜索?我发现使用 Selenium 时,一些高配置的登录页面可能会很困难。 没有。我只是希望它在失败时重新聚焦。 @Jack,这是 Selenium 的一个重点问题。被打断时会失去焦点。 【参考方案1】:使用此处的异常处理,您可能希望限制尝试的次数,或者不按您的方式调用原始函数。
try:
loginuser = wait.until(EC.visibility_of_element_located((By.NAME, "text")))
loginuser.send_keys("Username", Keys.RETURN)
except TimeoutException:
def retry_sign_in():
print("Username input crashed. Retrying now...")
driver.quit
return open_browser_func()
retrytimer = threading.Timer(5, retry_sign_in)
retrytimer.start()
您在这里重试,这很好,但是如果您每次都返回 open_browser_func(),如果它继续失败,它将继续运行该函数。如果您通过限制(IE,3 次)并强制执行,您可能会解决此问题。
对于这里的原始问题,我使用了两种解决方案来帮助解决尚未在 Selenium 中加载的元素-
-
使用睡眠或等待功能,虽然有效,但可能很草率。
创建一个函数以等待元素出现在视图中。这往往效果最好。
【讨论】:
重点是,我希望它重新聚焦和/或重新启动功能,以便一切顺利。以上是关于Selenium 超时异常未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章