6
Selenium 自动化
Selenium: Real Browser Automation
Selenium 就是雇了个真人帮你点浏览器——它能打开真 Chrome、执行 JS、点按钮、填表单。requests 搞不定的动态渲染页面,Selenium 上。
安装与第一个自动化
pip install selenium webdriver-manager
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
# 自动下载匹配的 ChromeDriver
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://www.example.com")
title = driver.find_element(By.TAG_NAME, "h1").text
print(title)
driver.quit() # 一定记得关!
基本操作:找元素、点、填
# 找元素:By.ID / By.XPATH / By.CSS_SELECTOR / By.NAME
search = driver.find_element(By.NAME, "q")
search.send_keys("Python") # 输入文字
search.submit() # 提交表单
# 点击按钮
btn = driver.find_element(By.XPATH, "//button[text()='搜索']")
btn.click()
# 读文本和属性
elem = driver.find_element(By.CSS_SELECTOR, ".title")
print(elem.text) # 可见文本
print(elem.get_attribute("href")) # 属性值
# 执行 JS
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
等待:别硬等,用显式等待
# 硬等待 time.sleep(2):笨,但简单
import time; time.sleep(2)
# 隐式等待:全局找不到就等10秒
driver.implicitly_wait(10)
# 显式等待(推荐):等某个条件出现
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".result"))
) # 最多等10秒,出现就继续
三种等待方式对比
| 方式 | 怎么用 | 评价 |
|---|---|---|
| 硬等待 | time.sleep(2) | 简单但笨,浪费时间 |
| 隐式等待 | driver.implicitly_wait(10) | 全局找元素最多等10秒 |
| 显式等待 | WebDriverWait.until(EC.xxx) | 最推荐,等条件出现 |
切换窗口与 iframe
# 新窗口:切换 handle
driver.switch_to.window(driver.window_handles[1])
# iframe:网页里套网页,得切进去
driver.switch_to.frame("iframe-id")
# 操作完切回主页面
driver.switch_to.default_content()
# 弹窗 alert
alert = driver.switch_to.alert
alert.accept() # 确定
alert.dismiss() # 取消
Cookie 操作
# 拿所有 Cookie
cookies = driver.get_cookies()
# 拿指定 Cookie
driver.get_cookie("sessionid")
# 加 Cookie(登录后手动带上)
driver.add_cookie({"name": "sessionid", "value": "abc123"})
# 删 Cookie
driver.delete_cookie("sessionid")
driver.delete_all_cookies()
常用选择器对照表
| 方式 | 示例 | 什么时候用 |
|---|---|---|
| By.ID | By.ID, "username" | 元素有 id |
| By.NAME | By.NAME, "q" | 表单 name 属性 |
| By.CSS_SELECTOR | By.CSS_SELECTOR, ".item h2" | 最常用,CSS 选择器 |
| By.XPATH | By.XPATH, "//button[text()='登录']" | 要按文本/层级找 |
| By.CLASS_NAME | By.CLASS_NAME, "item" | 单个 class |
| By.LINK_TEXT | By.LINK_TEXT, "下一页" | 按链接文本 |
执行 JavaScript
# Selenium 能跑 JS,干 requests 干不了的事
# 滚动到底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
# 隐藏元素
driver.execute_script("document.querySelector('.popup').style.display='none'")
# 获取 JS 变量
token = driver.execute_script("return window.__INITIAL_STATE__.token")
无头模式:后台运行不弹窗
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new") # 无头,不弹窗
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options, service=Service(ChromeDriverManager().install()))
完整案例:模拟登录 + 爬数据
# login_spider.py —— 模拟登录后爬需要权限的页面
driver.get("https://example.com/login")
# 填用户名密码
driver.find_element(By.ID, "username").send_keys("tom")
driver.find_element(By.ID, "password").send_keys("123456")
driver.find_element(By.ID, "submit").click()
# 等跳转完成
WebDriverWait(driver, 10).until(
EC.url_contains("dashboard")
)
# 现在爬登录后页面
driver.get("https://example.com/my-data")
items = driver.find_elements(By.CSS_SELECTOR, ".data-item")
for item in items:
print(item.text)
运行输出
# 登录成功,跳转到 dashboard
# 2026年9月订单:¥1,280.00
# 2026年8月订单:¥960.00
# ...
Selenium 慢
Selenium 开真浏览器,每个操作都要等页面渲染,比 requests 慢 10-100 倍。能用 requests 就别 Selenium——只有动态渲染、必须登录、必须执行 JS 时才上。大规模爬虫用 Scrapy 或 aiohttp。
Selenium 常见坑
| 坑 | 怎么避 |
|---|---|
| 元素还没加载就找 | 用显式等待 WebDriverWait |
| 窗口找不到 | switch_to.window 切换 handle |
| iframe 里找元素 | switch_to.frame 先进去 |
| 驱动版本不匹配 | 用 webdriver-manager 自动管理 |
| 忘了 quit() | 进程残留,用 try/finally 确保关闭 |
本章面试题 · Selenium
1.(概念题)为什么 Selenium 比 requests 慢?什么时候用它?
查看答案
答案:Selenium 启动真浏览器,要渲染页面、执行 JS、等元素出现,每步都有开销。只在 requests 搞不定时用:动态渲染、必须登录、必须执行 JS。
2.(概念题)为什么用显式等待而不是 time.sleep?
查看答案
答案:time.sleep(2) 不管元素出没出现都等 2 秒,浪费时间;显式等待(WebDriverWait)元素一出现就继续,快且稳。网络慢时 sleep 2 秒可能不够,显式等待最多等 10 秒。
3.(代码题)怎么在无头模式下运行 Chrome?
查看答案
答案:options.add_argument("--headless=new"),传 options 给 webdriver.Chrome(options=options)。生产爬虫都用无头,不弹窗。