现代 Selenium 爬虫教程 (2024)
你是不是也经历过这样的场景:用 requests 抓静态页面时飞快无比,可一旦遇上下拉加载、滑块验证、多层 iframe 嵌套、实时刷新 DOM 的动态页面就彻底抓瞎?别担心,这篇文章带你玩转 Selenium 4.x 新 API,并梳理出 2024 年依然好用的反检测与性能优化技巧,让你一站式搞定这些棘手问题。
1. 核心价值 — 为什么还选 Selenium 4?
虽然 Playwright、Puppeteer 等后起之秀势头很猛,但 Selenium 依然是复杂 Web 兼容性场景、遗留系统自动化、跨浏览器验证爬虫的优先选择,原因很实在:
- ✅ 生态最成熟:支持所有主流浏览器和编程语言,社区沉淀深厚;
- ✅ 方案最丰富:反检测、Grid 分布式、持续集成等现成方案遍地开花;
- ✅ 4.x 进步明显:API 更规范、原生支持 CDP(Chrome DevTools Protocol),无头模式也变得更稳定。
2. 极简environment-setup(告别驱动版本匹配的噩梦)
不用再手动下载和浏览器版本严格对应的驱动了,webdriver-manager 已经把这个痛苦环节变成了历史。
2.1 安装依赖包
# 推荐使用 4.15.0,稳定性非常能打
pip install selenium==4.15.0 webdriver-manager tenacity
💡 tenacity 会用于后面的自动重试,让爬虫更“皮实”。
2.2 (可选)安装 Chrome 浏览器
已经安装 Chrome 的可以跳过;如果是在服务器上运行,Linux 下可以用命令快速安装:
# Debian/Ubuntu 示例
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
sudo apt-get install -f # 自动修复可能缺失的依赖
Windows/macOS 直接去官网下载 Chrome 或 Edge 即可。
3. 基础操作:Selenium 4 统一写法
Selenium 4 废弃了一大堆旧 API(比如 find_element_by_id),现在必须使用 By 类统一定位,代码不但更规范,跨版本兼容性也更好。
3.1 一键启动浏览器
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# ✅ 现代初始化方式:自动下载并匹配驱动版本
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized") # 窗口最大化,方便定位元素
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
try:
driver.get("https://www.baidu.com")
print(f"页面标题:{driver.title}") # 输出:百度一下,你就知道
finally:
driver.quit() # 无论是否出错都要关闭,避免残留进程
3.2 常用元素定位与交互
from selenium.webdriver.common.by import By
# 推荐优先级:ID > NAME > CSS_SELECTOR > XPATH
search_box = driver.find_element(By.ID, "kw")
search_btn = driver.find_element(By.CSS_SELECTOR, "#su")
# 基础交互
search_box.send_keys("Selenium 4 爬虫") # 模拟打字
search_box.clear() # 清空输入框
search_box.send_keys("Python 爬虫") # 重新输入
search_btn.click() # 点击“百度一下”
4. advanced-features:搞定反爬、iframe 等棘手场景
光会用是远远不够的,下面这些技巧才是项目实战里真正让你少踩坑的关键。
4.1 显式等待:扔掉不靠谱的 time.sleep()
硬编码的睡眠时间不仅效率低下,还会被反爬系统当成“机器人特征”。显式等待 只针对某个元素达到特定状态时才继续,又快又稳。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
try:
# 等待搜索结果的第一条链接变为可点击,最多等 10 秒
first_result = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "#content_left h3 a"))
)
first_result.click()
finally:
driver.quit()
4.2 处理 iframe 和多窗口
iframe 嵌套、点击链接弹到新标签页……这些场景用 Selenium 4 的切换语法非常简洁。
# 1️⃣ 切换到 iframe(三种方式:ID/NAME、元素对象、索引)
iframe = driver.find_element(By.ID, "login-frame")
driver.switch_to.frame(iframe)
# 在 iframe 里操作
driver.find_element(By.NAME, "username").send_keys("test")
# 务必记得回到主文档!
driver.switch_to.default_content()
# 2️⃣ 切换到新打开的窗口
main_window = driver.current_window_handle # 记录当前句柄
driver.find_element(By.LINK_TEXT, "新标签页链接").click()
# 遍历所有句柄,切换到不是主窗口的那一个
for handle in driver.window_handles:
if handle != main_window:
driver.switch_to.window(handle)
break
# 处理完新窗口后可以关闭它,再切回主窗口
driver.close()
driver.switch_to.window(main_window)
4.3 2024 反检测技术:伪装成真人浏览器
大多数反爬系统会通过检测自动化特有的标记(比如 navigator.webdriver)来识别你。Selenium 4 借助 CDP 可以完美隐藏这些特征。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
options = webdriver.ChromeOptions()
# 1. 隐藏自动化标签
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
# 2. 伪装成真实用户的 User‑Agent(也可搭配 fake_useragent 库随机化)
options.add_argument(
"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
)
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
# 3. 注入脚本:覆盖 navigator.webdriver 等检测属性
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
"""
})
⚠️ 记住:反爬对抗是不断升级的过程,如果遇到强检测的网站,还可以配合 undetected-chromedriver 等定制方案。
4.4 健壮性保障:用 tenacity 自动重试
网络波动、偶发的元素加载延迟是家常便饭,手动 try...except 不仅代码丑,还容易遗漏。用 tenacity 的装饰器可以实现声明式重试。
from tenacity import retry, stop_after_attempt, wait_fixed
from selenium.common.exceptions import TimeoutException, NoSuchElementException
# 对常见的元素异常自动重试 3 次,每次间隔 2 秒
@retry(
stop=stop_after_attempt(3),
wait=wait_fixed(2),
retry=retry_if_exception_type((TimeoutException, NoSuchElementException))
)
def click_login_button(driver):
driver.find_element(By.ID, "login-btn").click()
# 使用起来就像普通函数一样
click_login_button(driver)
5. 性能优化:爬虫跑得更快、更省资源
5.1 现代无头模式(Chrome 112+ 必须这样用)
老旧的无头模式在 DOM 渲染上与正常浏览器存在差异,Chrome 112 开始引入 --headless=new,完美解决了这个问题。
options = webdriver.ChromeOptions()
options.add_argument("--headless=new") # 新•无头模式
options.add_argument("--window-size=1920,1080") # 无头模式必须指定窗口大小
options.add_argument("--blink-settings=imagesEnabled=false") # 禁用图片(节省大量带宽)
options.add_argument("--disable-dev-shm-usage") # 解决 Docker/Linux 内存限制
options.add_argument("--no-sandbox") # 同上,服务端运行必备
把这些参数传入 webdriver.Chrome(options=options) 就能悄无声息地在后台高速爬取。
5.2 混合 Requests + Selenium:速度与动态渲染兼得
不少网站只是登录、获取 Cookie 阶段需要动态交互,后续的数据接口完全可以用 requests 高速请求。这种“前重后轻”的搭配是 2024 年依然经典的做法。
import requests
from selenium import webdriver
# 1. 先用 Selenium 完成登录,获取 Cookies
driver = webdriver.Chrome(service=service, options=options)
try:
driver.get("https://需要登录的网站.com")
# …… 执行登录操作(输入用户名密码、点击登录、等待跳转)……
# 将 Cookies 格式化为 requests 可用的字典
cookies = {c["name"]: c["value"] for c in driver.get_cookies()}
finally:
driver.quit()
# 2. 后续通过 requests 携带 Cookies 高速抓取数据
session = requests.Session()
session.cookies.update(cookies)
response = session.get("https://需要登录的网站.com/api/data")
print(response.json()) # 直接处理 JSON 数据,效率拉满
6. 总结:Selenium 爬虫的正确打开姿势
- 统一 API:全面拥抱 Selenium 4.x 的
By 定位、CDP 命令;
- 反检测优先:隐藏
webdriver 标记、随机化 User‑Agent、避免死板的硬等待;
- 性能拉满:使用新版无头模式、禁止图片加载、在合适场景组合
requests;
- 稳定至上:用显式等待取代
time.sleep(),配合 tenacity 让代码自带重试体质;
- 选型灵活:如果目标只是现代网站且无需跨浏览器,Playwright 也很值得尝试~
有了这篇文章的方法,你已经可以搭建一个高效、稳定、反检测能力不俗的 Selenium 爬虫了。如果遇到棘手问题,欢迎在评论区继续讨论~