跳到主要内容Selenium 常用操作 API 指南 | 极客日志Python大前端
Selenium 常用操作 API 指南
Selenium 自动化测试涵盖元素属性获取、窗口控制、滚动条处理、截图、多窗口切换、Frame 切换、等待机制、鼠标键盘操作、弹框及下拉框处理。通过显式等待解决加载问题,利用 JavaScript 执行高级操作。针对验证码提供万能码、Cookie 绕过、第三方打码及本地 OCR 四种方案。最后总结常见定位失败排查清单及最佳实践速查表,提升脚本稳定性。
活在当下1 浏览 1. 元素本身属性操作
获取元素状态或内容,用于断言或逻辑判断。
text_content = element.text
is_checked = element.is_selected()
is_usable = element.is_enabled()
is_visible = element.is_displayed()
2. 浏览器窗口操作
driver.maximize_window()
driver.refresh()
driver.back()
driver.forward()
driver.quit()
3. 滚动条处理 (JavaScript 执行)
Selenium 无法直接操作滚动条,需通过执行 JS 代码实现。
js_scroll_abs = "window.scrollTo(0, 500)"
js_scroll_bottom = "window.scrollTo(0, document.body.scrollHeight)"
driver.execute_script(js_scroll_abs)
4. 截图处理
driver.get_screenshot_as_file("./screenshots/error_page.png")
5. 多窗口/标签页切换
当点击链接打开新标签页时,需切换句柄(Handle)才能操作新窗口。
handles = driver.window_handles
driver.switch_to.window(handles[-1])
driver.switch_to.window(handles[0])
6. Frame/Iframe 切换
若元素位于 <iframe> 或 <frame> 内部,必须先切换进入,操作完后再切出。
frame_element = driver.find_element(By.ID, "login_frame")
driver.switch_to.frame(frame_element)
driver.switch_to.default_content()
7. 时间等待机制
解决页面加载慢导致的 NoSuchElementException。
A. 强制等待 (不推荐作为主要手段)
import time
time.sleep(5)
B. 隐式等待 (全局设置)
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
wait = WebDriverWait(driver, 10, poll_frequency=0.5)
element = wait.until(
EC.visibility_of_element_located((By.ID, "username"))
)
element = wait.until(
EC.presence_of_element_located((By.ID, "username"))
)
element = wait.until(
EC.element_to_be_clickable((By.ID, "submit_btn"))
)
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
actions = ActionChains(driver)
menu_element = driver.find_element(By.ID, "menu_item")
actions.move_to_element(menu_element).perform()
9. 浏览器原生弹框处理
针对 window.alert, window.confirm, window.prompt 生成的原生弹窗,无法用普通元素定位。
from selenium.webdriver.common.alert import Alert
alert = driver.switch_to.alert
alert_text = alert.text
alert.accept()
10. 下拉框处理 (Select)
针对标准的 <select> 标签,Selenium 提供了专用类 Select。
from selenium.webdriver.support.ui import Select
select_element = driver.find_element(By.ID, "province")
dropdown = Select(select_element)
dropdown.select_by_visible_text("北京市")
dropdown.select_by_value("BJ")
dropdown.select_by_index(1)
is_multi = dropdown.is_multiple
11. 其他 JavaScript 高级用法
除了滚动条,JS 还可用于修改元素属性(绕过前端限制)或直接点击。
12. 定位不到元素?排查清单 (Troubleshooting)
当报错 NoSuchElementException 或 ElementNotInteractableException 时,按此顺序检查:
| 序号 | 可能原因 | 解决方案 |
|---|
| 1 | 元素未加载 | 页面慢,元素还没出来。解决:加显式等待 (WebDriverWait)。 |
| 2 | 在 Frame 里 | 元素在 <iframe> 内部,主文档找不到。解决:switch_to.frame()。 |
| 3 | 在新窗口 | 点击后开了新标签页,焦点还在旧窗口。解决:switch_to.window()。 |
| 4 | 需要悬停 | 元素是隐藏菜单,需鼠标移上去才显示。解决:ActionChains.move_to_element()。 |
| 5 | 属性动态变化 | ID 或 Class 是随机生成的 (如 id="btn_123" )。解决:改用 XPath 模糊匹配或稳定属性。 |
| 6 | 元素被遮挡 | 有广告弹窗或透明层盖住了元素。解决:先关闭弹窗,或用 execute_script 强制点击。 |
| 7 | 不在可视区 | 元素在屏幕下方,未滚动到。解决:scrollIntoView 滚动。 |
| 8 | 非标准下拉框 | 不是 <select> 标签,而是 div+ul+li 模拟的。解决:直接用普通元素定位点击,不要用 Select 类。 |
13. 验证码处理方案 (Captcha Handling)
Selenium 无法直接识别图形验证码。根据项目阶段和验证码类型,通常采用以下 4 种策略:
方案 A:测试环境'万能码/后门' (⭐⭐⭐⭐⭐ 推荐)
场景:公司内部测试环境。
做法:联系开发人员,在测试环境设置一个'万能验证码'(如固定输入 8888 或 1234 即可通过),或者在代码中判断如果是测试账号则跳过验证逻辑。
优点:最稳定、执行最快、维护成本最低。
缺点:需要开发配合,生产环境不可用。
if env == "test":
code_input.send_keys("8888")
方案 B:Cookie 绕过法 (⭐⭐⭐⭐ 推荐)
场景:登录一次后,后续操作不需要重复登录。
做法:
- 手动登录一次成功网站。
- 获取浏览器的
Cookie (特别是包含用户身份信息的 Session ID)。
- 在自动化脚本启动浏览器后,先注入该 Cookie,然后刷新页面,直接处于'已登录'状态,跳过验证码步骤。
优点:无需识别验证码,模拟真实用户状态。
缺点:Cookie 有有效期,过期需重新获取;首次仍需人工或识别介入。
driver.get("http://example.com")
driver.add_cookie({"name": "SESSION_ID", "value": "abc123xyz...", "domain": "example.com"})
driver.refresh()
方案 C:第三方打码平台 (⭐⭐⭐ 通用方案)
场景:必须通过真实验证码,且无后门。
做法:调用第三方 OCR 识别平台 API(如:超级鹰、云打码、2Captcha 等)。
流程:截图验证码 -> 发送图片到平台 -> 平台返回识别结果 -> 填入输入框。
优点:能解决大多数常见图形验证码。
缺点:收费、有网络延迟、识别率非 100%、依赖外部服务稳定性。
from chaojiying import ChaojiyingClient
element = driver.find_element(By.ID, "captcha_img")
element.screenshot("./code.png")
client = ChaojiyingClient('用户名', '密码', '软件ID')
result = client.post_file(9004, './code.png')
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
element.screenshot("./code.png")
text = pytesseract.image_to_string(Image.open("./code.png"), lang='eng')
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 等) | 若是 div+ul 模拟的下拉框,直接使用普通元素定位点击,勿用 Select 类 |
| 滚动/JS | driver.execute_script() | JS 是操作滚动条、修改属性的唯一途径 | 优先用 scrollIntoView 滚动到元素;可用于移除 disabled 属性或强制点击 |
| Frame 切换 | switch_to.frame(), switch_to.default_content() | 进得去必须出得来 | 操作完嵌套页面后,务必立即调用 default_content() 切回主文档,避免后续定位失败 |
| 多窗口 | window_handles, switch_to.window() | 句柄是动态列表,需重新获取 | 切换到新窗口操作完后,若需回主窗口,记得再次切换句柄 |
| 等待机制 | WebDriverWait + EC | 拒绝滥用 time.sleep(),慎用全局隐式等待 | 首选显式等待 (精准控制),次选隐式等待,尽量避免强制等待以提高脚本稳定性 |
| 环境清理 | driver.quit() | 关闭所有窗口并结束驱动进程 | 务必放在 finally 块或 tearDown 方法中,确保即使报错也能执行资源释放 |
相关免费在线工具
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online