一、Selenium 到底是干什么的
上一章我们已经知道,程序确实可以帮你打开网页、找到输入框、点击按钮、读取页面结果。 而真正把这件事做起来时,最经典、最常见的工具之一,就是 Selenium。
你可以先把 Selenium 理解成:
一个用代码控制浏览器的工具。
它能做的事情很像真人在电脑前的操作:
打开浏览器 访问网址 输入文字 点击按钮 选择下拉框 切换标签页 等待页面加载 截图 读取网页上的内容
所以它不是“请求网页源码”的工具,而是“控制真实浏览器行为”的工具。
这一点和前面学过的 requests 非常不一样。
requests 更像你直接向网站要数据。 Selenium 更像你真的打开一个浏览器窗口,一步一步去操作它。
这也是为什么,很多网页自动化、自动化测试、后台重复操作、爬取动态页面,都会提到 Selenium。
二、为什么有些网页必须用 Selenium
很多新手一开始会有疑问:
前面不是已经学过 requests 了吗,为什么还要学 Selenium。
因为有些网页,你直接请求到的内容,并不是你真正看到的页面内容。
比如:
页面数据是 JavaScript 动态加载的 按钮点击后才会出现结果 内容需要先登录后才能看 需要滚动页面才会继续加载 要先选条件、再点查询、再出表格 页面上有弹窗、标签切换、表单交互
这种场景下,单纯 requests.get() 往往不够。 因为它只能拿到网页初始响应,不会真的替你“点页面”。
而 Selenium 的思路刚好相反:
它不急着直接拿结果。 它先模拟人操作浏览器。 等页面真的展示出来后,再去读取你要的数据。
所以你可以先记住这个判断:
静态网页,很多时候 requests 就够。 动态交互强、依赖点击和等待的网页,Selenium 更合适。
三、Selenium 最常见的三个应用方向
学这个工具时,你最好先知道它通常被用在什么场景,不然容易学得很散。
1. 自动化测试
这是 Selenium 最经典的老本行。 比如测试登录页、搜索页、下单流程、后台管理流程。
2. 办公自动化
比如自动登录后台导出数据、批量提交表单、检查网页状态、重复点击菜单完成固定流程。
3. 动态网页数据采集
比如页面内容是点击按钮后加载出来的,或者滚动页面才出现,这时候 Selenium 可以先把页面“点开”,再拿数据。
所以它不是只服务测试,也不是只服务爬虫,它其实是浏览器自动化通用工具。
四、Selenium 的工作原理,先理解个大概就够
你现在不用追底层通信协议,但最好知道大概在发生什么。
通常流程是这样的:
Python 代码发出命令 浏览器驱动接收命令 驱动去控制真实浏览器 浏览器完成打开、点击、输入、读取等动作 结果再返回给 Python
所以 Selenium 不是凭空操作网页,它中间通常需要一个“驱动”来帮你和浏览器对接。
这也是为什么以前学 Selenium,经常会碰到一个很麻烦的问题:
还要单独下载浏览器驱动,版本不对还会报错。
不过现在比以前方便很多,入门门槛已经低了不少。
五、先安装 Selenium
安装命令很直接:
python -m pip install selenium
安装完之后,最常见的导入方式通常会长这样:
from selenium import webdriver
有时你还会看到:
from selenium.webdriver.common.by import By
这个 By 后面非常常用,因为它是元素定位方式的入口。
你现在先不用死记完整导入清单,后面看例子自然会熟。
六、第一段最小可运行代码:先把浏览器打开
入门第一步,不要一上来就登录、点按钮、写一堆流程。 先只做最小动作:
打开浏览器 访问网页 关掉浏览器
比如:
from selenium import webdriverimport timedriver = webdriver.Chrome()driver.get("https://www.python.org")time.sleep(3)driver.quit()
这段代码非常值得你先跑一遍。
它做了三件事:
启动 Chrome 浏览器 打开 Python 官网 停留 3 秒 关闭浏览器
这里的 driver 你可以理解成“浏览器控制对象”。 后面所有操作,基本都会围绕它来写。
get() 表示访问某个网址。quit() 表示彻底关闭浏览器。
这就是 Selenium 的真正起点。
七、为什么很多示例里会先用 time.sleep
因为刚入门时,你需要肉眼看见浏览器真的被打开了,真的跳转了,真的执行了动作。
所以很多演示代码会先加:
time.sleep(3)
这样页面不会一闪而过。
但你也要知道,time.sleep() 在正式自动化脚本里并不是最推荐的等待方式。 它简单、粗暴、容易懂,但不够智能。 后面我们会专门讲更稳的等待机制。
你现在先把它当作“教学辅助停顿”就够了。
八、元素定位,是 Selenium 里最核心的基础
浏览器能打开,只是第一步。 真正关键的是:
怎么找到你要操作的那个元素。
比如登录页里,程序怎么知道哪个是用户名输入框,哪个是密码框,哪个是登录按钮。
这就叫元素定位。
Selenium 里最常见的定位方式有这些:
按 id 按 name 按 class name 按标签名 按链接文字 按 CSS 选择器 按 XPath
你现在先不用全部背下来,但一定要先建立一个认识:
页面自动化的关键,不是“会点击”,而是“能稳定找到正确的元素”。
找不准,后面全都白搭。
九、最常见的定位入口:By
看一个典型写法:
from selenium.webdriver.common.by import By
然后配合:
driver.find_element(By.ID, "kw")
你可以先把这句理解成:
按 ID 去找页面里那个值为 kw 的元素。
这里的 By.ID 就是在说明“我打算按什么方式找”。 后面的 "kw" 是具体的定位值。
以后你会反复看到:
By.IDBy.NAMEBy.CLASS_NAMEBy.TAG_NAMEBy.LINK_TEXTBy.CSS_SELECTORBy.XPATH
它们本质上只是“找元素的方法不同”。
十、先看一个完整点的小例子:打开百度并输入关键词
from selenium import webdriverfrom selenium.webdriver.common.by import Byimport timedriver = webdriver.Chrome()driver.get("https://www.baidu.com")input_box = driver.find_element(By.ID, "kw")input_box.send_keys("Python")time.sleep(3)driver.quit()
这段代码的流程很清楚:
打开百度 通过 id 找到输入框 往里面输入 Python 等待 3 秒 关闭浏览器
这里第一次出现了一个很重要的方法:
send_keys()
它的作用就是往输入框里输入内容。
你可以把它理解成程序在“敲键盘”。
这一步一旦会了,很多表单类操作就打通了。 因为网页自动化里,输入几乎是最基础的动作之一。
十一、点击按钮:click()
输入完文字,下一步通常就是点按钮。
比如继续用百度例子:
from selenium import webdriverfrom selenium.webdriver.common.by import Byimport timedriver = webdriver.Chrome()driver.get("https://www.baidu.com")input_box = driver.find_element(By.ID, "kw")input_box.send_keys("Python")search_button = driver.find_element(By.ID, "su")search_button.click()time.sleep(3)driver.quit()
这里最关键的是:
search_button.click()
也就是点击搜索按钮。
你会发现,页面自动化的核心动作其实没那么多。 高频动作通常就是:
找 输 点 读 等
只是页面一复杂,这些动作会反复组合起来。
十二、find_element 和 find_elements,有什么区别
这两个方法名字很像,但意义不一样。
find_element()找的是一个元素。 通常如果没找到,会报错。
find_elements()找的是一组元素。 返回的是一个列表。 如果没找到,返回空列表。
看例子:
links = driver.find_elements(By.TAG_NAME, "a")print(len(links))
这表示把页面上所有 <a> 标签都找出来。
然后你就可以遍历:
for link in links[:5]: print(link.text)
这在什么场景有用。
比如:
一页里有很多搜索结果 很多链接 很多按钮 很多表格行
你不是只想点一个,而是想把一组元素都抓出来看看。 这时候 find_elements() 就特别有用。
十三、读取页面内容:text 和属性
自动化脚本不只是操作,也经常要读结果。
比如读取一个元素的文字:
title = driver.find_element(By.TAG_NAME, "h1")print(title.text)
这里的 .text 表示元素显示出来的文本内容。
如果你想读取属性,比如链接地址:
link = driver.find_element(By.TAG_NAME, "a")print(link.get_attribute("href"))
这表示去读这个元素的 href 属性。
所以你可以记住两个高频入口:
.text 看显示文本get_attribute() 看元素属性
这在结果验证和页面数据提取里都非常常用。
十四、为什么说等待是 Selenium 稳定性的关键
前面我们用 time.sleep() 暂时停一下,是为了教学。 但真实脚本里,更麻烦的问题是:
页面不一定每次都瞬间加载完成。
比如:
刚打开页面,输入框还没出现 刚点击按钮,结果区域还没渲染 刚提交表单,页面还没跳转完成 刚打开弹窗,按钮还不能点
如果你代码写成“上一行刚点完,下一行立刻就找结果”,就很容易报错。
这就是为什么 Selenium 脚本里,等待几乎是核心能力,不是附属能力。
十五、显式等待:比 sleep 更稳的方式
入门后你最应该尽快掌握的等待方式之一,就是显式等待。
先看基本写法:
from selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as EC
然后这样用:
from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Chrome()driver.get("https://www.baidu.com")input_box = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "kw")))input_box.send_keys("Python")driver.quit()
这段代码的意思不是“固定等 10 秒”,而是:
最多等 10 秒 只要输入框出现了,就立刻继续往下走
这就比 sleep(10) 聪明得多。
所以显式等待的核心价值是:
不是傻等 而是等到条件满足再继续
这会让脚本更稳,也更快。
十六、最常见的等待条件有哪些
你现在不需要全背,但可以先认识几个高频的。
1. presence_of_element_located
元素已经出现在页面 DOM 里。 适合判断“元素存在了没有”。
2. visibility_of_element_located
元素不只是存在,还得是可见的。 适合你想确认用户能看见它。
3. element_to_be_clickable
元素可以被点击。 适合按钮类操作前使用。
比如等待按钮可点击:
button = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "submit")))button.click()
这在真实脚本里非常常见。 因为“元素存在”不代表“已经能点”。
十七、Selenium 里常见的元素操作,不只有输入和点击
除了 send_keys() 和 click(),还有一些动作也很高频。
清空输入框:
input_box.clear()
模拟回车:
from selenium.webdriver.common.keys import Keysinput_box.send_keys("Python", Keys.ENTER)
这表示输入完后直接按回车。
如果你碰到:
搜索框输入后按回车触发 表单按回车提交 键盘控制切换
这些场景,Keys 就会很有用。
十八、获取当前页面信息,也很常用
比如当前网址:
print(driver.current_url)
当前页面标题:
print(driver.title)
这两个值在测试脚本里特别常用,因为它们很适合做结果验证。
比如登录后判断是不是跳到首页:
assert"dashboard"in driver.current_url
或者判断标题对不对:
assert"首页"in driver.title
你会发现,自动化测试很多时候并不需要多复杂的逻辑,关键就是:
执行操作 拿到页面状态 做判断
十九、截图:调试和留证据都很好用
网页自动化一出问题,最怕你不知道页面到底停在什么状态。 这时候截图非常值钱。
最简单的截图:
driver.save_screenshot("page.png")
这在两个场景里特别有用。
第一,调试时。 脚本报错前先截一张图,往往一眼就能看出为什么出问题。
第二,留痕时。 比如自动化测试失败时,把失败页面截图保存下来,后面排查会轻松很多。
所以截图虽然只是一个小功能,但非常实战。
二十、一个更贴近真实网页流程的小例子
我们写一个更完整一点的流程:
打开网页 等待输入框出现 输入关键词 点击按钮 等待结果出现 读取标题
from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Chrome()driver.get("https://www.baidu.com")wait = WebDriverWait(driver, 10)input_box = wait.until( EC.presence_of_element_located((By.ID, "kw")))input_box.send_keys("Python")search_button = wait.until( EC.element_to_be_clickable((By.ID, "su")))search_button.click()wait.until(EC.title_contains("Python"))print("当前标题:", driver.title)driver.quit()
这段代码已经体现出 Selenium 脚本的基本骨架了:
打开 等待 找元素 操作 等待结果 验证 关闭
只要这个骨架你看顺了,后面学更复杂的操作就不容易乱。
二十一、Selenium 脚本最常见的几个坑
1. 页面元素定位不稳
比如今天按钮有这个 id,明天页面改版后就没了。 或者 class 名是自动生成的,每次都变。 这会直接导致脚本脆弱。
2. 过度依赖 time.sleep
写起来简单,但很不稳,也很慢。 能用显式等待时,尽量早点过渡过去。
3. 操作太快,页面还没准备好
点击后立刻读取结果,是报错高发区。
4. 路径、弹窗、登录状态没考虑
有些页面需要先登录,有些会弹窗,有些会跳新标签页。 这些都要单独处理。
5. 只会操作,不会验证
这时脚本更像自动点击器,不像测试脚本。 要尽早建立“操作后必须判断结果”的意识。
二十二、为什么很多 Selenium 脚本维护成本高
因为浏览器页面本来就是会变的。
按钮位置会变 元素属性会变 文案会变 页面结构会变 流程也可能改
这就意味着,Selenium 自动化不是“写一次永远不改”,而是:
规则稳定时价值很高 规则频繁变化时维护成本会明显上升
所以成熟一点的做法通常是:
优先自动化那些稳定、核心、重复、常回归的流程 而不是什么都一把梭全自动化
这个判断非常重要。
二十三、这一章学到什么程度算入门了
入门阶段,不要求你立刻搞定复杂弹窗、切 iframe、多窗口切换。 你先把这些弄顺就已经很好:
会启动浏览器 会打开网页 会找元素 会输入 会点击 会读取文本 会做基础等待 会拿页面标题和 URL 会截图 知道脚本为什么会不稳
只要这些基础动作站稳了,后面继续学表单、下拉框、切窗口、切 iframe、执行 JS,就会轻松很多。
二十四、本章要点整理
Selenium 是 Python 中最常见的浏览器自动化工具之一,适合自动化测试、办公自动化和动态网页操作。 它和 requests 不同,核心是控制真实浏览器进行操作,而不是只发请求。 Selenium 的基本流程通常包括:打开页面、定位元素、执行操作、等待结果、读取结果、验证结果。 元素定位是核心基础,常见方式包括 ID、NAME、CSS 选择器、XPath 等。 最常用的基础动作包括 send_keys() 输入、click() 点击、.text 读文本、get_attribute() 读属性。 等待机制对脚本稳定性至关重要,显式等待通常比 time.sleep() 更稳。 截图、读取标题和 URL,都是调试和结果验证中的高频操作。 真正的自动化测试脚本,不只是会操作页面,更要会判断结果是否符合预期。