Python Selenium报'bool' object is not callable及验证码定位报错求解
问题原因及修复方案
两个报错的根因
- 第一个
TypeError: 'bool' object is not callable报错:WebDriverWait的until方法要求传入可调用的判断逻辑,你直接传入了recaptchaSolved.is_displayed()的执行结果(布尔值),不符合参数要求。 - 第二个
NoSuchElementException报错:你在验证码刚加载完成时就立刻查找包含Solved文本的元素,此时自动验证插件还没完成校验,对应的标识元素还没有生成,自然找不到。同时find_element_by_partial_link_text仅能匹配<a>标签的文本,若插件生成的Solved提示不是链接类型,也会匹配失败。
修复步骤
- 首先补充导入Selenium的显式等待依赖模块:
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By
- 修改验证码判断逻辑:先判断页面是否存在验证码,存在的话再用显式等待等待验证完成标识出现,不要提前查找未生成的元素。
- 额外优化:原代码读取账号时循环里固定取第1行的账号密码,建议改为取当前循环行的内容。
修改后的完整代码
## necessary import codes from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import time import xlrd import random ## random waiting time random_Get_Time = random.randint(1,5) ## importing data file data_File_Path = "C:/Users/doguk/Desktop/Python/DataFile.xls" ## targeting the data dataFile = xlrd.open_workbook(data_File_Path) accountInfo = dataFile.sheet_by_name("account_Ids_And_Passwords") usernameCount = accountInfo.nrows passwordCount = accountInfo.ncols # 修复原代码固定取第1行账号的问题,如需多账号循环可把后续逻辑缩进放到for循环内 for curr_row in range(1, usernameCount): username = accountInfo.cell_value(curr_row, 0) password = accountInfo.cell_value(curr_row, 1) ## setting up recaptcha solver plugin to browser recaptcha_Solver_Plugin_Path = "C:/Users/doguk/Desktop/Python/plugin.zip" ## adding recaptcha solver plugin to browser recaptchaSolverAddOptions = webdriver.ChromeOptions() recaptchaSolverAddOptions.add_extension(recaptcha_Solver_Plugin_Path) ## browser driver code chrome_Driver_Path = "C:/Users/doguk/Desktop/Python/chromedriver" driver = webdriver.Chrome(chrome_Driver_Path, options=recaptchaSolverAddOptions) ## enter the browser driver.get("**URL**") time.sleep(random_Get_Time) ## fullscreen code driver.maximize_window() ## filling account infos login_Form_Username = driver.find_element_by_id('username') login_Form_Username.send_keys(username) time.sleep(random_Get_Time) login_Form_Password = driver.find_element_by_id('password') login_Form_Password.send_keys(password) ## 修复后的验证码等待逻辑 # 先判断是否存在验证码,避免没有验证码时直接报错 recaptcha_list = driver.find_elements_by_class_name('g-recaptcha') if len(recaptcha_list) > 0 and recaptcha_list[0].is_displayed(): # 显式等待最多120秒,直到Solved标识出现,可根据插件实际验证速度调整超时时间 WebDriverWait(driver, 120).until( EC.visibility_of_element_located((By.XPATH, "//*[contains(text(),'Solved')]")) ) else: time.sleep(random_Get_Time) ## log in to platform login_Button = driver.find_element_by_class_name('btn') login_Button.click() time.sleep(random_Get_Time) ## logout from driver driver.quit()
逻辑说明
- 用
find_elements查找验证码元素,返回空列表就说明页面没有验证码,直接走短等待逻辑即可 - 显式等待超时时间设置为120秒,足够插件完成自动验证,验证完成后会立刻执行后续登录操作,比固定休眠110秒效率更高
- 如果你的插件完成验证后的提示不是
Solved文本,可以手动打开页面看插件验证完成后的元素内容,替换XPATH里的匹配文本即可。
内容的提问来源于stack exchange,提问作者Doğukan Yılmaz
相关产品推荐
相关产品推荐

