Python + Selenium 浏览器自动化测试与网页自动登录:从入门到实战
在日常开发、测试和办公自动化中,我们经常会遇到一些重复性的浏览器操作,例如打开网页、输入账号密码、点击登录按钮、检查页面是否加载成功、保存截图、批量处理后台数据等。
如果这些操作每天都要重复执行,手动处理不仅浪费时间,还容易因为漏点、输错、忘记截图而出错。Python 的 selenium 库可以帮助我们自动控制浏览器,完成网页自动化测试和网页自动登录等任务。
本文面向 Python 自动化测试初学者,通过一个完整案例讲解如何使用 Selenium 自动打开网页、输入用户名密码、点击按钮、等待页面元素加载,并自动截图保存。
一、Selenium 库介绍
Selenium 是一个常用的浏览器自动化测试工具,可以模拟真实用户在浏览器中的操作,例如:
- 打开网页
- 查找页面元素
- 输入文本
- 点击按钮
- 切换窗口
- 等待元素加载
- 获取页面内容
- 截图保存
- 执行 JavaScript
- 验证页面结果
Selenium 支持多种浏览器,包括:
- Chrome
- Edge
- Firefox
- Safari
在 Python 中使用 Selenium,可以编写自动化测试脚本,也可以完成一些办公自动化任务,例如后台系统自动登录、自动导出报表、自动截图留档、自动巡检页面状态等。
安装 Selenium:
bash
pip install selenium
查看版本:
bash
python -c "import selenium; print(selenium.__version__)"
二、ChromeDriver 安装配置
Selenium 需要通过浏览器驱动来控制浏览器。控制 Chrome 浏览器时,常用的是 ChromeDriver。
1. Selenium 4 的自动驱动管理
如果你使用的是 Selenium 4.6 及以上版本,Selenium Manager 通常可以自动管理浏览器驱动。很多情况下,你只需要安装 Selenium,然后直接运行:
python
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
Selenium 会尝试自动找到本机 Chrome,并匹配合适的驱动。
2. 手动安装 ChromeDriver
如果自动管理失败,可以手动安装 ChromeDriver。
步骤如下:
- 打开 Chrome 浏览器
- 在地址栏输入
chrome://version/ - 查看 Chrome 主版本号
- 下载对应版本的 ChromeDriver
- 将
chromedriver.exe放到一个固定目录 - 将该目录加入系统环境变量
Path
例如 Windows 中可以放到:
text
C:\WebDriver\chromedriver.exe
并把:
text
C:\WebDriver
加入环境变量 Path。
配置完成后,在命令行输入:
bash
chromedriver --version
如果能看到版本号,说明配置成功。
3. 指定 ChromeDriver 路径
如果不想配置环境变量,也可以在代码中指定驱动路径:
python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
service = Service(r"C:\WebDriver\chromedriver.exe")
driver = webdriver.Chrome(service=service)
对初学者来说,建议优先使用 Selenium 4 的自动驱动管理;如果失败,再手动配置 ChromeDriver。
三、自动打开网页
Selenium 打开网页的基本代码如下:
python
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
常用窗口操作:
python
driver.maximize_window()
driver.set_window_size(1280, 800)
获取网页标题:
python
print(driver.title)
获取当前地址:
python
print(driver.current_url)
关闭浏览器:
python
driver.quit()
注意:建议使用 driver.quit() 关闭整个浏览器进程,而不是只用 driver.close() 关闭当前标签页。
四、元素定位方法
网页自动化的核心是"找到元素,然后操作元素"。Selenium 提供了多种元素定位方式。
需要先导入:
python
from selenium.webdriver.common.by import By
常见定位方式如下:
1. 通过 ID 定位
python
username_input = driver.find_element(By.ID, "username")
适合页面元素有唯一 id 的情况。
2. 通过 name 定位
python
password_input = driver.find_element(By.NAME, "password")
表单输入框经常会有 name 属性。
3. 通过 class name 定位
python
button = driver.find_element(By.CLASS_NAME, "login-btn")
注意:CLASS_NAME 只能写单个 class,不能写多个 class 组合。
4. 通过 CSS Selector 定位
python
login_button = driver.find_element(By.CSS_SELECTOR, "button.login-btn")
CSS Selector 非常灵活,是实际项目中最常用的方式之一。
例如:
python
driver.find_element(By.CSS_SELECTOR, "input[name='username']")
driver.find_element(By.CSS_SELECTOR, "#login-form button[type='submit']")
5. 通过 XPath 定位
python
login_button = driver.find_element(By.XPATH, "//button[text()='登录']")
XPath 适合定位结构复杂、缺少稳定属性的元素。
常见 XPath:
python
//input[@id='username']
//button[contains(text(), '登录')]
//div[@class='message']
6. find_element 与 find_elements 的区别
查找单个元素:
python
element = driver.find_element(By.CSS_SELECTOR, ".item")
查找多个元素:
python
elements = driver.find_elements(By.CSS_SELECTOR, ".item")
区别:
find_element找不到元素会抛异常find_elements找不到元素会返回空列表
五、自动输入用户名密码
找到输入框后,可以使用 send_keys() 输入内容。
python
username_input = driver.find_element(By.ID, "username")
password_input = driver.find_element(By.ID, "password")
username_input.send_keys("demo_user")
password_input.send_keys("demo_password")
如果输入框中已有内容,可以先清空:
python
username_input.clear()
username_input.send_keys("demo_user")
真实项目中,不建议把账号密码直接写死在代码里。更推荐使用环境变量:
python
import os
username = os.getenv("TEST_USERNAME")
password = os.getenv("TEST_PASSWORD")
运行前设置环境变量:
bash
set TEST_USERNAME=demo_user
set TEST_PASSWORD=demo_password
这样可以避免账号密码泄露到代码仓库。
六、自动点击按钮
点击按钮使用 click():
python
login_button = driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
login_button.click()
有些页面按钮需要等待可点击后再点击,否则可能出现元素未加载、按钮被遮挡等问题。更推荐结合显式等待:
python
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
wait = WebDriverWait(driver, 10)
login_button = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))
)
login_button.click()
七、显式等待与隐式等待
网页不是瞬间加载完成的,尤其是现代前端页面经常使用 Ajax、Vue、React 等技术动态渲染内容。如果元素还没出现就去定位,很容易报错。
Selenium 常用两类等待方式:
- 隐式等待
- 显式等待
1. 隐式等待
隐式等待会对所有元素查找生效。
python
driver.implicitly_wait(10)
含义:查找元素时,如果元素暂时不存在,最多等待 10 秒。
优点:
- 写法简单
- 对全局生效
缺点:
- 不够精确
- 复杂页面中不容易控制具体等待条件
2. 显式等待
显式等待针对某个具体条件等待,更适合自动化测试。
python
wait = WebDriverWait(driver, 10)
element = wait.until(
EC.presence_of_element_located((By.ID, "username"))
)
常见等待条件:
python
EC.presence_of_element_located(locator) # 元素存在于 DOM 中
EC.visibility_of_element_located(locator) # 元素可见
EC.element_to_be_clickable(locator) # 元素可点击
EC.title_contains("首页") # 标题包含指定文字
EC.url_contains("dashboard") # URL 包含指定文字
实际项目中,建议以显式等待为主,隐式等待可以设置一个较短时间作为兜底。
八、自动截图保存
Selenium 可以保存当前浏览器截图,非常适合测试留痕、异常排查和自动化办公。
python
driver.save_screenshot("login_result.png")
也可以截图到指定目录:
python
from pathlib import Path
from datetime import datetime
screenshot_dir = Path("screenshots")
screenshot_dir.mkdir(exist_ok=True)
file_name = datetime.now().strftime("login_%Y%m%d_%H%M%S.png")
driver.save_screenshot(str(screenshot_dir / file_name))
如果登录失败,可以截图保存现场,方便后续分析。
九、完整实战代码:自动登录并截图
下面是一份完整实战代码。为了避免涉及真实网站账号密码,示例使用一个演示登录页地址和占位选择器。你在实际项目中只需要把 URL、账号密码和元素定位方式替换成自己的系统即可。
建议保存为:
text
selenium_login_demo.py
完整代码如下:
python
import os
from datetime import datetime
from pathlib import Path
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
LOGIN_URL = "https://example.com/login"
USERNAME = os.getenv("TEST_USERNAME", "demo_user")
PASSWORD = os.getenv("TEST_PASSWORD", "demo_password")
SCREENSHOT_DIR = Path("screenshots")
def create_driver():
"""创建 Chrome 浏览器对象。"""
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(3)
return driver
def save_screenshot(driver, name_prefix):
"""保存浏览器截图。"""
SCREENSHOT_DIR.mkdir(exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
file_path = SCREENSHOT_DIR / f"{name_prefix}_{timestamp}.png"
driver.save_screenshot(str(file_path))
return file_path
def login(driver):
"""自动打开网页、输入账号密码并点击登录。"""
wait = WebDriverWait(driver, 10)
driver.get(LOGIN_URL)
username_input = wait.until(
EC.visibility_of_element_located((By.ID, "username"))
)
password_input = wait.until(
EC.visibility_of_element_located((By.ID, "password"))
)
username_input.clear()
username_input.send_keys(USERNAME)
password_input.clear()
password_input.send_keys(PASSWORD)
login_button = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))
)
login_button.click()
wait.until(
EC.url_contains("dashboard")
)
success_element = wait.until(
EC.visibility_of_element_located((By.CSS_SELECTOR, ".user-info"))
)
return success_element.text
def main():
driver = create_driver()
try:
user_info = login(driver)
print(f"登录成功:{user_info}")
screenshot_path = save_screenshot(driver, "login_success")
print(f"成功截图已保存:{screenshot_path}")
except TimeoutException:
screenshot_path = save_screenshot(driver, "login_failed")
print(f"登录失败或页面加载超时,现场截图已保存:{screenshot_path}")
raise
finally:
driver.quit()
if __name__ == "__main__":
main()
十、如何改成真实网站登录
把示例代码改成真实项目,一般只需要修改 5 个地方。
1. 修改登录地址
python
LOGIN_URL = "https://your-company-system.com/login"
2. 修改用户名输入框定位
如果页面 HTML 是:
html
<input id="account" name="account">
则代码可以改成:
python
username_input = wait.until(
EC.visibility_of_element_located((By.ID, "account"))
)
3. 修改密码输入框定位
python
password_input = wait.until(
EC.visibility_of_element_located((By.NAME, "password"))
)
4. 修改登录按钮定位
python
login_button = wait.until(
EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '登录')]"))
)
5. 修改登录成功判断条件
登录成功后,页面可能跳转到后台首页,也可能出现用户头像或用户名。
例如:
python
wait.until(EC.url_contains("home"))
或者:
python
wait.until(
EC.visibility_of_element_located((By.CSS_SELECTOR, ".avatar"))
)
自动化测试中,登录成功判断非常重要。不能只点击按钮就认为登录成功,必须验证页面状态。
十一、常见问题与解决方法
1. 找不到元素
常见报错:
text
NoSuchElementException
原因可能是:
- 定位方式写错
- 页面还没加载完成
- 元素在 iframe 中
- 元素需要滚动后才出现
- 页面结构发生变化
解决建议:
- 使用浏览器开发者工具检查元素
- 优先使用稳定的
id、name、data-*属性 - 增加显式等待
- 如果元素在 iframe 中,先切换 iframe
2. 元素不可点击
常见报错:
text
ElementClickInterceptedException
可能原因:
- 页面弹窗遮挡
- 按钮还没变成可点击状态
- 页面动画还没结束
解决方式:
python
login_button = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))
)
login_button.click()
3. 页面有验证码
如果登录页面有验证码、短信验证码、滑块验证,不建议绕过验证码。验证码本身就是为了防止自动化滥用。
企业内部测试环境可以采用这些方式:
- 测试环境关闭验证码
- 使用专门的测试账号白名单
- 后端提供测试登录接口
- 自动化测试前写入测试登录 Cookie
4. 浏览器启动失败
可能原因:
- Chrome 没安装
- ChromeDriver 版本不匹配
- Selenium 版本过旧
- 驱动路径没有配置
建议先升级 Selenium:
bash
pip install -U selenium
然后确认 Chrome 能正常打开。
十二、自动化办公场景分析
Selenium 不只适合自动化测试,也可以用于一些办公自动化场景。
1. 后台系统自动登录
很多公司内部系统需要每天登录查看数据,例如 CRM、ERP、OA、工单系统、数据看板等。Selenium 可以自动登录后台,进入指定页面。
2. 自动导出报表
如果系统没有开放 API,但页面上提供"导出 Excel"按钮,可以使用 Selenium 自动点击筛选条件、选择日期、点击导出。
3. 页面巡检与截图留档
运维或测试人员可以定时打开多个业务页面,检查是否出现错误提示,并自动保存截图。
4. 批量录入表单
一些旧系统没有批量导入功能,只能手动填写网页表单。Selenium 可以读取 Excel 数据,然后自动填写网页表单。
5. 自动化回归测试
开发完成新功能后,可以用 Selenium 编写登录、查询、提交、删除等流程测试脚本,减少人工回归测试成本。
十三、自动化测试代码编写建议
初学者写 Selenium 脚本时,建议注意以下几点:
- 不要把真实账号密码写死在代码里
- 尽量使用显式等待
- 优先选择稳定的元素定位方式
- 每个关键步骤后都做结果验证
- 失败时保存截图
- 用
try...finally确保浏览器最终关闭 - 不要对公共网站进行高频自动化请求
- 遵守目标网站的使用规则
一个好的自动化脚本,不只是能跑通一次,而是能稳定、可维护、容易定位问题。
十四、总结
本文使用 Python + Selenium 完成了一个"浏览器自动化测试与网页自动登录"的入门实战案例。
你已经学习了:
- Selenium 库的作用
- ChromeDriver 的安装与配置
- 如何自动打开网页
- 如何自动输入用户名和密码
- 如何自动点击登录按钮
- 常见元素定位方法
- 显式等待与隐式等待的区别
- 如何自动截图保存
- 一份完整的自动登录实战代码
- Selenium 在自动化办公中的应用场景
对于 Python 自动化测试初学者来说,建议先从简单页面练习元素定位、输入、点击和等待,再逐步扩展到真实业务系统。
当你掌握 Selenium 后,就可以把很多重复性的浏览器操作变成脚本,让测试、办公和数据处理流程更加高效。