1. 元素本身属性操作获取元素状态或内容用于断言或逻辑判断。# 假设已定位到元素: element driver.find_element(By.ID, xxx) # 1. 获取元素文本 (获取标签对之间的文本不含 HTML 标签) text_content element.text # 2. 判断元素是否被选中 (常用于单选框 radio、复选框 checkbox) is_checked element.is_selected() # 返回 True/False # 3. 判断元素是否可用 (未被 disabled 禁用) is_usable element.is_enabled() # 返回 True/False # 4. 判断元素是否可见 (在页面上显示且宽高不为0) is_visible element.is_displayed() # 返回 True/False 模拟点击element.click() 模拟输入element.send_keys() 模拟清除element.clear() 页面刷新element.refresh()2. 浏览器窗口操作控制浏览器窗口的行为和生命周期。# 1. 最大化窗口 driver.maximize_window() # 2. 刷新页面 driver.refresh() # 3. 后退 (相当于点击浏览器后退按钮) driver.back() # 4. 前进 (相当于点击浏览器前进按钮) driver.forward() # 5. 退出 (关闭所有关联窗口并结束驱动进程务必在脚本末尾使用) driver.quit() # 注意: driver.close() 仅关闭当前焦点窗口3. 滚动条处理 (JavaScript 执行)Selenium 无法直接操作滚动条需通过执行 JS 代码实现。# 1. 定义 JS 字符串 # 方式 A: 滚动到绝对坐标 (x横向, y纵向) js_scroll_abs window.scrollTo(0, 500) # 方式 B: 滚动到底部 js_scroll_bottom window.scrollTo(0, document.body.scrollHeight) # 方式 C: 滚动到特定元素位置 (需先定位元素) # element driver.find_element(By.ID, footer) # js_scroll_elem arguments[0].scrollIntoView(); # 2. 执行 JS 代码 driver.execute_script(js_scroll_abs)4. 截图处理用于自动化测试失败时的现场保留或验证。# 截取整个页面并保存为文件 # 参数为文件路径 (支持 .png) driver.get_screenshot_as_file(./screenshots/error_page.png) # 或者获取二进制数据 (不保存文件用于内存处理) # img_data driver.get_screenshot_as_png()5. 多窗口/标签页切换当点击链接打开新标签页时需切换句柄Handle才能操作新窗口。# 1. 获取所有窗口句柄 (列表形式) handles driver.window_handles # 2. 切换到指定窗口 (通过下标或具体句柄值) # 切换到最新打开的窗口 (通常是列表最后一个) driver.switch_to.window(handles[-1]) # 切换到第一个窗口 driver.switch_to.window(handles[0]) # 3. (可选) 关闭当前窗口后切回主窗口 # driver.close() # driver.switch_to.window(driver.window_handles[0])6. Frame/Iframe 切换若元素位于iframe或frame内部必须先切换进入操作完后再切出。# 1. 定位到 frame 元素 frame_element driver.find_element(By.ID, login_frame) # 或者直接通过 ID/Name 字符串: driver.switch_to.frame(login_frame) # 2. 切换到该 frame (之后只能操作 frame 内部的元素) driver.switch_to.frame(frame_element) # ... 执行内部元素操作 ... # 3. 切回主文档 (默认内容)以便操作外部元素 driver.switch_to.default_content() # (可选) 切换到父级 frame (若嵌套多层) # driver.switch_to.parent_frame()7. 时间等待机制解决页面加载慢导致的NoSuchElementException。A. 强制等待 (不推荐作为主要手段)import time # 程序暂停执行指定秒数无论页面是否加载完成 time.sleep(5)B. 隐式等待 (全局设置)# 设置全局超时时间。若元素未立即出现轮询查找直到超时。 # 只需设置一次对后续所有 find_element 生效。 driver.implicitly_wait(10)C. 显式等待 (推荐局部精准控制)配合WebDriverWait和expected_conditions(EC) 使用。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 初始化等待对象最大等待10秒每0.5秒检查一次 wait WebDriverWait(driver, 10, poll_frequency0.5) # 场景 1: 等待元素可见 (推荐确保元素不仅能找到还能交互) element wait.until( EC.visibility_of_element_located((By.ID, username)) ) # 场景 2: 等待元素存在 (仅在 DOM 中不一定可见) element wait.until( EC.presence_of_element_located((By.ID, username)) ) # 场景 3: 等待元素可点击 element wait.until( EC.element_to_be_clickable((By.ID, submit_btn)) ) # 场景 4: 自定义条件 (Lambda 表达式) element wait.until( lambda x: x.find_element(By.ID, dynamic_content) )8. 鼠标与键盘操作用于处理悬停 (Hover)、拖拽 (Drag Drop)、右键点击、双击等复杂交互。from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys # 1. 初始化动作链 actions ActionChains(driver) # 2. 鼠标悬停 (二级菜单常用) # 先定位到父级菜单元素 menu_element driver.find_element(By.ID, menu_item) actions.move_to_element(menu_element).perform() # .perform() 必须调用以执行动作 # action.perform() 执行鼠标动作 # 3. 右键点击 # actions.context_click(element).perform() # 4. 双击 # actions.double_click(element).perform() # 5. 拖拽 (从源元素拖到目标元素) # source driver.find_element(By.ID, drag) # target driver.find_element(By.ID, drop) # actions.drag_and_drop(source, target).perform() # 6. 键盘组合键 (如: CtrlA 全选, CtrlC 复制) # input_box driver.find_element(By.ID, content) # input_box.send_keys(Keys.CONTROL, a) # 全选 # input_box.send_keys(Keys.CONTROL, c) # 复制9. 浏览器原生弹框处理针对window.alert,window.confirm,window.prompt生成的原生弹窗无法用普通元素定位。from selenium.webdriver.common.alert import Alert # 1. 切换到弹框 alert driver.switch_to.alert # 2. 获取弹框文本内容 alert_text alert.text # 3. 点击“确定” (接受) alert.accept() # 4. 点击“取消” (解散仅适用于 confirm/prompt) # alert.dismiss() # 5. 在 prompt 弹框中输入内容 # alert.send_keys(输入的内容) # alert.accept()10. 下拉框处理 (Select)针对标准的select标签Selenium 提供了专用类Select。from selenium.webdriver.support.ui import Select # 1. 定位到 select 元素 select_element driver.find_element(By.ID, province) dropdown Select(select_element) # 2. 通过可见文本选择 dropdown.select_by_visible_text(北京市) # 3. 通过 value 属性值选择 dropdown.select_by_value(BJ) # 4. 通过索引选择 (从0开始) dropdown.select_by_index(1) # 5. 取消选择 (仅支持多选下拉框) # dropdown.deselect_all() # dropdown.deselect_by_visible_text(北京市) # 6. 判断是否多选 is_multi dropdown.is_multiple11. 其他 JavaScript 高级用法除了滚动条JS 还可用于修改元素属性绕过前端限制或直接点击。# 1. 移除元素的 disabled 属性 (强制启用按钮) # btn driver.find_element(By.ID, submit_btn) # driver.execute_script(arguments[0].removeAttribute(disabled), btn) # 2. 直接通过 JS 点击元素 (当 element.click() 被遮挡或失效时) # driver.execute_script(arguments[0].click(), btn) # 3. 修改输入框的值 (绕过某些监听事件限制) # input_box driver.find_element(By.ID, username) # driver.execute_script(arguments[0].valueadmin, input_box) # 4. 获取页面标题或当前 URL (通常直接用 driver.title / driver.current_url但也可用 JS) # title driver.execute_script(return document.title)12. 定位不到元素排查清单 (Troubleshooting) ️当报错NoSuchElementException或ElementNotInteractableException时按此顺序检查序号可能原因解决方案1元素未加载页面慢元素还没出来。解决加显式等待(WebDriverWait)。2在 Frame 里元素在iframe内部主文档找不到。解决switch_to.frame()。3在新窗口点击后开了新标签页焦点还在旧窗口。解决switch_to.window()。4需要悬停元素是隐藏菜单需鼠标移上去才显示。解决ActionChains.move_to_element()。5属性动态变化ID 或 Class 是随机生成的 (如idbtn_123)。解决改用 XPath 模糊匹配或稳定属性。6元素被遮挡有广告弹窗或透明层盖住了元素。解决先关闭弹窗或用execute_script强制点击。7不在可视区元素在屏幕下方未滚动到。解决scrollIntoView滚动。8非标准下拉框不是select标签而是divulli模拟的。解决直接用普通元素定位点击不要用Select类。13. 验证码处理方案 (Captcha Handling) ️Selenium无法直接识别图形验证码。根据项目阶段和验证码类型通常采用以下 4 种策略方案 A测试环境“万能码/后门” (⭐⭐⭐⭐⭐ 推荐)场景公司内部测试环境。做法联系开发人员在测试环境设置一个“万能验证码”如固定输入8888或1234即可通过或者在代码中判断如果是测试账号则跳过验证逻辑。优点最稳定、执行最快、维护成本最低。缺点需要开发配合生产环境不可用。# 示例测试环境固定验证码 if env test: code_input.send_keys(8888) # 开发约定的万能码方案 BCookie 绕过法 (⭐⭐⭐⭐ 推荐)场景登录一次后后续操作不需要重复登录。做法手动登录一次成功网站。获取浏览器的Cookie(特别是包含用户身份信息的 Session ID)。在自动化脚本启动浏览器后先注入该 Cookie然后刷新页面直接处于“已登录”状态跳过验证码步骤。优点无需识别验证码模拟真实用户状态。缺点Cookie 有有效期过期需重新获取首次仍需人工或识别介入。# 1. 打开首页 driver.get(http://example.com) # 2. 添加 Cookie (格式需与浏览器一致) driver.add_cookie({name: SESSION_ID, value: abc123xyz..., domain: example.com}) # 3. 刷新页面生效 driver.refresh() # 此时已自动登录可直接操作内部页面方案 C第三方打码平台 (⭐⭐⭐ 通用方案)场景必须通过真实验证码且无后门。做法调用第三方 OCR 识别平台 API如超级鹰、云打码、2Captcha 等。流程截图验证码 - 发送图片到平台 - 平台返回识别结果 - 填入输入框。优点能解决大多数常见图形验证码。缺点收费、有网络延迟、识别率非 100%、依赖外部服务稳定性。# 伪代码示例 (以超级鹰为例) from chaojiying import ChaojiyingClient # 1. 截取验证码元素图片 element driver.find_element(By.ID, captcha_img) element.screenshot(./code.png) # 2. 调用第三方 API client ChaojiyingClient(用户名, 密码, 软件ID) result client.post_file(9004, ./code.png) # 9004代表验证码类型 # 3. 获取识别结果并输入 if result[ret] 0: code result[pic_str] driver.find_element(By.ID, captcha_input).send_keys(code) else: print(识别失败)方案 D本地 OCR 库 (⭐⭐ 简单验证码)场景验证码非常简单纯数字、无干扰线、字体清晰。做法使用tesseract-ocr(Python 库pytesseract) 本地识别。优点免费、无需网络。缺点对复杂验证码干扰线、扭曲、点选识别率极低配置环境麻烦。import pytesseract from PIL import Image # 1. 截图 element.screenshot(./code.png) # 2. 图片预处理 (去色、二值化等提高识别率 - 需OpenCV配合) # ... 预处理代码 ... # 3. 识别 text pytesseract.image_to_string(Image.open(./code.png), langeng) driver.find_element(By.ID, captcha_input).send_keys(text.strip()) 核心建议首选找开发加测试后门方案 A。次选Cookie 绕过方案 B适合登录后的大流程测试。最后手段第三方打码方案 C仅在必须验证登录功能且无其他办法时使用。避免不要试图用 Selenium 自己去“猜”或硬编码复杂的动态验证码。 Selenium 核心操作与最佳实践终极速查表场景分类推荐方法 / 核心类关键语法/注意点 最佳实践建议基础交互click(),send_keys(),clear()输入前建议先clear()清空旧值操作前先检查is_displayed()和is_enabled()确保元素可见且可用状态断言element.text,is_selected()is_enabled(),is_displayed()text仅获取可见文本is_系列返回布尔值不要只依赖find_element不报错务必用is_系列做逻辑判断复杂鼠标ActionChains必须调用.perform()才会执行动作用于悬停 (Hover)、拖拽、右键链式调用更清晰原生弹窗driver.switch_to.alert必须先切换上下文才能操作(.accept(),.dismiss())仅处理浏览器原生 Alert/Confirm/Prompt非原生模态框需用普通定位下拉菜单Select类仅限select标签(select_by_visible_text等)若是divul模拟的下拉框直接使用普通元素定位点击勿用 Select 类滚动/JSdriver.execute_script()JS 是操作滚动条、修改属性的唯一途径优先用scrollIntoView滚动到元素可用于移除disabled属性或强制点击Frame 切换switch_to.frame()switch_to.default_content()进得去必须出得来操作完嵌套页面后务必立即调用default_content()切回主文档避免后续定位失败多窗口window_handlesswitch_to.window()句柄是动态列表需重新获取切换到新窗口操作完后若需回主窗口记得再次切换句柄等待机制WebDriverWaitEC拒绝滥用time.sleep()慎用全局隐式等待首选显式等待(精准控制)次选隐式等待尽量避免强制等待以提高脚本稳定性环境清理driver.quit()关闭所有窗口并结束驱动进程务必放在finally块或tearDown方法中确保即使报错也能执行资源释放
Selenium 常用操作 API
1. 元素本身属性操作获取元素状态或内容用于断言或逻辑判断。# 假设已定位到元素: element driver.find_element(By.ID, xxx) # 1. 获取元素文本 (获取标签对之间的文本不含 HTML 标签) text_content element.text # 2. 判断元素是否被选中 (常用于单选框 radio、复选框 checkbox) is_checked element.is_selected() # 返回 True/False # 3. 判断元素是否可用 (未被 disabled 禁用) is_usable element.is_enabled() # 返回 True/False # 4. 判断元素是否可见 (在页面上显示且宽高不为0) is_visible element.is_displayed() # 返回 True/False 模拟点击element.click() 模拟输入element.send_keys() 模拟清除element.clear() 页面刷新element.refresh()2. 浏览器窗口操作控制浏览器窗口的行为和生命周期。# 1. 最大化窗口 driver.maximize_window() # 2. 刷新页面 driver.refresh() # 3. 后退 (相当于点击浏览器后退按钮) driver.back() # 4. 前进 (相当于点击浏览器前进按钮) driver.forward() # 5. 退出 (关闭所有关联窗口并结束驱动进程务必在脚本末尾使用) driver.quit() # 注意: driver.close() 仅关闭当前焦点窗口3. 滚动条处理 (JavaScript 执行)Selenium 无法直接操作滚动条需通过执行 JS 代码实现。# 1. 定义 JS 字符串 # 方式 A: 滚动到绝对坐标 (x横向, y纵向) js_scroll_abs window.scrollTo(0, 500) # 方式 B: 滚动到底部 js_scroll_bottom window.scrollTo(0, document.body.scrollHeight) # 方式 C: 滚动到特定元素位置 (需先定位元素) # element driver.find_element(By.ID, footer) # js_scroll_elem arguments[0].scrollIntoView(); # 2. 执行 JS 代码 driver.execute_script(js_scroll_abs)4. 截图处理用于自动化测试失败时的现场保留或验证。# 截取整个页面并保存为文件 # 参数为文件路径 (支持 .png) driver.get_screenshot_as_file(./screenshots/error_page.png) # 或者获取二进制数据 (不保存文件用于内存处理) # img_data driver.get_screenshot_as_png()5. 多窗口/标签页切换当点击链接打开新标签页时需切换句柄Handle才能操作新窗口。# 1. 获取所有窗口句柄 (列表形式) handles driver.window_handles # 2. 切换到指定窗口 (通过下标或具体句柄值) # 切换到最新打开的窗口 (通常是列表最后一个) driver.switch_to.window(handles[-1]) # 切换到第一个窗口 driver.switch_to.window(handles[0]) # 3. (可选) 关闭当前窗口后切回主窗口 # driver.close() # driver.switch_to.window(driver.window_handles[0])6. Frame/Iframe 切换若元素位于iframe或frame内部必须先切换进入操作完后再切出。# 1. 定位到 frame 元素 frame_element driver.find_element(By.ID, login_frame) # 或者直接通过 ID/Name 字符串: driver.switch_to.frame(login_frame) # 2. 切换到该 frame (之后只能操作 frame 内部的元素) driver.switch_to.frame(frame_element) # ... 执行内部元素操作 ... # 3. 切回主文档 (默认内容)以便操作外部元素 driver.switch_to.default_content() # (可选) 切换到父级 frame (若嵌套多层) # driver.switch_to.parent_frame()7. 时间等待机制解决页面加载慢导致的NoSuchElementException。A. 强制等待 (不推荐作为主要手段)import time # 程序暂停执行指定秒数无论页面是否加载完成 time.sleep(5)B. 隐式等待 (全局设置)# 设置全局超时时间。若元素未立即出现轮询查找直到超时。 # 只需设置一次对后续所有 find_element 生效。 driver.implicitly_wait(10)C. 显式等待 (推荐局部精准控制)配合WebDriverWait和expected_conditions(EC) 使用。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 初始化等待对象最大等待10秒每0.5秒检查一次 wait WebDriverWait(driver, 10, poll_frequency0.5) # 场景 1: 等待元素可见 (推荐确保元素不仅能找到还能交互) element wait.until( EC.visibility_of_element_located((By.ID, username)) ) # 场景 2: 等待元素存在 (仅在 DOM 中不一定可见) element wait.until( EC.presence_of_element_located((By.ID, username)) ) # 场景 3: 等待元素可点击 element wait.until( EC.element_to_be_clickable((By.ID, submit_btn)) ) # 场景 4: 自定义条件 (Lambda 表达式) element wait.until( lambda x: x.find_element(By.ID, dynamic_content) )8. 鼠标与键盘操作用于处理悬停 (Hover)、拖拽 (Drag Drop)、右键点击、双击等复杂交互。from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys # 1. 初始化动作链 actions ActionChains(driver) # 2. 鼠标悬停 (二级菜单常用) # 先定位到父级菜单元素 menu_element driver.find_element(By.ID, menu_item) actions.move_to_element(menu_element).perform() # .perform() 必须调用以执行动作 # action.perform() 执行鼠标动作 # 3. 右键点击 # actions.context_click(element).perform() # 4. 双击 # actions.double_click(element).perform() # 5. 拖拽 (从源元素拖到目标元素) # source driver.find_element(By.ID, drag) # target driver.find_element(By.ID, drop) # actions.drag_and_drop(source, target).perform() # 6. 键盘组合键 (如: CtrlA 全选, CtrlC 复制) # input_box driver.find_element(By.ID, content) # input_box.send_keys(Keys.CONTROL, a) # 全选 # input_box.send_keys(Keys.CONTROL, c) # 复制9. 浏览器原生弹框处理针对window.alert,window.confirm,window.prompt生成的原生弹窗无法用普通元素定位。from selenium.webdriver.common.alert import Alert # 1. 切换到弹框 alert driver.switch_to.alert # 2. 获取弹框文本内容 alert_text alert.text # 3. 点击“确定” (接受) alert.accept() # 4. 点击“取消” (解散仅适用于 confirm/prompt) # alert.dismiss() # 5. 在 prompt 弹框中输入内容 # alert.send_keys(输入的内容) # alert.accept()10. 下拉框处理 (Select)针对标准的select标签Selenium 提供了专用类Select。from selenium.webdriver.support.ui import Select # 1. 定位到 select 元素 select_element driver.find_element(By.ID, province) dropdown Select(select_element) # 2. 通过可见文本选择 dropdown.select_by_visible_text(北京市) # 3. 通过 value 属性值选择 dropdown.select_by_value(BJ) # 4. 通过索引选择 (从0开始) dropdown.select_by_index(1) # 5. 取消选择 (仅支持多选下拉框) # dropdown.deselect_all() # dropdown.deselect_by_visible_text(北京市) # 6. 判断是否多选 is_multi dropdown.is_multiple11. 其他 JavaScript 高级用法除了滚动条JS 还可用于修改元素属性绕过前端限制或直接点击。# 1. 移除元素的 disabled 属性 (强制启用按钮) # btn driver.find_element(By.ID, submit_btn) # driver.execute_script(arguments[0].removeAttribute(disabled), btn) # 2. 直接通过 JS 点击元素 (当 element.click() 被遮挡或失效时) # driver.execute_script(arguments[0].click(), btn) # 3. 修改输入框的值 (绕过某些监听事件限制) # input_box driver.find_element(By.ID, username) # driver.execute_script(arguments[0].valueadmin, input_box) # 4. 获取页面标题或当前 URL (通常直接用 driver.title / driver.current_url但也可用 JS) # title driver.execute_script(return document.title)12. 定位不到元素排查清单 (Troubleshooting) ️当报错NoSuchElementException或ElementNotInteractableException时按此顺序检查序号可能原因解决方案1元素未加载页面慢元素还没出来。解决加显式等待(WebDriverWait)。2在 Frame 里元素在iframe内部主文档找不到。解决switch_to.frame()。3在新窗口点击后开了新标签页焦点还在旧窗口。解决switch_to.window()。4需要悬停元素是隐藏菜单需鼠标移上去才显示。解决ActionChains.move_to_element()。5属性动态变化ID 或 Class 是随机生成的 (如idbtn_123)。解决改用 XPath 模糊匹配或稳定属性。6元素被遮挡有广告弹窗或透明层盖住了元素。解决先关闭弹窗或用execute_script强制点击。7不在可视区元素在屏幕下方未滚动到。解决scrollIntoView滚动。8非标准下拉框不是select标签而是divulli模拟的。解决直接用普通元素定位点击不要用Select类。13. 验证码处理方案 (Captcha Handling) ️Selenium无法直接识别图形验证码。根据项目阶段和验证码类型通常采用以下 4 种策略方案 A测试环境“万能码/后门” (⭐⭐⭐⭐⭐ 推荐)场景公司内部测试环境。做法联系开发人员在测试环境设置一个“万能验证码”如固定输入8888或1234即可通过或者在代码中判断如果是测试账号则跳过验证逻辑。优点最稳定、执行最快、维护成本最低。缺点需要开发配合生产环境不可用。# 示例测试环境固定验证码 if env test: code_input.send_keys(8888) # 开发约定的万能码方案 BCookie 绕过法 (⭐⭐⭐⭐ 推荐)场景登录一次后后续操作不需要重复登录。做法手动登录一次成功网站。获取浏览器的Cookie(特别是包含用户身份信息的 Session ID)。在自动化脚本启动浏览器后先注入该 Cookie然后刷新页面直接处于“已登录”状态跳过验证码步骤。优点无需识别验证码模拟真实用户状态。缺点Cookie 有有效期过期需重新获取首次仍需人工或识别介入。# 1. 打开首页 driver.get(http://example.com) # 2. 添加 Cookie (格式需与浏览器一致) driver.add_cookie({name: SESSION_ID, value: abc123xyz..., domain: example.com}) # 3. 刷新页面生效 driver.refresh() # 此时已自动登录可直接操作内部页面方案 C第三方打码平台 (⭐⭐⭐ 通用方案)场景必须通过真实验证码且无后门。做法调用第三方 OCR 识别平台 API如超级鹰、云打码、2Captcha 等。流程截图验证码 - 发送图片到平台 - 平台返回识别结果 - 填入输入框。优点能解决大多数常见图形验证码。缺点收费、有网络延迟、识别率非 100%、依赖外部服务稳定性。# 伪代码示例 (以超级鹰为例) from chaojiying import ChaojiyingClient # 1. 截取验证码元素图片 element driver.find_element(By.ID, captcha_img) element.screenshot(./code.png) # 2. 调用第三方 API client ChaojiyingClient(用户名, 密码, 软件ID) result client.post_file(9004, ./code.png) # 9004代表验证码类型 # 3. 获取识别结果并输入 if result[ret] 0: code result[pic_str] driver.find_element(By.ID, captcha_input).send_keys(code) else: print(识别失败)方案 D本地 OCR 库 (⭐⭐ 简单验证码)场景验证码非常简单纯数字、无干扰线、字体清晰。做法使用tesseract-ocr(Python 库pytesseract) 本地识别。优点免费、无需网络。缺点对复杂验证码干扰线、扭曲、点选识别率极低配置环境麻烦。import pytesseract from PIL import Image # 1. 截图 element.screenshot(./code.png) # 2. 图片预处理 (去色、二值化等提高识别率 - 需OpenCV配合) # ... 预处理代码 ... # 3. 识别 text pytesseract.image_to_string(Image.open(./code.png), langeng) driver.find_element(By.ID, captcha_input).send_keys(text.strip()) 核心建议首选找开发加测试后门方案 A。次选Cookie 绕过方案 B适合登录后的大流程测试。最后手段第三方打码方案 C仅在必须验证登录功能且无其他办法时使用。避免不要试图用 Selenium 自己去“猜”或硬编码复杂的动态验证码。 Selenium 核心操作与最佳实践终极速查表场景分类推荐方法 / 核心类关键语法/注意点 最佳实践建议基础交互click(),send_keys(),clear()输入前建议先clear()清空旧值操作前先检查is_displayed()和is_enabled()确保元素可见且可用状态断言element.text,is_selected()is_enabled(),is_displayed()text仅获取可见文本is_系列返回布尔值不要只依赖find_element不报错务必用is_系列做逻辑判断复杂鼠标ActionChains必须调用.perform()才会执行动作用于悬停 (Hover)、拖拽、右键链式调用更清晰原生弹窗driver.switch_to.alert必须先切换上下文才能操作(.accept(),.dismiss())仅处理浏览器原生 Alert/Confirm/Prompt非原生模态框需用普通定位下拉菜单Select类仅限select标签(select_by_visible_text等)若是divul模拟的下拉框直接使用普通元素定位点击勿用 Select 类滚动/JSdriver.execute_script()JS 是操作滚动条、修改属性的唯一途径优先用scrollIntoView滚动到元素可用于移除disabled属性或强制点击Frame 切换switch_to.frame()switch_to.default_content()进得去必须出得来操作完嵌套页面后务必立即调用default_content()切回主文档避免后续定位失败多窗口window_handlesswitch_to.window()句柄是动态列表需重新获取切换到新窗口操作完后若需回主窗口记得再次切换句柄等待机制WebDriverWaitEC拒绝滥用time.sleep()慎用全局隐式等待首选显式等待(精准控制)次选隐式等待尽量避免强制等待以提高脚本稳定性环境清理driver.quit()关闭所有窗口并结束驱动进程务必放在finally块或tearDown方法中确保即使报错也能执行资源释放