目录
- 环境准备
- 第一个 Selenium 脚本
- 核心概念:浏览器驱动
- 核心操作详解
- 定位元素
- 与元素交互
- 获取元素信息
- 处理下拉框和弹窗
- 执行 JavaScript
- 等待策略
- 高级用法
- 页面截图
- 录制屏幕
- 无头模式
- 实战案例:爬取知乎热榜
- 最佳实践与注意事项
环境准备
在开始之前,你需要确保你的电脑上已经安装了以下软件:

- Python: 建议使用 3.6+ 版本。
- Chrome 浏览器: Selenium 将控制它。
- ChromeDriver: 这是 Selenium 控制 Chrome 浏览器的桥梁。
安装 Python 库
打开你的终端或命令提示符,使用 pip 安装 selenium 库:
pip install selenium
下载 ChromeDriver
这是最关键也最容易出错的一步。
-
检查 Chrome 版本: 打开 Chrome 浏览器,进入
设置->Chrome,记下你的 Chrome 版本号(0.5735.199)。 -
下载对应版本的 ChromeDriver:
(图片来源网络,侵删)- 访问官方下载地址:https://googlechromelabs.github.io/chrome-for-testing/
- 找到与你的 Chrome 版本最接近的
chromedriver版本,推荐下载win32或mac-x64或linux64压缩包。 - 重要提示: 从 Chrome 115 版本开始,Google 官方推荐使用这个新链接,旧版的
https://chromedriver.chromium.org/downloads已不再维护。
-
配置环境:
- 方法一 (推荐): 将下载的
chromedriver.exe(Windows) 或chromedriver(Mac/Linux) 文件放到你的 Python 脚本所在的同一个目录下,这样 Selenium 会自动寻找。 - 方法二: 将
chromedriver所在的目录添加到系统的PATH环境变量中,这样你可以在任何地方运行它。
- 方法一 (推荐): 将下载的
第一个 Selenium 脚本
让我们从一个最简单的例子开始:打开 Chrome 浏览器,访问百度,然后关闭。
# 1. 导入 webdriver
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
# 2. 创建一个 Chrome 浏览器实例
# chromedriver 不在脚本同目录或 PATH 中,需要指定其路径
# driver = webdriver.Chrome(executable_path="path/to/your/chromedriver")
driver = webdriver.Chrome()
# 3. 打开一个网页
driver.get("https://www.baidu.com")
# 4. 打印网页标题
print("页面标题是:", driver.title)
# 5. 让浏览器窗口等待 5 秒,方便观察
time.sleep(5)
# 6. 关闭浏览器
driver.quit()
运行这个脚本,你会看到一个 Chrome 窗口自动打开,访问百度,5 秒后自动关闭。
核心概念:浏览器驱动
- WebDriver: Selenium 的核心,是一个浏览器自动化 API,它就像是你的 Python 代码和浏览器之间的“翻译官”。
- 浏览器驱动: 每种浏览器(Chrome, Firefox, Edge 等)都有自己的驱动程序,Chrome 使用
ChromeDriver,Firefox 使用GeckoDriver,你的 Python 代码通过 WebDriver 调用驱动程序,再由驱动程序去控制具体的浏览器。
核心操作详解
1 定位元素
自动化测试的核心就是找到页面上的元素(如按钮、输入框、链接),然后对它们进行操作,Selenium 提供了 8 种定位方式,最常用的前三种:
| 定位方式 | Python 方法 | 描述 | 示例 |
|---|---|---|---|
| ID | find_element(By.ID, "value") |
通过元素的 id 属性定位,最快最可靠 |
find_element(By.ID, "kw") |
| XPath | find_element(By.XPATH, "value") |
通过路径表达式定位,非常强大和灵活 | find_element(By.XPATH, '//input[@id="kw"]') |
| CSS Selector | find_element(By.CSS_SELECTOR, "value") |
通过 CSS 选择器定位,速度也很快,推荐使用 | find_element(By.CSS_SELECTOR, "#kw") |
| Name | find_element(By.NAME, "value") |
通过 name 属性定位 |
find_element(By.NAME, "wd") |
| Tag Name | find_element(By.TAG_NAME, "value") |
通过 HTML 标签名定位(如 div, input) |
find_element(By.TAG_NAME, "input") |
| Class Name | find_element(By.CLASS_NAME, "value") |
通过 class 属性定位 |
find_element(By.CLASS_NAME, "s_ipt") |
| Link Text | find_element(By.LINK_TEXT, "value") |
通过完整的链接文本定位 <a>
| |
| Partial Link Text | find_element(By.PARTIAL_LINK_TEXT, "value") |
通过部分链接文本定位 <a>
|
注意: find_element (单数) 只返回第一个匹配的元素,如果找不到会抛出 NoSuchElementException 异常,如果需要查找所有元素,请使用 find_elements (复数),它返回一个列表。
2 与元素交互
找到元素后,你就可以对它们进行操作了。
# 假设 driver 已经打开百度
# 定位搜索框
search_box = driver.find_element(By.ID, "kw")
# 1. 在搜索框中输入内容
search_box.send_keys("Selenium 教程")
# 2. 模拟按下回车键
search_box.send_keys(Keys.ENTER)
# 或者定位“百度一下”按钮并点击
# search_button = driver.find_element(By.ID, "su")
# search_button.click()
3 获取元素信息
操作之后,通常需要获取一些信息来验证结果。
# 获取元素的文本内容
element = driver.find_element(By.ID, "su")
print("按钮文本:", element.text)
# 获取元素的属性值
print("按钮的 type 属性:", element.get_attribute("type"))
# 获取元素的标签名
print("按钮的标签名:", element.tag_name)
4 处理下拉框和弹窗
-
下拉框: 使用
Select类。from selenium.webdriver.support.ui import Select # 假设有一个 id 为 "country" 的下拉框 select = Select(driver.find_element(By.ID, "country")) # 通过索引选择 (从 0 开始) select.select_by_index(1) # 通过 value 值选择 select.select_by_value("us") # 通过可见文本选择 select.select_by_visible_text("China") -
弹窗:
- 警告框:
driver.switch_to.alert.accept()(点击确定) /dismiss()(点击取消) - 确认框: 同上
- 提示框:
driver.switch_to.alert.send_keys("输入文本")后再accept()
- 警告框:
5 执行 JavaScript
Selenium 可以直接在浏览器中执行任意 JavaScript 代码,这非常强大。
# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 获取页面某个元素的文本 (比 find_element 更直接)
element_text = driver.execute_script("return document.getElementById('kw').value;")
print("通过 JS 获取的搜索框内容:", element_text)
6 等待策略
这是 Selenium 自动化中最重要的概念之一,如果页面元素加载需要时间,而你的代码立即去查找它,很可能会失败,因为元素还没出现。
-
强制等待 (不推荐):
time.sleep(5)- 缺点: 固定等待 5 秒,无论元素是否已经加载好,效率低下。
-
隐式等待 (全局等待):
# 设置一个全局等待时间,10 秒 driver.implicitly_wait(10) # 之后所有的 find_element 操作都会等待最多 10 秒 # 如果元素在 10 秒内出现,立即继续执行;10 秒后还没出现,则抛出异常
- 缺点: 只对
find_element有效,并且一旦设置,全局生效,无法针对特定元素设置不同的等待时间。
- 缺点: 只对
-
显式等待 (强烈推荐): 针对特定元素设置等待条件,最灵活、最精确。
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待最多 10 秒,直到 id 为 "myDynamicElement" 的元素出现 try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) print("元素已找到!") except Exception as e: print("元素在指定时间内未找到:", e) # 等待元素可被点击 # WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "submit-button"))).click()常用的
expected_conditions:EC.presence_of_element_located: 元素出现在 DOM 中,不一定可见。EC.visibility_of_element_located: 元素可见。EC.element_to_be_clickable: 元素可被点击。EC.title_contains: 标题包含特定文本。
高级用法
1 页面截图
# 截取整个浏览器窗口的截图
driver.save_screenshot("baidu_screenshot.png")
# 截取某个特定元素
element = driver.find_element(By.ID, "kw")
element.screenshot("search_box_screenshot.png")
2 录制屏幕
需要安装 selenium-screen-recorder 库。
pip install selenium-screen-recorder
from screen_recorder import ScreenRecorder
# 创建录制器实例
recorder = ScreenRecorder()
# 开始录制
recorder.start("my_recording.mp4")
# ... 你的自动化操作 ...
# 停止录制
recorder.stop()
3 无头模式
在不显示浏览器界面的情况下运行脚本,速度更快,适合在服务器上运行。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建 Chrome 选项对象
chrome_options = Options()
# 添加无头模式参数
chrome_options.add_argument("--headless")
# 还可以设置窗口大小
chrome_options.add_argument("--window-size=1920,1080")
# 使用选项创建浏览器实例
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.baidu.com")
print("无头模式下页面标题:", driver.title)
driver.quit()
实战案例:爬取知乎热榜
目标:打开知乎热榜,获取前 5 条热榜标题、热度、链接并保存到 CSV 文件。
import csv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # 自动管理驱动
# 自动下载并管理 ChromeDriver
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
try:
driver.get("https://www.zhihu.com/hot")
driver.implicitly_wait(5) # 设置一个隐式等待作为保底
# 知乎热榜的标题、链接、热度都在一个 <div class="HotItem-item"> 容器内
hot_items = driver.find_elements(By.CSS_SELECTOR, "div.HotItem-item")
data_to_save = []
for item in hot_items[:5]: # 只取前5条
# 标题和链接在 <a> 标签内
title_element = item.find_element(By.CSS_SELECTOR, "a.HotItem-title")
title = title_element.text
link = title_element.get_attribute("href")
# 热度在 <span class="HotItem-metrics"> 内
heat_element = item.find_element(By.CSS_SELECTOR, "span.HotItem-metrics")
heat = heat_element.text
data_to_save.append([title, heat, link])
print(f"标题: {title}, 热度: {heat}, 链接: {link}")
# 保存到 CSV 文件
with open("zhihu_hot.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerow(["标题", "热度", "链接"]) # 写入表头
writer.writerows(data_to_save) # 写入数据
print("\n数据已成功保存到 zhihu_hot.csv")
finally:
# 无论是否发生异常,最后都要关闭浏览器
driver.quit()
最佳实践与注意事项
-
显式优先: 优先使用
WebDriverWait(显式等待),避免time.sleep()和implicitly_wait。 -
稳定的定位器: 优先使用
ID和CSS Selector,它们比XPath更稳定,因为 XPath 依赖 HTML 的层级结构,容易因页面结构变化而失效。 -
try...finally或with语句: 确保浏览器在任何情况下都能被正确关闭,否则会占用大量内存和 CPU。 -
元素定位优化: 如果一个元素难以定位,可以尝试先定位其父元素,再从父元素中查找子元素,这样更稳定。
parent = driver.find_element(By.ID, "parent-container") child = parent.find_element(By.CLASS_NAME, "child-class")
-
处理 iframe: 如果目标元素在
<iframe>内,必须先切换到该 iframe,才能定位到里面的元素。# 切换到 iframe (可以通过 id, name, 或 WebElement 定位) driver.switch_to.frame("my_iframe_id") # 现在可以操作 iframe 内的元素了 element_in_iframe = driver.find_element(By.ID, "element_id") # 操作完成后,切回主页面 (非常重要!) driver.switch_to.default_content() -
反爬虫: 大量、频繁的自动化操作可能会被网站识别为爬虫,可以采取以下措施:
- 控制速度: 在操作之间加入合理的随机延迟。
- 使用代理: IP 被封时使用代理 IP。
- 模拟人类行为: 随机移动鼠标、滚动页面等(Selenium ActionChains)。
- 使用 Cookies: 登录后保存 Cookies,下次直接加载,避免重复登录。
-
驱动管理: 使用
webdriver-manager这样的库可以自动为你下载和管理正确版本的浏览器驱动,避免手动下载和配置的麻烦。
希望这份详细的教程能帮助你全面掌握 Python Selenium 的用法!
