资讯动态

Selenium网页自动化完全指南:从环境搭建到实战脚本

发布时间:2026/9/29 7:46:04 来源:尧图企业网站定制
有了 Selenium 这个老朋友网页自动化操作其实比你想象中简单得多。前阵子有个学测试的朋友问我说自己每天要在后台系统里录几十条数据手动复制粘贴到怀疑人生问我能不能用 Selenium 搞一个半自动脚本把重复动作交给程序跑。我当时给他的回答是“能而且你花一个下午学会基础以后就能省下无数个下午。”这篇教程就是冲着这个目标来的——不管你是测试工程师、运维还是单纯想偷个懒的普通办公族只要你写过一点 Python哪怕只是照着抄过几行代码都能跟下来。我不会一上来就丢一堆术语把你砸晕。咱们先搞清楚 Selenium 到底是个什么东西、为什么它能模拟人在浏览器里的操作然后再一步步把环境装好把定位元素、点击、输入这些核心动作用透最后用一个小实战把整个流程串起来。学完你就能自己写脚本去处理那些需要重复点击、重复填表、重复抓数据的网页任务了。1. 先把 Selenium 是什么讲明白1.1 网页自动化的本质是什么说白了网页自动化就是让程序替我们去驱动浏览器。你在浏览器里做的所有事情打开网址、点击按钮、输入文字、下拉选择、滚动页面本质上都可以被翻译成浏览器内核能理解的一条条命令。Selenium 正好提供了这样一套能力它通过 WebDriver 协议去指挥浏览器让浏览器表现得像有一个真实用户在操作。很多新手第一次接触 Selenium 时会困惑它到底是一个插件、一个软件还是一个编程库我直接说结论Selenium 是一个自动化测试框架严格讲是给你写代码时用的第三方库。它不是 Chrome 网上应用店里那种插件不需要你跑到浏览器里点“添加扩展程序”。它提供了一套 API我们用 Python、Java 这些语言调用它再由它把指令翻译给浏览器驱动浏览器驱动再去控制真实的浏览器窗口。很多人问“怎么安装 selenium 插件”其实就是把安装思路弄混了。我们要装的是 Python 库而不是什么浏览器扩展。驱动倒是需要单独下载但它也不是插件而是连接测试脚本和浏览器的一条专用通道后面我会详细讲。1.2 Selenium 在自动化生态里的位置现在做网页自动化的工具其实不少有人用 Playwright有人用 Puppeteer还有人直接用 Requests 模拟 HTTP 请求。Selenium 的优势在于它够老、够稳、资料够多。它是目前支持浏览器最全的自动化方案Chrome、Edge、Firefox、Safari 基本都能跑而且生态成熟不管遇到什么报错几乎都能在社区里搜到答案。它和学习成本低并不矛盾。你要是只想快速抓个数据Requests 确实很轻量但遇到需要执行 JavaScript 的页面、需要登录后操作的页面、或者有复杂交互的页面纯 HTTP 模拟就会非常痛苦。Selenium 直接操作真实浏览器能天然绕过很多前端加密和动态渲染的麻烦代价就是速度慢一点、资源占用高一点。所以我一般这么建议能简单静态抓取就 Requests遇到动态交互、表单操作、回归测试这类场景直接上 Selenium别犹豫。1.3 它能做什么不能做什么Selenium 能做的事情大概可以总结成这么几类自动填写表单并提交自动点击按钮和菜单自动翻页抓取列表数据自动处理弹窗和警告框对已有网页做回归测试甚至还能结合截图功能做页面异常巡检。但它不是万能的。它模拟的是“能看到页面的人”而不是“能绕过所有反爬机制的神仙”。遇到极强的人机验证、复杂的滑块拼图、需要扫码登录的支付场景Selenium 一样会被拦住。另外它对桌面应用、手机原生 App 的控制能力非常弱那是另一个技术栈的活儿。认识到边界你才不会在踩坑之后骂它垃圾。2. 环境准备装好一套能跑的自动化环境2.1 语言驱动怎么搭配才省心Selenium 支持的编程语言很多Python、Java、C#、Ruby 都有官方绑定。我给新手的建议永远只有一个如果你没有历史包袱直接用 Python。原因很简单Python 写起来最短资料最全遇到问题随便一搜就是现成答案。有了语言还得有浏览器驱动。这里的关键点是驱动版本必须和浏览器版本匹配否则你连浏览器都打不开。比如你用 Chrome就得去下载对应版本的 ChromeDriver。注意是“对应版本”不是“最新版本”很多人第一步就栽在这里。Chrome 浏览器会自动升级而 ChromeDriver 不会所以最常见的情况是今天脚本还能跑明天报了个SessionNotCreatedException一看浏览器静默升级了驱动版本对不上了。如果你用的是新版 Edge也不用慌Edge 走的是 Chromium 内核驱动叫 msedgedriver下载和配置思路跟 ChromeDriver 完全一样。Firefox 则是 geckodriver。2.2 安装步骤从 Python 到 selenium库假设你已经装好了 Python。没装的话去官网下载安装包安装时记得勾选“Add Python to PATH”这个勾选非常重要不勾后面命令行会找不到 python。装完 Python 后打开命令行Windows 下是 CMD 或 PowerShellmacOS 下是 Terminal执行pip install selenium如果你想指定版本比如公司项目里固定了某个版本可以这样pip install selenium4.25.0装完之后验证一下python -c import selenium; print(selenium.__version__)如果你能输出版本号说明库已经装好了。注意这里不需要去安装什么“selenium 插件”很多教程里说的“插件”其实就是这个 Python 库别再被绕晕了。2.3 浏览器驱动的坑版本对应是头等大事接下来下载浏览器驱动。以 ChromeDriver 为例第一步打开 Chrome 浏览器在地址栏输入chrome://version找到“Google Chrome”这一行记下完整的版本号比如131.0.6778.86。第二步去 ChromeDriver 下载页面选择和你浏览器主版本号一致的版本下载。下载下来的压缩包里只有一个可执行文件Windows 下是chromedriver.exemacOS 下是chromedriver。第三步把这个驱动放到一个你记得住的位置。最简单的做法是新建一个文件夹专门放驱动比如D:\drivers然后把路径配置到系统环境变量里。如果你不想配环境变量也可以在代码里显式指定路径后面我会给例子。这里有个实操技巧驱动文件不一定非要放到 Python 安装目录或者项目目录里只要让 Selenium 能找到就行。新手最容易踩的坑是驱动路径写错、或者驱动版本和浏览器版本不匹配结果 Selenium 报了WebDriverException误以为是代码写错了。新版 Selenium 还有一个 Selenium Manager 机制在部分环境里可以自动下载匹配的驱动。但国内网络环境下自动下载不一定稳定所以我建议老老实实手动下载驱动路径配好一劳永逸。2.4 验证环境写一个能打开网页的脚本环境配好之后我们来验证一下全套流程是否通。新建一个 Python 文件比如test_env.py写入以下代码from selenium import webdriver from selenium.webdriver.chrome.service import Service # 如果已经把 chromedriver 配置到 PATH可以不用指定 service service Service(rD:\drivers\chromedriver.exe) driver webdriver.Chrome(serviceservice) driver.get(https://www.baidu.com) print(页面的标题是, driver.title) input(按回车键关闭浏览器...) driver.quit()运行这个脚本如果你能看到一个真实的 Chrome 窗口被打开并且自动访问了百度首页打印出页面标题那就说明你的工作区已经通了。后面所有操作都建立在这个基础之上。如果你把驱动配置到了 PATH那么webdriver.Chrome()这一行可以不用传service参数。这里我说一句刚开始学的时候尽量别用无头模式也就是别让浏览器在后台悄悄跑。你最好看着浏览器窗口每一步输入、点击是怎么执行的这样你对整个自动化的理解会扎实得多。3. 核心操作定位、枚举、交互一个不落3.1 选择器和定位元数据先搞清楚要操作谁Selenium 自动化最核心的步骤就是先告诉它“你要操作页面上的哪个元素”。这个“告诉”的动作专业说法叫定位元素。Selenium 提供了非常多的定位方式ID、Name、Class Name、Tag Name、CSS Selector、XPath、Link Text等等。其中我用得最多的是CSS Selector和XPath。ID 当然最方便但现在很多前端框架生成的页面里ID 是动态变化的今天叫name_1明天可能就叫name_2这种时候用 ID 定位就废了。CSS Selector 简洁高效适合按 class、属性来选XPath 则灵活适合根据元素之间的层级关系来定位尤其是没有明确 class 和 id 的场景。这里我要重点提一个很多教程不会细讲的概念定位元数据。简单说定位元数据就是“用什么方式、用什么表达式去找到某个元素”的这组描述信息。比如from selenium.webdriver.common.by import By login_button_locator (By.ID, login-btn)这一行代码里的(By.ID, login-btn)就是一个定位元数据。它本身还不是元素只是一个“配方”。你可以把这个“配方”存成一个变量、放到字典里、甚至单独写一个文件统一管理。等到真正需要操作时再把它配合find_element方法使用。为什么要在意这个概念因为你在写自动化脚本的时候最痛苦的事情就是页面一改版所有代码都要跟着改。如果你把定位元数据单独抽出来统一管理出现问题时只需要改一处不用在全代码里到处找。这个小习惯能让你的脚本从“能用”进化到“好维护”。3.2 页面元素枚举批量处理才是自动化的大杀器除了定位单个元素Selenium 还支持枚举页面元素也就是一次性拿回符合某个条件的元素列表。这个方法叫find_elements注意是复数elements。举个例子你想抓取页面里所有商品卡片的标题这些标题在同一个 class 下面代码可以这样写from selenium.webdriver.common.by import By # 拿到所有符合条件的元素 title_elements driver.find_elements(By.CSS_SELECTOR, .product-title) # 枚举并处理 for index, element in enumerate(title_elements): print(f第{index 1}个标题: {element.text})你可能会问这和单个定位有什么本质区别区别大了。单个定位只能拿一个批量枚举却可以把页面上的同类元素全部抓出来然后配合循环逐个处理。比如你在一个表格里要挨个点击每一行的“编辑”按钮或者你想统计某个列表里到底有多少条数据用find_elements几行代码就搞定了。在实际项目中我经常把find_elements和“只存定位元数据”结合起来。先把枚举规则定义好再在具体流程里调用。这样做的好处是页面上某类元素的数量或者顺序变了我们至少不用改逻辑代码只要调整定位规则就行。3.3 常用交互操作点击、输入、等待、滚动元素定位到了接下来就是对它做操作。最常见的有这么几类输入文字用send_keysinput_box driver.find_element(By.ID, username) input_box.send_keys(test_user)点击按钮用clicklogin_btn driver.find_element(By.ID, login-btn) login_btn.click()清空输入框用clear当你需要重新输入内容时这个操作很重要否则新的文字会追加在旧文字后面。获取元素文本用.text获取属性用.get_attribute(href)获取输入框的值也是.get_attribute(value)。等待这块非常关键。网页加载是异步的你点了一个按钮可能要等两三秒才出现新的内容。如果代码立刻去找新元素大概率会报NoSuchElementException。Selenium 提供了两种等待方式强制等待time.sleep(5)和智能等待WebDriverWait。强制等待简单粗暴但效率低等久了浪费时间等少了照样报错。我更推荐智能等待它会在指定时间内反复尝试直到元素出现或者超时from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待最多10秒直到“登录成功”的提示元素可见 success_element WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CLASS_NAME, success-tip)) )滚动页面也是高频操作。有的页面是滚动加载更多不滚到底就不会出现后续数据。你可以用execute_script直接执行 JavaScript# 滚动到页面底部 driver.execute_script(window.scrollTo(0, document.body.scrollHeight);)也可以滚动到某个具体元素附近target_element driver.find_element(By.ID, target) driver.execute_script(arguments[0].scrollIntoView();, target_element)3.4 表单处理与文件上传比你想的更简单网页自动化的很大一块工作就是填表单。包括文本框、下拉框、单选框、复选框、文件上传。下拉框的常见处理方式是用 Select 类from selenium.webdriver.support.ui import Select select_element Select(driver.find_element(By.ID, city)) select_element.select_by_visible_text(上海) # 按看到的文字选择 # 或者 select_by_value(shanghai)按 option 的 value 属性选择文件上传有点特殊。很多人的第一反应是去找弹窗然后用鼠标去操作文件选择框这是最复杂也最不稳定的做法。其实简单得很只要文件上传的 input 标签是可见的直接用send_keys传本地文件路径就行file_input driver.find_element(By.NAME, attachment) file_input.send_keys(rD:\data\report.xlsx)Selenium 会把文件路径自动填进文件选择框并确认不需要任何额外操作。如果你遇到的是隐藏的 input 元素那就先执行 JavaScript 把它变成可见再用上面的方式操作。4. 完整实战自动登录并抓取列表数据4.1 场景设计与思路拆解现在我们把前面学的知识串起来做一个小而完整的实战。场景是自动登录一个后台系统进入某个数据列表页面循环抓取表格里的数据最后把结果打印出来。这个场景非常典型。很多人日常工作里其实都是这种“登录—进入页面—翻页—复制数据”的重复操作。写成脚本后半自动执行你只需要在扫码登录或者验证码环节介入一下就行。为了让脚本更接近真实项目我会把定位元数据统一放在一个字典里管理。这样既体现了“仅存储定位元数据”的思路也让代码更清晰。假设登录页面包含用户名输入框、密码输入框、登录按钮。列表页面包含一行一行的数据每行里有姓名、部门、职位三列。我们约定用 CSS Selector 来定位因为大多数前端页面都会给这些元素加相对稳定的 class 名。4.2 代码实现与逐段解释先看完整代码import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 1. 集中管理定位元数据页面改版时只改这里 LOCATORS { username: (By.ID, username), password: (By.ID, password), login_btn: (By.CSS_SELECTOR, button.login-btn), data_rows: (By.CSS_SELECTOR, table tbody tr), cell: (By.CSS_SELECTOR, td), } # 2. 启动浏览器 service Service(rD:\drivers\chromedriver.exe) driver webdriver.Chrome(serviceservice) driver.get(https://example.com/login) try: # 3. 等待输入框出现并输入账号密码 username_input WebDriverWait(driver, 10).until( EC.presence_of_element_located(LOCATORS[username]) ) username_input.send_keys(admin) password_input driver.find_element(*LOCATORS[password]) password_input.send_keys(123456) # 4. 点击登录 driver.find_element(*LOCATORS[login_btn]).click() # 5. 等待列表页加载 time.sleep(3) rows driver.find_elements(*LOCATORS[data_rows]) for row_index, row in enumerate(rows, start1): cells row.find_elements(*LOCATORS[cell]) # 确保这一行至少有3列避免解析到空行 if len(cells) 3: name cells[0].text.strip() department cells[1].text.strip() position cells[2].text.strip() print(f第{row_index}行{name} / {department} / {position}) finally: # 6. 别忘了关闭浏览器资源 driver.quit()代码不长但里面有几个设计点值得展开说。第一我把所有定位元数据放进了LOCATORS字典。你注意看字典里的值都是一对元组比如(By.ID, username)。这就是前面讲的“仅存储定位元数据”的实践。查找元素的地方统一用driver.find_element(*LOCATORS[username])星号的作用是把元组展开成两个参数等价于driver.find_element(By.ID, username)。如果哪天页面元素 ID 变了我只需要改字典里的这一行不用动下面的任何逻辑。第二登录按钮点完以后我用了time.sleep(3)。这里我没有用智能等待是因为页面跳转后是一个全新的页面结构等待某个新元素可能不太可靠。当然更严谨的做法是等待列表页的某个特征元素出现但实战中我们经常会遇到接口返回快、页面渲染慢的情况用sleep兜底也是一种可以接受的方案。关键是别把sleep当唯一手段能等特定元素就等特定元素。第三遍历每一行的数据时我先取到所有行再在行内部继续用find_elements来枚举单元格。这就是“页面元素枚举”的嵌套使用。先枚举行再枚举每一行里的列。如果你只枚举所有td你就会拿到一个扁平的列表很难分辨哪个单元格属于哪一行所以分层枚举非常关键。4.3 运行结果与常见报错排查这段代码跑起来后你会在控制台看到类似这样的输出第1行张三 / 技术部 / 后端工程师 第2行李四 / 产品部 / 产品经理 第3行王五 / 运营部 / 运营专员如果能跑出这样的结果说明你的环境、定位、交互基本都过关了。如果你在实战中遇到问题多半集中在下面几个地方输入框定位不到。最常见的原因是页面用了 iframe你需要先切换到 iframe 才能定位里面的元素。切换代码是driver.switch_to.frame(frame_name_or_id)操作完再切换回来driver.switch_to.default_content()。输入框能定位但输入不进去。有可能是页面在输入时做了特殊事件监听你可以试试给元素先点击一下再输入或者用action_chains模拟键盘输入。还不行就用execute_script直接给 value 赋值但这个方式需要手动触发事件比较绕不推荐新手首选。数据列表只抓到了第一页或者很少的数据。那就要考虑翻页操作了。翻页的本质是点击下一页按钮你可以找到下一页按钮的定位元数据循环执行点击或者有些表格支持每页条数选择直接把每页条数改成大数值一次性全部加载。这个要视具体页面而定。4.4 如何把脚本改成可复用的自动化测试框架雏形上面这个脚本是一次性的日志还比较乱。真正在公司里做自动化测试不可能把所有逻辑都堆在一个文件里。简单来说你要学会做三件事第一把定位元数据从代码里抽出来放成单独的配置文件比如用一个 Python 模块专门管 locator或者直接用 YAML、JSON 文件来存。第二把常用操作封装成函数或类比如login(username, password)、get_table_data()这样测试用例只需要调用这些方法。第三引入数据驱动把测试数据从 Excel 或数据库读取而不是写死在代码里。这么做之后你就拥有了一个非常朴素的“前端自动化测试框架”。等你能自己写出这种分层结构的代码再去看市面上基于 Selenium 二次封装的框架比如 SeleniumBase、Robot Framework 这些你就能看懂它们的设计思路了。到那时“selenium 自动化测试框架”这个概念对你来说就不是一个抽象名词而是你正在使用的方法论。5. 常见问题与排查技巧实录5.1 定位不到元素的隐藏原因NoSuchElementException是出现频率最高的报错但它背后的原因千差万别。我踩过很多坑之后总结了这么几种情况按概率排序元素确实在页面上但你找得太早了。页面是异步渲染的JavaScript 还没执行完元素还没生成出来。这种情况用智能等待基本能解决。元素在 iframe 里。前面说过如果你没有先切进 iframeSelenium 的默认上下文是主页面文档它“看”不到 iframe 里的任何元素。解决方法是先定位 iframe 元素再switch_to.frame()。元素是动态生成的每次刷新 ID 都会变。这种情况要尽量用相对稳定的属性比如 class、name、自定义>

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑