Selenium 是最经典的浏览器自动化工具,它可以通过代码完全模拟真人操作浏览器 —— 打开网页、点击按钮、输入文字、滑动页面、抓取数据,甚至能处理 JavaScript 动态渲染的页面,是自动化测试、网络爬虫、重复网页操作的神器。
和 requests 这种纯网络请求库不同,Selenium 是真的启动一个真实的浏览器,所有操作和人手动点完全一样,所以能搞定绝大多数复杂的网页,新手也能快速上手。
本文从环境搭建、基础操作到进阶技巧,全程配可运行代码 + 逐行解释 + 避坑指南,零基础也能一步步跑通第一个自动化脚本。
⚠️ 合规提示:本文仅用于技术学习,请遵守网站的 robots 协议和用户协议,不要用于恶意爬虫、批量注册等违规操作。
一、先搞懂:Selenium 是什么?能做什么?
1. 通俗理解
你可以把 Selenium 理解成一个「机器人操作员」:
- 你给它写好步骤:打开哪个网站、点哪个按钮、输入什么内容
- 它会自动启动浏览器,完全按照你的步骤一步步操作,和真人手动点一模一样
- 网页上能看到的内容,它都能拿到;你能手动做的操作,它基本都能做
2. 核心优势
- ✅ 能处理动态页面:JS 渲染的页面、需要登录的页面、点击才加载的内容,都能搞定(这是 requests 做不到的)
- ✅ 完全模拟真人:鼠标点击、键盘输入、拖拽、悬停,所有人工操作都能模拟
- ✅ 兼容性好:支持 Chrome、Edge、Firefox 等所有主流浏览器
- ✅ 新手友好:语法简单,不需要懂复杂的网络请求、JS 逆向
3. 适用场景
- 动态网页爬虫:抓取需要点击、登录、JS 渲染的数据
4. 局限性
- ❌ 速度慢:因为要启动真实浏览器,加载所有资源,比纯请求库慢很多
- ❌ 占用资源多:浏览器本身占内存,不适合大规模高并发爬取
- ❌ 容易被反爬识别:比如检测到自动化工具,会被封 IP 或弹验证码
二、环境搭建(新手第一步,必看)
Selenium 的环境分两步:安装 Python 库 + 浏览器驱动。Selenium 4.6 之后的版本已经自动管理驱动,不用手动下载,新手直接装最新版即可,省去最麻烦的一步。
第 1 步:安装 selenium 库
打开终端 / 命令行,执行:
建议装最新版,自动驱动管理非常省心。
第 2 步:准备浏览器
电脑上安装 Chrome 浏览器或者 Edge 浏览器即可,不需要手动下载驱动,新版 Selenium 会自动匹配下载对应版本的驱动。
如果你用的是旧版 Selenium,需要手动下载对应版本的 ChromeDriver,放到 Python 安装目录里。新手直接装最新版就好,不用踩这个坑。
第 3 步:验证是否成功
跑一个最简单的脚本,能打开浏览器就算成功:
# 导入webdriver,这是selenium的核心from selenium import webdriver# 创建Chrome浏览器对象(会自动打开一个Chrome窗口)driver = webdriver.Chrome()# 打开百度首页driver.get("https://www.baidu.com")# 打印网页标题,验证是否成功打开print("网页标题:", driver.title)# 关闭浏览器driver.quit()
运行后如果自动弹出 Chrome 窗口、打开百度、控制台打印「网页标题:百度一下,你就知道」,说明环境搭建成功。
三、核心基础:元素定位
浏览器里的按钮、输入框、文字,都叫「页面元素」。想操作它们,第一步就是找到这个元素,这是 Selenium 最核心的基础。
1. 定位方法总览
Selenium 提供了 8 种定位方式,新手掌握最常用的 3 种就够应付 90% 的场景:
| | | |
|---|
By.ID | | | |
By.XPATH | | | |
By.CSS_SELECTOR | | | |
By.NAME | | | |
By.CLASS_NAME | | | |
By.LINK_TEXT | | | |
By.PARTIAL_LINK_TEXT | | | |
By.TAG_NAME | | | |
2. 基础语法
所有定位都统一用 find_element() 方法,传入定位方式和定位值:
from selenium.webdriver.common.by import By# 格式:driver.find_element(定位方式, 定位值)element = driver.find_element(By.ID, "kw")
- 找到元素返回「元素对象」,可以对它做点击、输入等操作
- 找不到元素会直接报错
NoSuchElementException
如果要找多个元素(比如列表里的所有项),用 find_elements()(加 s),返回元素列表,找不到返回空列表。
3. 最实用:XPath 定位详解
XPath 是新手必须掌握的万能定位法,相当于给元素写「路径地址」,哪怕元素没有 id、没有 class,也能精准定位到。
基础语法规则
//标签名[@属性名="属性值"]:按属性筛选,比如 //input[@id="kw"]text()="文字"/..
常用示例
# 1. 按id找输入框driver.find_element(By.XPATH, '//input[@id="kw"]')# 2. 按文字找按钮(最常用,比如"登录"按钮)driver.find_element(By.XPATH, '//button[text()="登录"]')# 3. 按class找divdriver.find_element(By.XPATH, '//div[@class="item"]')# 4. 组合多个属性,更精准driver.find_element(By.XPATH, '//input[@type="text" and @name="wd"]')# 5. 包含某个文字(模糊匹配)driver.find_element(By.XPATH, '//a[contains(text(), "新闻")]')
💡 新手小技巧:不用自己手写复杂 XPath 打开浏览器按 F12 打开开发者工具,在 Elements 里找到目标元素,右键 → 复制 → 复制 XPath,直接粘到代码里就行。
四、第一个完整实战:百度自动搜索
我们用 Selenium 实现:打开百度 → 输入「Python 教程」 → 点击搜索按钮 → 打印搜索结果标题,全程自动操作。
完整代码 + 逐行解释
# 1. 导入核心模块from selenium import webdriverfrom selenium.webdriver.common.by import Byimport time# 2. 创建Chrome浏览器对象driver = webdriver.Chrome()# 3. 打开百度首页driver.get("https://www.baidu.com")# 4. 找到搜索输入框(id是kw),输入关键词# send_keys():给输入框输入文字search_input = driver.find_element(By.ID, "kw")search_input.send_keys("Python教程")# 强制等待1秒,模拟人的思考时间(后面会讲更专业的等待)time.sleep(1)# 5. 找到百度一下按钮(id是su),点击它# click():点击元素search_btn = driver.find_element(By.ID, "su")search_btn.click()# 等待页面加载完time.sleep(2)# 6. 获取搜索结果的标题,打印出来# find_elements 找所有符合条件的元素,返回列表titles = driver.find_element(By.XPATH, '//h3[@class="title"]')titles = driver.find_elements(By.XPATH, '//h3[contains(@class,"title")]')print(f"共找到{len(titles)}条结果:")for i, title in enumerate(titles, 1): print(f"{i}. {title.text}") # .text 获取元素的文字内容# 7. 关闭浏览器driver.quit()
关键方法解释
| |
|---|
driver.get(url) | |
element.send_keys("文字") | |
element.click() | |
element.text | |
driver.quit() | |
driver.close() | |
五、常用元素操作大全
找到元素之后,就可以对它做各种操作,下面是日常最高频的操作。
1. 输入框操作
input_box = driver.find_element(By.ID, "input_id")# 输入文字input_box.send_keys("要输入的内容")# 清空输入框原有内容input_box.clear()# 按回车键(提交表单)from selenium.webdriver.common.keys import Keysinput_box.send_keys(Keys.ENTER)
2. 获取元素信息
element = driver.find_element(By.ID, "test")# 获取元素的文字内容print(element.text)# 获取元素的某个属性值,比如href、src、classprint(element.get_attribute("href"))print(element.get_attribute("class"))# 判断元素是否可见print(element.is_displayed())# 判断元素是否可用(灰色不可点)print(element.is_enabled())
3. 浏览器基础操作
# 刷新页面driver.refresh()# 后退到上一页driver.back()# 前进到下一页driver.forward()# 设置浏览器窗口大小driver.set_window_size(1200, 800)# 窗口最大化driver.maximize_window()# 打开新标签页driver.execute_script("window.open()")# 切换标签页,handles是所有标签页的列表,0是第一个driver.switch_to.window(driver.window_handles[1])
六、重中之重:三种等待方式(新手避坑核心)
新手 90% 的报错都是「元素找不到」,绝大多数原因都是代码跑得比页面加载快—— 元素还没渲染出来,代码就已经去查找了,自然找不到。
Selenium 有三种等待方式,用来解决这个问题,各有适用场景。
1. 强制等待:time.sleep ()
最简单的等待,让程序暂停指定秒数,时间到了再继续往下跑。
import timetime.sleep(3) # 强制等待3秒
2. 隐式等待:implicitly_wait ()
给整个浏览器设置一个最长等待时间,在时间范围内,元素加载出来了就立刻继续;超时还没加载出来才报错。只需要设置一次,整个 driver 生命周期都生效。
# 创建浏览器后,设置隐式等待10秒driver = webdriver.Chrome()driver.implicitly_wait(10)
- 优点:只写一次,所有元素查找都自动等待,不浪费时间
- 缺点:必须等整个页面加载完,有些局部加载的场景不灵活
- 新手建议:默认加上这一行,能解决 80% 的元素找不到问题
3. 显式等待:WebDriverWait
最精准、最灵活的等待方式,专门等某个指定元素满足条件(比如可见、可点击),条件满足立刻继续,超时就报错。 适合复杂场景,比如等某个弹窗出现、等某个按钮变成可点击状态。
语法示例
from selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.by import By# 创建等待对象:最长等10秒,每0.5秒检查一次wait = WebDriverWait(driver, 10)# 等待元素可见,可见后就返回元素对象element = wait.until( EC.visibility_of_element_located((By.ID, "kw")))# 等待元素可点击button = wait.until( EC.element_to_be_clickable((By.ID, "su")))
常用的等待条件
| |
|---|
visibility_of_element_located | |
element_to_be_clickable | |
presence_of_element_located | |
text_to_be_present_in_element | |
三种等待选型建议
- 普通场景、新手默认:加一行
implicitly_wait(10) - 复杂页面、精准控制:用显式等待
WebDriverWait
七、进阶常用操作
1. 切换 iframe
很多网站会把登录框、广告放在 iframe 嵌套页面里,这时候直接找元素是找不到的,必须先切换到对应的 iframe 里。
# 方式1:按iframe的id或name切换driver.switch_to.frame("iframe_id")# 方式2:先定位到iframe元素,再切换iframe_elem = driver.find_element(By.TAG_NAME, "iframe")driver.switch_to.frame(iframe_elem)# 操作完iframe里的内容,切回主页面driver.switch_to.default_content()
2. 处理 Alert 弹窗
网页原生的提示弹窗(alert/confirm/prompt),不能用元素定位,需要专门的方法处理。
# 切换到弹窗alert = driver.switch_to.alert# 获取弹窗里的文字print(alert.text)# 点击确定/接受alert.accept()# 点击取消alert.dismiss()# 给输入型弹窗输入内容alert.send_keys("输入内容")
3. 下拉选择框(Select)
针对 <select> 标签的下拉菜单,有专门的 Select 类处理,比自己点击选项更稳定。
from selenium.webdriver.support.ui import Select# 定位到select元素select_elem = driver.find_element(By.ID, "city")select = Select(select_elem)# 按索引选(从0开始)select.select_by_index(2)# 按value属性选select.select_by_value("beijing")# 按显示的文字选(最常用)select.select_by_visible_text("北京市")
4. 鼠标悬停操作
模拟鼠标移到某个元素上,触发悬浮菜单。
from selenium.webdriver.common.action_chains import ActionChains# 定位要悬停的元素menu = driver.find_element(By.ID, "menu")# 创建动作链对象,执行悬停ActionChains(driver).move_to_element(menu).perform()
5. 页面截图
# 截取整个页面,保存为图片driver.get_screenshot_as_file("页面截图.png")# 截取某个元素的截图element = driver.find_element(By.ID, "code")element.screenshot("验证码截图.png")
6. 执行 JavaScript 代码
遇到 Selenium 不好操作的场景,可以直接执行 JS 代码,非常万能。
# 滚动页面到最底部driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")# 滚动到指定元素位置element = driver.find_element(By.ID, "target")driver.execute_script("arguments[0].scrollIntoView();", element)# 修改元素属性,比如把隐藏的输入框变成可见driver.execute_script("arguments[0].style.display='block';", element)
八、新手高频报错 & 避坑指南
1. NoSuchElementException:找不到元素
这是最常见的报错,原因基本就这几个:
- 页面还没加载完
- 定位写错了
- 元素在 iframe 里
- 元素在新标签页里
- 元素被遮挡 / 不可见
2. ElementNotInteractableException:元素不可交互
找到了元素,但点不了、输不进去,常见原因:
- 元素还没加载完成 解决:先关掉弹窗,或者等元素可点击再操作。
3. 被网站识别为自动化工具
很多网站会检测 Selenium,弹出验证码或者直接拒绝访问。 简单的规避方法:
- 加启动参数,去掉自动化标识:
from selenium.webdriver.chrome.options import Optionschrome_options = Options()# 去掉webdriver标识chrome_options.add_argument("--disable-blink-features=AutomationControlled")# 无头模式(不显示浏览器窗口,后台运行)# chrome_options.add_argument("--headless")driver = webdriver.Chrome(options=chrome_options)
4. 无头模式(后台运行)
不想看到浏览器窗口,让它在后台默默运行,加 --headless 参数即可,适合部署到服务器。
注意:无头模式更容易被反爬检测,调试时建议开着窗口,稳定运行再用无头。
九、综合实战:抓取豆瓣电影 Top250 第一页
用 Selenium 抓取豆瓣电影 Top250 的电影名和评分,演示动态页面数据抓取。
from selenium import webdriverfrom selenium.webdriver.common.by import Byimport time# 创建浏览器,加隐式等待driver = webdriver.Chrome()driver.implicitly_wait(10)driver.maximize_window()# 打开豆瓣Top250driver.get("https://movie.douban.com/top250")# 找到所有电影条目items = driver.find_elements(By.XPATH, '//div[@class="item"]')print("豆瓣电影Top250 第一页:\n")for item in items: # 在item内部继续找,用相对路径(点开头) title = item.find_element(By.XPATH, './/span[@class="title"]').text score = item.find_element(By.XPATH, './/span[@class="rating_num"]').text print(f"《{title}》 评分:{score}")# 等待3秒看效果time.sleep(3)# 关闭浏览器driver.quit()
说明:豆瓣这个页面用 requests 也能抓,这里只是演示 Selenium 的用法。真正复杂的、需要点击翻页、登录的页面,才是 Selenium 发挥优势的地方。
十、学习建议与总结
- 先练基础:先把元素定位、点击输入、等待这三个核心练熟,这是所有自动化的基础
- 善用开发者工具:浏览器 F12 是最好的帮手,看元素属性、复制 XPath 都靠它
- 从简单场景入手:先做自动搜索、自动填表这类简单脚本,再慢慢做复杂的
- 不要滥用 Selenium
- 静态页面、简单请求 → 用 requests 更快更省资源
- 动态页面、需要登录、复杂交互 → 用 Selenium