Selenium如何实现等待控制台输入短信验证码的超时控制逻辑?
解决方案
问题根源
WebDriverWait是Selenium提供的页面元素显式等待工具,仅对页面DOM的状态变化生效,你没有在后面拼接.until(判定条件)的情况下,这行代码不会产生任何等待/超时逻辑,也完全无法检测控制台的用户输入行为,所以无法实现输入超时判断。
Python原生的input()是阻塞调用,只要用户不输入就会一直挂起,本身没有超时机制,需要自己额外实现。
修复方案
我们可以用Python标准库的threading模块实现跨平台的带超时输入功能,不需要安装第三方依赖:
第一步:先实现带超时的输入工具函数
import threading class InputTimeoutError(Exception): pass def timed_input(prompt, timeout=180): result = None def input_thread(): nonlocal result result = input(prompt).strip() t = threading.Thread(target=input_thread) t.daemon = True t.start() t.join(timeout) if t.is_alive(): raise InputTimeoutError("输入超时") return result
第二步:替换你原有问题代码段的对应逻辑
把原来的WebDriverWait(driver, 180)那两行替换成调用上面的timed_input,同时捕获超时异常即可:
try: # 删掉原来没用的WebDriverWait(driver, 180)行 verification = timed_input('Waiting for SMS... you have 180 seconds: ', timeout=180) while len(verification) != 4: verification = timed_input('Must be 4 numbers: ', timeout=180) driver.find_element_by_name('OtpCode').send_keys(verification) try: WebDriverWait(driver, 20).until(EC.element_to_be_clickable( (By.XPATH, "//button[@id='confirm__button']"))).click() time.sleep(8) print('LOGGIN SUCCESFUL!.') self.get_categories(driver) except selenium.common.exceptions.ElementClickInterceptedException: print('Code expired!.') time.sleep(10) driver.close() self.login(url) # 新增捕获我们自定义的输入超时异常 except InputTimeoutError: print('输入超时!180秒内未收到验证码输入') driver.close() return None except selenium.common.exceptions.TimeoutException: print('Timeout!!!.') driver.close() return None
额外优化提示
- 你原来的验证码长度判断用
while循环比多次if判断更合理,避免用户多次输入错误长度的情况 - 所有的
time.sleep()都可以替换成WebDriverWait的显式等待,提升脚本运行效率,也避免因为网络波动导致的元素未加载报错
内容的提问来源于stack exchange,提问作者tadeo soresi
相关产品推荐
相关产品推荐

