演示浏览器的各种操作
本页面是 Selenium 常用浏览器操作的交互式演示区,共 9 个区域:
① 参数配置:Chrome / Edge / Firefox 选项面板,支持无头模式、User-Agent、下载目录等配置,实时生成 Python 代码
② 打开关闭:get 跳转 URL、close 关闭当前标签、quit 退出整个浏览器,演示页面完整生命周期
③ 页面导航:back 返回上一页、forward 前进到下一页、refresh 刷新当前页面
④ 窗口控制:maximize_window 最大化、minimize_window 最小化、set_window_size/set_window_position/set_window_rect 控制尺寸与坐标
⑤ 页面信息:读取 title 标题、current_url 当前地址、page_source 页面源码、get_log 浏览器日志
⑥ 元素交互:click 点击、send_keys 输入、clear 清空,以及 get_attribute / is_displayed / is_enabled 等属性与状态查询
⑦ Cookie操作:add_cookie 添加、get_cookies / get_cookie 读取、delete_cookie / delete_all_cookies 删除
⑧ 截图保存:save_screenshot 保存到文件、get_screenshot_as_file / get_screenshot_as_base64 / get_screenshot_as_png 多种截图方式,以及元素级别截图
⑨ 超时等待:三种超时(page_load / script / implicit_wait)与 readyState 三阶段详解、Selenium 4 新写法,三种等待方式(强制 sleep / 隐式 implicitly_wait / 显式 WebDriverWait + expected_conditions)对比与最佳实践、超时后处理策略与重试模板
每个区域提供对应的 API 说明、可点击的模拟操作按钮,以及一键复制的 Python Selenium 代码。
add_argument() + add_experimental_option()use_webview=True 测试桌面嵌入应用--inprivate(Chrome 是 --incognito)set_preference() 直接改 about:configset_preference() 方法可精细控制 about:config 全部设置,但不支持 Chromium 专属的 prefs/excludeSwitches/隐身模式。
本界面已根据当前选择的浏览器自动过滤可用配置项并生成对应代码。
# 默认 ChromeOptions(无任何配置) from selenium.webdriver.chrome.options import Options from selenium import webdriver options = Options() driver = webdriver.Chrome(options=options)
get、close、quit 三个 API 覆盖完整生命周期。close() 不关浏览器进程,多标签场景下别用它收尾 |
quit() 测试结束务必调用,否则残留进程会吃内存
driver.get("https://xxx") 打开指定网址(https://autotest-505.pages.dev/,点击网址在同一浏览器窗口打开新标签页)driver.close() 关闭当前页签driver.quit() 退出整个浏览器(所有页签)
# ① 启动 Chrome 浏览器 from selenium import webdriver from selenium.webdriver.common.by import By import psutil, time # 进程对比用,需先 pip install psutil # 采集 chrome / chromedriver 进程 PID 集合的辅助函数 def procs(): return {p.pid for p in psutil.process_iter(["name"]) if p.info["name"] in ("chrome.exe", "chromedriver.exe")} _pids = procs() # 启动前基线,排除你自己开着的 Chrome driver = webdriver.Chrome() # ② 打开演示页面(此时只有这一个标签页) driver.get("https://autotest-505.pages.dev/browser_op_tech_sections/open_close_tech.html") print("启动后新增进程:", procs() - _pids) # chromedriver.exe + 若干 chrome.exe # ③ 点击“对应 API”区域中的 https://autotest-505.pages.dev/ 链接 # 该链接 target="_blank",点击后会在【同一浏览器窗口】里新开一个标签页 # 注意:点击后 driver 的焦点仍停留在原标签页,这里不做标签页切换 driver.find_element(By.CSS_SELECTOR, 'a[href="https://autotest-505.pages.dev/"]').click() time.sleep(1) # 等新标签页进程稳定 print("点击后新增进程:", procs() - _pids) # 新标签页触发 Chrome 多进程架构创建渲染进程(也可能复用) # ④ close():只关闭 driver 当前所在标签页,另一个不受影响;用 3 个信号对比(和 quit 后三行完全镜像) driver.close() print("close 后残留进程:", procs() - _pids) # 非空集合:chrome/chromedriver 都还活着 print("chromedriver 进程状态:", driver.service.process.poll()) # None:进程仍在运行(未退出) print("驱动还能连接吗:", driver.service.is_connectable()) # True:会话仍存活 # ⑤ quit():关闭所有剩余标签页并退出浏览器进程(无需先切换标签);用 3 个确定性信号佐证 driver.quit() time.sleep(1) # 等系统回收进程 print("quit 后残留进程:", procs() - _pids) # set():chrome/chromedriver 全部退出 print("chromedriver 退出码:", driver.service.process.poll()) # 0:驱动进程已正常结束 print("驱动还能连接吗:", driver.service.is_connectable()) # False:driver 已释放 # 注意:Selenium 4 的 quit() 不会把 driver.session_id 置空,不要用它判断会话是否结束
maximize 和 fullscreen 不一样:前者保留任务栏,后者 F11 沉浸式 |
set_window_rect 是 Selenium 4 新增,一次搞定尺寸+位置
driver.maximize_window() 最大化窗口driver.minimize_window() 最小化窗口driver.fullscreen_window() 全屏(F11)driver.set_window_size(w, h) 设置尺寸driver.set_window_position(x, y) 设置位置driver.set_window_rect(x, y, width, height) 同时设置尺寸和位置driver.get_window_size() 获取尺寸,返回 {'width':w, 'height':h}driver.get_window_position() 获取左上角坐标
Selenium 自动化测试练习平台
# ① 启动浏览器并打开窗口控制演示页 from selenium import webdriver driver = webdriver.Chrome() driver.get("https://autotest-505.pages.dev/browser_op_tech_sections/window_control_tech.html") # ② 设置 / 获取窗口尺寸(单位:像素) driver.set_window_size(1024, 768) print(driver.get_window_size()) # {'width': 1024, 'height': 768} # ③ 设置 / 获取窗口位置(相对屏幕左上角) driver.set_window_position(100, 50) print(driver.get_window_position()) # {'x': 100, 'y': 50} # ④ 一次设置 x / y / width / height driver.set_window_rect(x=0, y=0, width=1280, height=800) # ⑤ 最大化 / 最小化 / 全屏(等同 F11) driver.maximize_window() driver.minimize_window() driver.fullscreen_window() # ⑥ 结束会话 driver.quit()
page_source 返回完整 HTML,可能非常大,谨慎打印 |
current_url 包含 hash(#后面的部分),断言时注意
driver.title 获取当前页面标题driver.current_url 获取当前页面完整 URLdriver.page_source 获取当前页面完整 HTML 源码driver.name 获取当前浏览器名称(如 chrome / firefox)driver.get_log("browser") 获取浏览器 Console 日志
# ① 启动浏览器 from selenium import webdriver driver = webdriver.Chrome() driver.get("https://autotest-505.pages.dev/browser_op_tech_sections/page_info_tech.html") # ② 获取页面标题(<title> 标签内容) print("标题:", driver.title) # ③ 获取当前完整 URL(常用于验证页面跳转是否成功) print("URL:", driver.current_url) # ④ 获取页面 HTML 源码 print("源码长度:", len(driver.page_source)) # ⑤ 浏览器名称、当前窗口句柄与全部句柄 print("浏览器:", driver.name) print("当前句柄:", driver.current_window_handle) print("所有句柄:", driver.window_handles) driver.quit()
ElementNotInteractableException 元素存在但不可交互(被遮挡/没滚动到) |
click() 点不到时试试 driver.execute_script("arguments[0].click()", el) 用 JS 强制点击(el 就是你用 find_element() 定位到的那个元素对象,execute_script 会把它作为参数传给 JS 里的 arguments[0],相当于绕过 Selenium 的可交互性检查直接触发 DOM 事件)
element.click() 点击元素element.send_keys("text") 输入文本(配合 Keys.ENTER 可模拟回车)element.clear() 清空输入框element.submit() 表单提交(等同于在输入框按回车)element.text 获取元素可见文本element.get_attribute("href") 获取 HTML 属性element.get_property("value") 获取 DOM property(比 get_attribute 更可靠,比如读输入框当前值)element.tag_name 获取标签名(如 "input" / "button")element.size 获取尺寸 {'height': N, 'width': N}element.location 获取页面坐标 {'x': N, 'y': N}element.rect 获取完整的位置+尺寸对象element.is_displayed() 元素是否可见element.is_enabled() 元素是否可操作element.is_selected() 复选框/单选框是否选中
# ① 启动浏览器并打开元素交互演示页 from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://autotest-505.pages.dev/browser_op_tech_sections/element_interact_tech.html") # ② 定位输入框与复选框(id 与本演示页真实元素一致) username = driver.find_element(By.ID, "mockUsername") password = driver.find_element(By.ID, "mockPassword") remember = driver.find_element(By.ID, "mockRemember") # ③ 输入文本、清空后重新输入 username.send_keys("admin") username.clear() username.send_keys("admin") password.send_keys("123456") # ④ 点击复选框;submit() 模拟回车提交表单 remember.click() password.submit() # ⑤ 读取元素属性与状态(自动化断言常用) print("placeholder:", username.get_attribute("placeholder")) print("标签名:", username.tag_name) print("尺寸/坐标/矩形:", username.size, username.location, username.rect) print("选中/可见/可用:", remember.is_selected(), username.is_displayed(), username.is_enabled()) driver.quit()
save_screenshot |
嵌入 HTML → get_screenshot_as_base64 |
上传 AI → get_screenshot_as_png |
只截按钮/验证码 → element.screenshot
headless Chrome + --full-page-screenshot、selenium-screenshot 库、或 JS 滚动拼接。
# ① 启动浏览器并打开截图演示页 from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://autotest-505.pages.dev/browser_op_tech_sections/screenshot_tech.html") # ② 整页(视口)截图保存为文件,成功返回 True print(driver.save_screenshot("full.png")) driver.get_screenshot_as_file("full2.png") # 等价写法 # ③ 截图为 base64 字符串,适合直接嵌入 HTML 测试报告 b64 = driver.get_screenshot_as_base64() # ④ 截图为 PNG 二进制 bytes,可在内存中处理或上传到服务器 png_data = driver.get_screenshot_as_png() with open("from_bytes.png", "wb") as f: f.write(png_data) # ⑤ 只截取单个元素(Selenium 4+,id 与本演示页按钮一致) btn = driver.find_element(By.ID, "shotBtnElement") btn.screenshot("element.png") driver.quit()
from selenium.webdriver.common.timeouts import Timeoutsdriver.timeouts = Timeouts(implicit_wait=3, page_load=30, script=10)print(driver.timeouts.page_load) → 返回当前 page_load 值
driver.execute_script("window.stop()")
driver.save_screenshot("timeout.png")
page_load_timeout 管页面加载,
script_timeout 管 execute_script,
implicitly_wait 管 find_element。
set_page_load_timeout() 就会一直用页面加载超时初始值 300s(太长,正常页面加载用不了这么久)
driver.execute_script("window.stop()") → 重试/跳过/截图留证每隔 N 毫秒问一次"条件满足了吗?" → 满足就返回,超时就报错。
time.sleep 傻等不管页面 → 推荐用 WebDriverWait 精准等条件。
time.sleep 代替 —— 机器快白等、慢就崩,CI/CD 上尤其不稳定clickable > visibility > presence# ① 启动浏览器 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() # ② 三类超时设置(单位:秒) driver.set_page_load_timeout(30) # 页面导航加载最多等 30s driver.set_script_timeout(10) # execute_script 最多等 10s driver.implicitly_wait(1) # find_element 兜底轮询最多 1s driver.get("https://autotest-505.pages.dev/browser_op_tech_sections/timeout_wait_tech.html") # ③ JS 注入:execute_script 受 set_script_timeout(10) 保护,脚本卡住最多抛超时异常 ready_state = driver.execute_script("return document.readyState") print("页面加载状态:", ready_state) # complete # 注入 JS 直接读取元素文本(不经过 Selenium 定位器) card_text = driver.execute_script("return document.getElementById('mockCard1').innerText;") print("卡片内容:", card_text) # ④ 普通定位:find_element 受 implicitly_wait(1) 保护,元素没立即出现时兜底轮询最多 1s sleep_btn = driver.find_element(By.ID, "waitBtnSleep") print("定位到按钮:", sleep_btn.text) # ⑤ 显式等待(推荐):每 0.5s 轮询一次,最长等 10s wait = WebDriverWait(driver, 10, poll_frequency=0.5) # 等按钮可点击后再点击(id 与本演示页“显式等待”按钮一致) btn = wait.until(EC.element_to_be_clickable((By.ID, "waitBtnExp"))) btn.click() # 等异步加载的卡片变为可见(id 与本演示页动态元素一致) wait.until(EC.visibility_of_element_located((By.ID, "mockCard1"))) # ⑥ 结束会话 driver.quit()
| 因素 | 本地 | CI/CD 云服务器 |
| 网络 | 专线稳定 | 数据中心共享,偶发抖动 |
| CPU | 独占 | 多租户,可能被抢占 |
| 浏览器缓存 | 有 | 没有(每次全新启动) |
| 页面加载速度 | 有缓存,秒出 | 全量下载,慢 2~5 倍 |
| 并发任务 | 只跑你这一份 | 可能几十上百个同时抢资源 |
"A session has an associated session implicit wait timeout that specifies a time to wait for the implicit element location strategy"implicit=0.5s → 驱动最多等待 500ms 后必须放弃
→ 驱动在一次 findElement / findElements 调用中,最多愿意等待的总时间即为该值,不得超时。
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
def test_polling(d, delay):
d.implicitly_wait(2)
d.get('about:blank')
d.execute_script(f"setTimeout(()=>{{document.body.innerHTML='t'}},{delay})")
t0 = time.perf_counter()
try:
cost = (time.perf_counter() - t0) * 1000
print(f"delay={delay:4d} 耗时={cost:6.0f} 差值={cost-delay:+5.0f}")
except: print(f"delay={delay} 超时")
driver = webdriver.Chrome()
for delay in range(10, 1550, 50): # 50ms 步进,覆盖 10~1500ms
test_polling(driver, delay)
driver.quit()
最坏 = implicit × (explicit超时 / pollFreq)try: find_element ... except NoSuchElementException:| 值 | 兜底窗口 (规范定义) |
叠加成本 explicit=15s |
白等 10次不存在 |
依据类型 | 推荐 |
| 不设(=0) | 0ms | 0 秒 | 0 秒 | 规范 | 最严谨 |
| 1s | 1000ms | 30 秒 | 10 秒 | 经验+权衡 | 默认推荐 |
| 0.5s | 500ms | 15 秒 | 5 秒 | 经验+权衡 | 确认页面 <500ms |
| 2s | 2000ms | 60 秒 | 20 秒 | 代价太大 | 谨慎 |
| ≥5s | ≥5000ms | 150 秒+ | 50 秒+ | 爆炸 | ❌ 绝对避免 |