目录
引言:为什么 Requests 爬不到数据?Selenium 才是动态页面的 “克星”
1.1 Selenium vs Requests:核心差异对比
1.2 Selenium 的核心优势:3 个让你放弃 Requests 的理由
二、环境搭建:3 分钟搞定 Chrome+Selenium(Windows/Mac 通用)
2.1 步骤 1:安装 Chrome 浏览器(已安装的跳过)
三、Selenium 核心基础:元素定位与操作(8 种定位方式 + 5 种常用操作)
3.2 8 种元素定位方式(实战常用 3 种,全掌握更灵活)
四、Selenium 实战项目:10 个常见场景,覆盖 90% 使用需求
项目 5:自动处理弹窗(alert/confirm/prompt)
项目 6:某宝商品信息爬取(处理 iframe 和动态加载)
项目 8:Headless 模式运行(无界面爬取,提高效率)
项目 10:Selenium 结合 BeautifulSoup(提取复杂页面数据)
五、避坑指南:Selenium 新手常踩的 8 个坑及解决方案
坑 2:元素定位不到(NoSuchElementException)
坑 3:元素不可点击(ElementClickInterceptedException)
6.2 Selenium 结合 IP 代理(应对 IP 封禁)

class 卑微码农:
def __init__(self):
self.技能 = ['能读懂十年前祖传代码', '擅长用Ctrl+C/V搭建世界', '信奉"能跑就别动"的玄学']
self.发量 = 100 # 初始发量
self.咖啡因耐受度 = '极限'
def 修Bug(self, bug):
try:
# 试图用玄学解决问题
if bug.严重程度 == '离谱':
print("这一定是环境问题!")
else:
print("让我看看是谁又没写注释...哦,是我自己。")
except Exception as e:
# 如果try块都救不了,那就...
print("重启一下试试?")
self.发量 -= 1 # 每解决一个bug,头发-1
# 实例化一个我
我 = 卑微码农()
引言:为什么 Requests 爬不到数据?Selenium 才是动态页面的 “克星”
如果你用 Python Requests 写过爬虫,大概率遇到过这些 “绝望时刻”:“用 Requests 爬某商品列表,返回的 HTML 全是空的,连个商品名称都没有”;“想爬某音评论,F12 看 HTML 里明明有评论内容,用 response.text 却找不到,全是 JS 代码”;“模拟登录某网站,输入账号密码后点登录,结果页面跳转后还是未登录状态,Requests 根本处理不了 JS 渲染”。

这些问题的根源只有一个 ——你爬的是动态页面。Requests 只能获取静态 HTML,而现代网站(某宝、某音、某乎)的内容大多靠 JavaScript 动态加载,甚至登录、交互都依赖 JS 执行。这时候,就需要 “能模拟真实浏览器” 的工具 ——Python Selenium。
Selenium 本质是 “自动化测试工具”,但在爬虫领域堪称 “动态页面杀手”—— 它能像人一样打开浏览器,自动输入文字、点击按钮、滚动页面,还能运行网页里的 JS 代码,拿到 JS 加载后的完整数据。不管是动态评论、JS 加密的登录、需要滑动验证的页面,Selenium 都能搞定。
这篇博客不会讲枯燥的理论,而是从 “新手能上手” 的角度,带你从环境搭建到 10 个实战案例,一步步掌握 Selenium。每个知识点都配 “详细操作步骤 + 带注释的代码 + 运行结果”,你跟着复制粘贴就能跑通,遇到的 “ChromeDriver 报错”“元素定位不到”“页面加载慢” 等坑,我也会把自己踩过的解决方案告诉你 —— 看完这篇,你再也不用对着动态页面 “抓瞎” 了。
一、Selenium 入门:搞懂它为什么能搞定动态页面

在动手前,先搞清楚 Selenium 和 Requests 的核心区别,知道它到底能解决什么问题,避免学完不知道怎么用。
1.1 Selenium vs Requests:核心差异对比
很多新手以为 Selenium 是 “升级版 Requests”,其实两者的工作原理完全不同 ——Requests 是 “直接发 HTTP 请求”,Selenium 是 “模拟浏览器操作”,就像 “写信” 和 “上门拜访” 的区别。
| 对比维度 | Requests | Selenium |
|---|---|---|
| 工作原理 | 直接发送 HTTP 请求,获取静态 HTML | 启动真实浏览器,执行 JS,获取渲染后的数据 |
| 动态页面支持 | 不支持(无法运行 JS) | 完全支持(浏览器自动运行 JS) |
| 元素交互 | 无法模拟点击、输入等操作 | 支持点击、输入、下拉、滑动等所有交互 |
| 性能 | 快(无浏览器开销),适合静态页面 | 慢(有浏览器开销),适合动态页面 |
| 反爬风险 | 易被识别(无浏览器指纹) | 不易被识别(模拟真实用户行为) |
| 适用场景 | 静态网页爬取(豆瓣 Top250、博客园) | 动态页面 / 交互场景 |
举个例子:爬取某音某视频的评论(动态加载)
- 用 Requests:发请求拿到的 HTML 里只有 JS 代码,没有评论内容,因为评论是滚动页面后 JS 动态加载的;
- 用 Selenium:打开某音页面,自动滚动到底部,等待 JS 加载评论,再提取已经渲染好的评论数据 —— 和你手动操作浏览器看到的内容完全一致。
1.2 Selenium 的核心优势:3 个让你放弃 Requests 的理由
- 搞定动态页面:不管是 JS 加载的列表、AJAX 请求的评论,还是需要点击才显示的内容,Selenium 都能像人一样操作浏览器,拿到最终渲染后的页面数据;
- 模拟真实交互:自动填写表单、点击按钮、切换窗口、处理弹窗,甚至能滑动验证码(配合 PIL 识别),解决 Requests 搞不定的登录、验证场景;
- 低反爬风险:Selenium 启动的浏览器有完整的 “浏览器指纹”(User-Agent、Cookie、本地存储),行为和真实用户一致,网站很难识别是爬虫。
二、环境搭建:3 分钟搞定 Chrome+Selenium(Windows/Mac 通用)

Selenium 需要 “浏览器 + WebDriver” 配合才能工作 ——WebDriver 是控制浏览器的 “驱动程序”,不同浏览器对应不同的 WebDriver(Chrome 用 ChromeDriver,Firefox 用 GeckoDriver)。这里推荐用Chrome 浏览器 + ChromeDriver,因为最稳定、文档最全。
2.1 步骤 1:安装 Chrome 浏览器(已安装的跳过)
-
Windows 用户:
- 打开 Chrome 官网下载最新版 Chrome,默认安装;
- 安装完成后,打开 Chrome,点击右上角 “三个点”→“设置”→“关于 Chrome”,查看浏览器版本,记下来,后面下载 Driver 要用。
-
Mac 用户:
- 从 App Store 或 Chrome 官网下载 Chrome,安装后打开;
- 点击顶部 “Chrome”→“关于 Chrome”,查看版本号,同样记下来。
2.2 步骤 2:下载对应版本的 ChromeDriver
ChromeDriver 必须和 Chrome 浏览器版本 “匹配”(比如 Chrome 126.x,Driver 也要是 126.x),版本不匹配会直接报错,这是新手最常踩的坑!
下载步骤:
-
打开 ChromeDriver 下载地址)
-
根据 Chrome 版本选择 Driver 版本:
- 比如 Chrome 版本是 “126.0.6478.126”,就找开头是 “126.0.6478” 的 Driver 版本(后面的小版本号不用完全一致,比如 126.0.6478.182 也能用);
- 选择对应系统的压缩包(Windows 选 “win32.zip”,Mac 选 “mac64.zip” 或 “mac_arm64.zip”,根据电脑芯片选)。
-
解压 ChromeDriver:
- Windows:解压后得到 “chromedriver.exe”,把它放到 Python 的 Scripts 目录下(比如 “C:\Python310\Scripts”,如果不知道 Python 路径,命令行输入
where python查看); - Mac:解压后得到 “chromedriver”,把它放到 “/usr/local/bin” 目录下(打开终端,输入
sudo mv ~/Downloads/chromedriver /usr/local/bin/,需要输入电脑密码)。
- Windows:解压后得到 “chromedriver.exe”,把它放到 Python 的 Scripts 目录下(比如 “C:\Python310\Scripts”,如果不知道 Python 路径,命令行输入
2.3 步骤 3:安装 Selenium 库
打开命令行(Windows 用 CMD,Mac 用终端),输入以下命令安装 Selenium:
# Windows/Mac通用
pip install selenium
如果是 Python 3.x,可能需要用pip3:
# Mac/Linux用户可能需要
pip3 install selenium
2.4 步骤 4:验证环境是否配置成功
写一段简单的代码,测试能否启动 Chrome 并打开网页:
# 导入Selenium的webdriver模块
from selenium import webdriver
# 导入时间模块,用于等待页面加载
import time
# 1. 启动Chrome浏览器(如果配置了环境变量,不用指定Driver路径)
driver = webdriver.Chrome()
# 2. 打开官网
driver.get("https://www.XXXX.net/")
# 3. 等待3秒,让页面加载完成(模拟人看页面的时间)
time.sleep(3)
# 4. 打印页面标题(验证是否成功打开)
print("当前页面标题:", driver.title)
# 5. 关闭浏览器
driver.quit()
运行结果:
- 会自动弹出 Chrome 浏览器,打开 XXXX 官网;
- 3 秒后,命令行输出 “当前页面标题: XXXX- 专业开发者社区”;
- 浏览器自动关闭。
如果出现以下问题,按对应方案解决:
- “chromedriver.exe not found”:Driver 没放到环境变量目录,解决方法:在
webdriver.Chrome()中手动指定 Driver 路径,比如:# Windows示例:指定chromedriver.exe的路径 driver = webdriver.Chrome(executable_path="C:\\Downloads\\chromedriver.exe") # Mac示例:指定chromedriver的路径 driver = webdriver.Chrome(executable_path="/Users/yourname/Downloads/chromedriver") - “version not match”:Driver 版本和 Chrome 不匹配,回到步骤 2 重新下载对应版本的 Driver;
- Chrome 闪退:检查 Driver 路径是否正确,或重启电脑后再试。
三、Selenium 核心基础:元素定位与操作(8 种定位方式 + 5 种常用操作)

Selenium 的核心是 “找到元素→操作元素”—— 比如找到 “用户名输入框”→输入文字,找到 “登录按钮”→点击。这部分是基础,必须掌握,否则后面实战根本没法动手。
3.1 先搞懂:什么是 “元素”?怎么看元素结构?
网页上的每个控件都是 “元素”—— 输入框、按钮、链接、图片、下拉框,这些都对应 HTML 中的标签(如<input> <button> <a>)。要定位元素,首先要知道元素的 “特征”(如 id、class、xpath),这些特征可以用 Chrome 开发者工具查看。
查看元素特征的步骤:
- 打开 Chrome,访问目标网页;
- 按
F12打开开发者工具,切换到 “Elements” 标签; - 点击左上角的 “选择元素” 按钮(图标是□,或按
Ctrl+Shift+C); - 鼠标点击网页上的 “用户名输入框”,开发者工具会自动定位到对应的 HTML 标签,比如:
<input type="text" class="base-input-text" id="alliance-user-name" name="alliance-user-name" placeholder="手机号/邮箱/用户名" autocomplete="off"> - 从这个标签中,能看到元素的特征:id 是 “alliance-user-name”,class 是 “base-input-text”,name 是 “alliance-user-name”—— 这些都能用来定位元素。
3.2 8 种元素定位方式(实战常用 3 种,全掌握更灵活)
Selenium 提供了 8 种定位元素的方法,对应find_element()系列函数(定位单个元素)和find_elements()系列函数(定位多个元素,返回列表)。最常用的是id 定位、XPath 定位、CSS Selector 定位,其他方式根据场景选用。
| 定位方式 | 函数(单个元素) | 函数(多个元素) | 适用场景 |
|---|---|---|---|
| id | find_element (By.ID, "id 值") | find_elements (By.ID, "id 值") | 元素有唯一 id(优先用,最稳定) |
| name | find_element (By.NAME, "name 值") | find_elements (By.NAME, "name 值") | 元素有 name 属性(如表单输入框) |
| class name | find_element (By.CLASS_NAME, "类名") | find_elements (By.CLASS_NAME, "类名") | 元素有 class 属性(注意类名不能有空格) |
| tag name | find_element (By.TAG_NAME, "标签名") | find_elements (By.TAG_NAME, "标签名") | 定位同类标签(如所有<a>链接) |
| link text | find_element (By.LINK_TEXT, "链接文本") | find_elements (By.LINK_TEXT, "链接文本") | 定位超链接(精确匹配文本) |
| partial link text | find_element (By.PARTIAL_LINK_TEXT, "部分文本") | find_elements (By.PARTIAL_LINK_TEXT, "部分文本") | 定位超链接(模糊匹配文本) |
| XPath | find_element (By.XPATH, "xpath 表达式") | find_elements (By.XPATH, "xpath 表达式") | 万能定位(复杂场景必用) |
| CSS Selector | find_element (By.CSS_SELECTOR, "css 表达式") | find_elements (By.CSS_SELECTOR, "css 表达式") | 灵活定位(前端开发者常用) |
实战示例:定位 XXXX登录页的元素
以登录页的 “用户名输入框”“密码输入框”“登录按钮” 为例,用不同方式定位:
from selenium import webdriver
from selenium.webdriver.common.by import By # 导入By类,用于指定定位方式
import time
# 启动Chrome并打开XXXX登录页
driver = webdriver.Chrome()
driver.get("https://passport.xxx.net/login?code=applets")
time.sleep(3) # 等待页面加载
# 1. 定位用户名输入框(id定位,最优先)
username_input = driver.find_element(By.ID, "alliance-user-name")
print("用户名输入框元素:", username_input)
# 2. 定位密码输入框(name定位)
password_input = driver.find_element(By.NAME, "alliance-user-password")
print("密码输入框元素:", password_input)
# 3. 定位登录按钮(XPath定位,复制自Chrome开发者工具)
# 如何复制XPath:Elements标签中右键元素→Copy→Copy XPath
login_button = driver.find_element(By.XPATH, '//*[@id="app"]/div/div[2]/div/div[2]/div[1]/form/div[3]/button')
print("登录按钮元素:", login_button)
# 4. 定位“记住我”复选框(CSS Selector定位,复制自Chrome开发者工具)
# 如何复制CSS Selector:Elements标签中右键元素→Copy→Copy selector
remember_checkbox = driver.find_element(By.CSS_SELECTOR, "#app > div > div.login-box > div > div.login-form > div.login-form-item.remember-item > label > input[type=checkbox]")
print("记住我复选框:", remember_checkbox)
time.sleep(5)
driver.quit()
关键技巧:用 Chrome 开发者工具自动生成定位表达式
不用手动写 XPath 或 CSS Selector,直接复制:
- Elements 标签中找到目标元素,右键点击;
- 复制 XPath:
Copy → Copy XPath(绝对路径)或Copy → Copy full XPath(相对路径,推荐); - 复制 CSS Selector:
Copy → Copy selector; - 直接粘贴到代码中,稍作修改即可(比如绝对路径改相对路径,更稳定)。
3.3 5 种常用元素操作(输入、点击、获取文本等)
定位到元素后,最常用的操作有 5 种:输入文字、点击、获取文本、获取属性、清除内容。每种操作都对应元素对象的方法。
操作方法汇总:
| 操作 | 方法 | 示例 |
|---|---|---|
| 输入文字 | element.send_keys ("内容") | username_input.send_keys("123456") |
| 点击元素 | element.click() | login_button.click() |
| 获取元素文本 | element.text | print(login_button.text) |
| 获取元素属性 | element.get_attribute ("属性名") | print(input.get_attribute("placeholder")) |
| 清除输入内容 | element.clear() | username_input.clear() |
实战示例:模拟登录 (完整操作流程)
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
# 启动Chrome并打开登录页
driver = webdriver.Chrome()
driver.get("https://passport.xxx.net/login?code=applets")
driver.maximize_window() # 最大化浏览器窗口(避免元素被遮挡)
time.sleep(3)
try:
# 1. 定位并输入用户名(替换成你的XXXX账号)
username_input = driver.find_element(By.ID, "alliance-user-name")
username_input.clear() # 先清除输入框(防止有默认内容)
username_input.send_keys("你的手机号/邮箱") # 替换成实际账号
time.sleep(1) # 等待1秒,模拟人输入的间隔
# 2. 定位并输入密码(替换成你的XXXX密码)
password_input = driver.find_element(By.NAME, "alliance-user-password")
password_input.clear()
password_input.send_keys("你的密码") # 替换成实际密码
time.sleep(1)
# 3. 定位并点击“登录”按钮
login_button = driver.find_element(By.XPATH, '//*[@id="app"]/div/div[2]/div/div[2]/div[1]/form/div[3]/button')
login_button.click()
time.sleep(5) # 等待登录跳转
# 4. 验证是否登录成功(判断页面标题是否包含“XXXX”)
if "XXXX" in driver.title:
print("登录成功!当前页面标题:", driver.title)
# 5. 获取登录后的用户名(定位用户名元素,获取文本)
user_name = driver.find_element(By.XPATH, '//*[@id="xxxx-toolbar"]/div/div/div[3]/div[1]/div[1]/a/span').text
print("当前登录用户:", user_name)
else:
print("登录失败,可能需要验证码!")
except Exception as e:
print("操作出错:", e)
finally:
time.sleep(10) # 停留10秒,让你看到结果
driver.quit() # 无论是否出错,都关闭浏览器
注意事项:
- 登录验证码问题:如果要求输入验证码(图形验证码、短信验证码),上面的代码会卡住,后面会讲验证码的解决方案;
- 元素遮挡:如果点击按钮时提示 “元素被遮挡”,可以先最大化窗口(
driver.maximize_window()),或滚动页面到元素可见位置; - 输入间隔:用
time.sleep(1)模拟人输入的速度,避免被网站识别为爬虫。
3.4 等待机制:解决 “元素还没加载就定位” 的坑
新手最常遇到的错误之一:“NoSuchElementException”(找不到元素),原因是代码执行速度比页面加载快,元素还没渲染出来,代码就去定位了。Selenium 提供了 3 种等待方式,解决这个问题。
3 种等待方式对比:
| 等待方式 | 原理 | 适用场景 |
|---|---|---|
| 强制等待(sleep) | time.sleep (秒数),固定等待 | 简单场景,调试时用(不推荐实战) |
| 隐式等待 | driver.implicitly_wait (秒数),全局等待元素加载 | 全局生效,适合大部分场景 |
| 显式等待 | WebDriverWait + 预期条件,等待特定元素加载 | 复杂场景(如动态加载列表、弹窗) |
实战示例:显式等待(推荐,最灵活)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # 显式等待类
from selenium.webdriver.support import expected_conditions as EC # 预期条件
# 启动Chrome
driver = webdriver.Chrome()
driver.get("https://www.xxxx.net/")
# 1. 隐式等待:全局设置,所有元素定位最多等待10秒
driver.implicitly_wait(10)
# 2. 显式等待:等待“热门文章”标题出现,最多等待15秒
# 预期条件:元素可见(EC.visibility_of_element_located)
try:
# WebDriverWait(驱动, 最长等待时间, 轮询间隔).until(预期条件)
hot_article_title = WebDriverWait(driver, 15, 0.5).until(
EC.visibility_of_element_located((By.XPATH, '//*[@id="mainContent"]/div[1]/div[1]/h2'))
)
print("热门文章标题:", hot_article_title.text)
except Exception as e:
print("等待超时,未找到元素:", e)
driver.quit()
常用预期条件(expected_conditions):
EC.visibility_of_element_located:元素可见(存在且显示在页面上);EC.presence_of_element_located:元素存在(不一定可见);EC.element_to_be_clickable:元素可点击(可见且 Enabled);EC.text_to_be_present_in_element:元素文本包含指定内容;EC.alert_is_present:弹窗出现。
实战建议:隐式等待全局设置(10 秒),复杂场景用显式等待,尽量不用time.sleep()(固定等待不灵活,容易浪费时间或等待不够)。
四、Selenium 实战项目:10 个常见场景,覆盖 90% 使用需求

学会基础操作后,用实战项目巩固 —— 选 10 个用户最常遇到的场景,从简单到复杂,每个项目都有完整代码和运行说明,跟着做就能跑通。
项目 1:自动打开网页并截图(生成网页报告)
需求:自动打开首页,等待页面加载完成后截图,保存到本地。代码:
from selenium import webdriver
import time
import os
# 启动Chrome
driver = webdriver.Chrome()
driver.get("https://www.xxx.net/")
driver.maximize_window()
time.sleep(5) # 等待页面完全加载
# 截图并保存(路径:当前目录下的xxxx_screenshot.png)
screenshot_path = os.path.join(os.getcwd(), "xxxx_screenshot.png")
driver.save_screenshot(screenshot_path)
print(f"截图已保存到:{screenshot_path}")
driver.quit()
运行结果:当前代码目录下生成 “xxxx_screenshot.png”,包含 xxxx首页的完整截图。
项目 2:自动填写并提交表单(模拟注册)
需求:自动打开某测试表单页面,填写表单并提交,打印提交结果。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
# 打开测试表单页面
driver.get("http://xxx.org/forms/post")
try:
# 1. 填写姓名(input标签,name="custname")
name_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "custname"))
)
name_input.send_keys("张三")
# 2. 选择套餐(radio按钮,value="medium")
medium_radio = driver.find_element(By.XPATH, '//input[@value="medium"]')
medium_radio.click()
# 3. 选择配送时间(select下拉框,需要用Select类)
from selenium.webdriver.support.ui import Select
time_select = Select(driver.find_element(By.NAME, "delivery"))
time_select.select_by_value("13:00") # 按value选择
# 也可以按索引选择:time_select.select_by_index(2)
# 按文本选择:time_select.select_by_visible_text("14:00")
# 4. 填写备注(textarea标签,name="comments")
comments_textarea = driver.find_element(By.NAME, "comments")
comments_textarea.send_keys("请放在小区门口快递柜,谢谢!")
# 5. 提交表单(button标签,type="submit")
submit_btn = driver.find_element(By.XPATH, '//form//button[@type="submit"]')
submit_btn.click()
# 6. 等待提交结果加载,打印结果
result = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.TAG_NAME, "pre"))
)
print("表单提交结果:")
print(result.text)
except Exception as e:
print("表单填写出错:", e)
finally:
input("按回车键关闭浏览器...") # 暂停,让你查看结果
driver.quit()
关键知识点:下拉框用Select类处理,支持按 value、索引、文本选择,这是表单操作的常用场景。
项目 3:爬取某音评论(动态加载页面)
需求:自动打开某音某视频页面,滚动页面加载更多评论,提取前 20 条评论并打印。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome()
# 某音视频链接(替换成你想爬的视频)
driver.get("https://v.mouyin.com/iJd5qkDm/")
driver.maximize_window()
try:
# 1. 等待页面加载,切换到评论iframe(某音评论在iframe中,必须先切换)
# 如何判断iframe:Elements标签中搜索<iframe>,评论相关标签在iframe内
WebDriverWait(driver, 15).until(
EC.frame_to_be_available_and_switch_to_it(
(By.XPATH, '//iframe[contains(@src, "comment")]')
)
)
print("已切换到评论iframe")
# 2. 滚动页面加载更多评论(滚动3次,每次滚动到底部)
for i in range(3):
# 执行JS滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print(f"第{i+1}次滚动,等待评论加载...")
time.sleep(3) # 等待评论加载
# 3. 提取前20条评论(评论内容在class为"comment-content"的div中)
comments = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located(
(By.CLASS_NAME, "comment-content")
)
)
# 4. 打印评论
print(f"\n共提取到{len(comments)}条评论,前20条:")
for idx, comment in enumerate(comments[:20], 1):
print(f"{idx}. {comment.text.strip()}")
except Exception as e:
print("爬取评论出错:", e)
finally:
# 切换回主文档(离开iframe)
driver.switch_to.default_content()
input("按回车键关闭浏览器...")
driver.quit()
关键知识点:某音评论在iframe中,必须用switch_to.frame()切换才能定位元素;动态加载的内容用execute_script()执行 JS 滚动页面,触发加载。
项目 4:自动登录 Git(处理表单和跳转)
需求:自动打开 Git 登录页,输入账号密码,点击登录,验证是否登录成功并打印个人主页信息。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 替换成你的GitHub账号密码
GITHUB_USERNAME = "你的GitHub用户名"
GITHUB_PASSWORD = "你的GitHub密码"
driver = webdriver.Chrome()
driver.get("https://github.com/login")
try:
# 1. 输入用户名(id="login_field")
username_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "login_field"))
)
username_input.send_keys(GITHUB_USERNAME)
# 2. 输入密码(id="password")
password_input = driver.find_element(By.ID, "password")
password_input.send_keys(GITHUB_PASSWORD)
# 3. 点击登录按钮(name="commit")
login_btn = driver.find_element(By.NAME, "commit")
login_btn.click()
# 4. 等待登录跳转,验证是否成功(个人主页的头像是否可见)
WebDriverWait(driver, 15).until(
EC.visibility_of_element_located(
(By.XPATH, '//*[@aria-label="View profile and more"]')
)
)
print("GitHub登录成功!")
# 5. 跳转到个人主页,打印仓库数量
driver.get(f"https://github.com/{GITHUB_USERNAME}")
repo_count = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located(
(By.XPATH, '//*[@id="user-profile-frame"]//span[contains(text(), "Repositories")]/following-sibling::span')
)
)
print(f"当前用户仓库数量:{repo_count.text.strip()}")
except Exception as e:
print("GitHub登录出错:", e)
finally:
input("按回车键关闭浏览器...")
driver.quit()
注意事项:如果 Git 开启了两步验证,需要额外处理(比如接收短信验证码),后面进阶部分会讲验证码解决方案。
项目 5:自动处理弹窗(alert/confirm/prompt)
需求:自动打开测试弹窗页面,处理 alert 弹窗(确定)、confirm 弹窗(取消)、prompt 弹窗(输入内容并确定)。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.alert import Alert
driver = webdriver.Chrome()
# 打开测试弹窗页面(本地HTML,也可以用在线测试页)
driver.get("https://www.w3schools.com/js/tryit.asp?filename=tryjs_alert")
try:
# 切换到iframe(测试页面的JS在iframe中)
driver.switch_to.frame("iframeResult")
# 1. 处理alert弹窗(点击"Try it"按钮,弹出alert,点击确定)
alert_btn = driver.find_element(By.XPATH, '//button[text()="Try it"]')
alert_btn.click()
# 等待alert弹窗出现,切换到alert
alert = WebDriverWait(driver, 5).until(EC.alert_is_present())
print("Alert弹窗内容:", alert.text) # 打印弹窗文本
alert.accept() # 点击确定
print("已处理alert弹窗(确定)")
# 2. 处理confirm弹窗(先添加一个confirm按钮,执行JS)
driver.execute_script('''
const btn = document.createElement('button');
btn.textContent = 'Try Confirm';
btn.onclick = function() { confirm('确定要删除吗?'); };
document.body.appendChild(btn);
''')
confirm_btn = driver.find_element(By.XPATH, '//button[text()="Try Confirm"]')
confirm_btn.click()
# 处理confirm弹窗
confirm = WebDriverWait(driver, 5).until(EC.alert_is_present())
print("Confirm弹窗内容:", confirm.text)
confirm.dismiss() # 点击取消
print("已处理confirm弹窗(取消)")
# 3. 处理prompt弹窗(执行JS创建prompt按钮)
driver.execute_script('''
const btn = document.createElement('button');
btn.textContent = 'Try Prompt';
btn.onclick = function() { prompt('请输入你的名字:', '张三'); };
document.body.appendChild(btn);
''')
prompt_btn = driver.find_element(By.XPATH, '//button[text()="Try Prompt"]')
prompt_btn.click()
# 处理prompt弹窗
prompt = WebDriverWait(driver, 5).until(EC.alert_is_present())
print("Prompt弹窗内容:", prompt.text)
prompt.send_keys("李四") # 输入内容
prompt.accept() # 点击确定
print("已处理prompt弹窗(输入'李四'并确定)")
except Exception as e:
print("处理弹窗出错:", e)
finally:
driver.switch_to.default_content()
input("按回车键关闭浏览器...")
driver.quit()
关键知识点:弹窗用Alert类处理,accept()是确定,dismiss()是取消,send_keys()用于 prompt 输入内容。
项目 6:某宝商品信息爬取(处理 iframe 和动态加载)
需求:自动打开某宝搜索页,搜索 “Python 编程书籍”,滚动加载商品,提取前 10 件商品的名称、价格、销量。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome()
driver.get("https://www.xxx.com/")
driver.maximize_window()
try:
# 1. 输入搜索关键词(id="q")
search_input = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "q"))
)
search_input.send_keys("Python编程书籍")
# 2. 点击搜索按钮(class="btn-search")
search_btn = driver.find_element(By.CLASS_NAME, "btn-search")
search_btn.click()
time.sleep(3) # 等待搜索结果加载
# 3. 处理某宝登录弹窗(如果出现)
try:
# 点击“密码登录”(如果有弹窗)
login_btn = WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="login"]/div[1]/i'))
)
login_btn.click()
print("请手动完成某宝登录(扫码或输入账号密码)...")
# 等待用户手动登录完成(120秒超时)
WebDriverWait(driver, 120).until(
EC.title_contains("Python编程书籍 - 某宝搜索")
)
except:
print("未出现登录弹窗,继续爬取...")
# 4. 滚动页面加载更多商品(滚动2次)
for i in range(2):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print(f"第{i+1}次滚动,等待商品加载...")
time.sleep(4)
# 5. 提取商品信息(商品项class="item J_MouserOnverReq ",注意空格)
products = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located(
(By.XPATH, '//div[@class="item J_MouserOnverReq "]')
)
)
# 6. 解析商品信息
print(f"\n共提取到{len(products)}件商品,前10件:")
for idx, product in enumerate(products[:10], 1):
# 商品名称(class="J_ClickStat")
name = product.find_element(By.CLASS_NAME, "J_ClickStat").text.strip()
# 商品价格(class="J_price")
price = product.find_element(By.CLASS_NAME, "J_price").text.strip()
# 商品销量(class="J_comment")
sales = product.find_element(By.CLASS_NAME, "J_comment").text.strip()
print(f"{idx}. 名称:{name[:50]}... | 价格:{price} | 销量:{sales}")
except Exception as e:
print("爬取某宝商品出错:", e)
finally:
input("按回车键关闭浏览器...")
driver.quit()
注意事项:某宝反爬较严,可能需要手动登录(扫码或输入账号密码),代码中预留了 120 秒等待时间;商品 class 有空格,定位时要完整复制。
项目 7:自动生成网页截图报告(多页面截图拼接)
需求:自动打开 XXX、GitHub、某乎三个网站,分别截图,将截图路径生成一个 HTML 报告。代码:
from selenium import webdriver
import time
import os
# 要截图的网站列表
websites = [
{"name": "xxx", "url": "https://www.xxx.net/"},
{"name": "GitHub", "url": "https://github.com/"},
{"name": "某乎", "url": "https://www.zzz.com/"}
]
# 截图保存目录
screenshot_dir = os.path.join(os.getcwd(), "website_screenshots")
if not os.path.exists(screenshot_dir):
os.makedirs(screenshot_dir)
# 启动Chrome
driver = webdriver.Chrome()
driver.maximize_window()
# 存储截图路径
screenshot_paths = []
try:
for site in websites:
name = site["name"]
url = site["url"]
print(f"正在处理{name}...")
# 打开网站
driver.get(url)
# 等待页面加载
time.sleep(5)
# 截图并保存
screenshot_path = os.path.join(screenshot_dir, f"{name}_screenshot.png")
driver.save_screenshot(screenshot_path)
screenshot_paths.append({
"name": name,
"url": url,
"path": screenshot_path
})
print(f"{name}截图已保存:{screenshot_path}")
# 生成HTML报告
report_content = f"""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>网站截图报告</title>
<style>
body {{ font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }}
.site {{ margin-bottom: 50px; }}
.site h2 {{ color: #333; }}
.site img {{ max-width: 100%; border: 1px solid #eee; }}
.site a {{ color: #0066cc; text-decoration: none; }}
</style>
</head>
<body>
<h1>网站截图报告</h1>
<p>生成时间:{time.strftime("%Y-%m-%d %H:%M:%S")}</p>
<hr>
"""
for path_info in screenshot_paths:
report_content += f"""
<div class="site">
<h2>{path_info['name']}</h2>
<p>网址:<a href="{path_info['url']}" target="_blank">{path_info['url']}</a></p>
<p>截图:</p>
<img src="{os.path.abspath(path_info['path'])}" alt="{path_info['name']}截图">
</div>
"""
report_content += """
</body>
</html>
"""
# 保存HTML报告
report_path = os.path.join(os.getcwd(), "website_screenshot_report.html")
with open(report_path, "w", encoding="utf-8") as f:
f.write(report_content)
print(f"\nHTML报告已生成:{report_path}")
print("打开报告即可查看所有网站截图!")
except Exception as e:
print("生成截图报告出错:", e)
finally:
driver.quit()
运行结果:生成 “website_screenshots” 目录(包含 3 个网站的截图)和 “website_screenshot_report.html”,打开 HTML 报告能看到每个网站的截图和链接。
项目 8:Headless 模式运行(无界面爬取,提高效率)
需求:用 Headless 模式(无浏览器界面)爬取豆瓣 Top250 电影名称,不弹出浏览器,后台运行。代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options # 导入Chrome选项类
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 配置Headless模式
chrome_options = Options()
chrome_options.add_argument("--headless=new") # 启用Headless模式(Chrome 112+推荐)
chrome_options.add_argument("--disable-gpu") # 禁用GPU加速(避免部分环境报错)
chrome_options.add_argument("--window-size=1920,1080") # 设置窗口大小(模拟桌面)
chrome_options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36") # 设置User-Agent
# 启动Headless模式的Chrome
driver = webdriver.Chrome(options=chrome_options)
try:
driver.get("https://movie.douban.com/top250")
print("已打开豆瓣Top250(Headless模式,无界面)")
# 提取前10部电影名称
movie_names = WebDriverWait(driver, 15).until(
EC.presence_of_all_elements_located(
(By.XPATH, '//div[@class="hd"]/a/span[1]')
)
)
print("\n豆瓣Top250前10部电影:")
for idx, name in enumerate(movie_names[:10], 1):
print(f"{idx}. {name.text}")
except Exception as e:
print("Headless模式爬取出错:", e)
finally:
driver.quit()
print("\n爬虫已结束(Headless模式)")
关键知识点:Headless 模式适合服务器环境(无桌面)或需要提高效率的场景,不弹出浏览器,资源占用少;Chrome 112 + 用--headless=new,旧版本用--headless。
项目 9:处理滑动验证码(模拟人类滑动,登录某网站)
需求:模拟登录某带滑动验证码的测试网站(https://www.geetest.com/demo/slide-float.html),自动滑动验证码完成验证。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains # 用于模拟鼠标操作
import time
import random
driver = webdriver.Chrome()
driver.get("https://www.geetest.com/demo/slide-float.html")
driver.maximize_window()
try:
# 1. 点击“开始验证”按钮
start_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, "geetest_radar_tip"))
)
start_btn.click()
time.sleep(2)
# 2. 定位滑动验证码的滑块和背景
# 滑块(class="geetest_slider_button")
slider = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, "geetest_slider_button"))
)
# 背景图(class="geetest_canvas_bg geetest_absolute")
bg = driver.find_element(By.CLASS_NAME, "geetest_canvas_bg")
# 3. 模拟人类滑动:先快速滑动,再缓慢调整(避免被识别为机器)
action = ActionChains(driver)
# 按住滑块
action.click_and_hold(slider).perform()
time.sleep(0.2) # 按住后停留0.2秒
# 滑动逻辑:总距离约260px(根据实际情况调整)
total_distance = 260
# 分3段滑动:加速→匀速→减速
# 第一段:滑动180px,较快
action.move_by_offset(xoffset=180, yoffset=0).perform()
time.sleep(random.uniform(0.1, 0.3)) # 随机停留0.1-0.3秒
# 第二段:滑动60px,较慢
action.move_by_offset(xoffset=60, yoffset=0).perform()
time.sleep(random.uniform(0.2, 0.4))
# 第三段:滑动20px,缓慢调整
action.move_by_offset(xoffset=20, yoffset=0).perform()
time.sleep(random.uniform(0.1, 0.2))
# 松开滑块
action.release().perform()
print("已完成滑动验证,等待结果...")
# 4. 验证是否成功
time.sleep(3)
success_msg = driver.find_element(By.CLASS_NAME, "geetest_success_radar_tip_content")
if success_msg.text == "验证成功":
print("滑动验证码验证成功!")
else:
print("验证失败,可能需要重新尝试...")
except Exception as e:
print("处理滑动验证码出错:", e)
finally:
input("按回车键关闭浏览器...")
driver.quit()
关键知识点:用ActionChains模拟鼠标滑动,分阶段滑动(加速→匀速→减速),加入随机停留时间,模拟人类操作,避免被验证码系统识别为机器。
项目 10:Selenium 结合 BeautifulSoup(提取复杂页面数据)
需求:用 Selenium 打开某乎专栏页面,获取页面 HTML 后,用 BeautifulSoup 解析文章标题和链接(结合两者优势:Selenium 处理动态加载,BeautifulSoup 高效解析)。代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup # 导入BeautifulSoup
import time
driver = webdriver.Chrome()
# 某乎专栏页面(比如“Python技术”专栏)
driver.get("https://zhuanlan.xxx.com/python-cafe")
driver.maximize_window()
try:
# 1. 等待页面加载,滚动到底部(加载更多文章)
WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.CLASS_NAME, "ColumnPageHeader-title"))
)
# 滚动到底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3)
# 2. 获取页面HTML,交给BeautifulSoup解析
page_html = driver.page_source
soup = BeautifulSoup(page_html, "lxml")
# 3. 用BeautifulSoup提取文章信息(文章项class="ArticleItem-root")
articles = soup.find_all("div", class_="ArticleItem-root")
print(f"共提取到{len(articles)}篇文章:")
for idx, article in enumerate(articles[:15], 1):
# 文章标题(class="ArticleItem-title")
title_tag = article.find("h2", class_="ArticleItem-title")
title = title_tag.text.strip() if title_tag else "未知标题"
# 文章链接(a标签的href属性)
link_tag = title_tag.find("a") if title_tag else None
link = link_tag["href"] if (link_tag and "href" in link_tag.attrs) else "无链接"
# 文章作者(class="UserLink-link")
author_tag = article.find("a", class_="UserLink-link")
author = author_tag.text.strip() if author_tag else "未知作者"
print(f"{idx}. 标题:{title}")
print(f" 作者:{author}")
print(f" 链接:https://zhuanlan.xxx.com{link}\n")
except Exception as e:
print("提取某乎专栏文章出错:", e)
finally:
input("按回车键关闭浏览器...")
driver.quit()
关键优势:Selenium 负责获取动态加载后的完整 HTML,BeautifulSoup 负责高效解析(比 Selenium 的find_element()更快),两者结合兼顾动态页面处理和解析效率。
五、避坑指南:Selenium 新手常踩的 8 个坑及解决方案

Selenium 虽然强大,但新手很容易踩坑,这里总结 8 个最常见的问题,每个问题都给具体的解决方案,帮你少走弯路。
坑 1:ChromeDriver 版本不匹配,浏览器闪退
现象:启动 Chrome 时闪退,命令行提示 “session not created: This version of ChromeDriver only supports Chrome version XX”。原因:ChromeDriver 版本和 Chrome 浏览器版本不匹配(比如 Driver 是 125.x,Chrome 是 126.x)。解决方案:
- 查看 Chrome 版本:Chrome→设置→关于 Chrome,记下图标后的版本号(如 126.0.6478.126);
- 下载对应版本的 ChromeDriver:找开头为 “126.0.6478” 的 Driver;
- 替换旧的 Driver,或在代码中手动指定新 Driver 路径:
driver = webdriver.Chrome(executable_path="C:\\new_chromedriver.exe")
坑 2:元素定位不到(NoSuchElementException)
现象:代码运行时报错 “selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element”。常见原因及解决方案:
- 元素在 iframe 中:切换到 iframe 后再定位,代码:
# 按id切换iframe driver.switch_to.frame("iframe_id") # 按XPath切换iframe driver.switch_to.frame(driver.find_element(By.XPATH, '//iframe[@src="xxx"]')) # 操作完成后切换回主文档 driver.switch_to.default_content() - 页面还没加载完成:用显式等待,等待元素可点击后再定位(见 3.4 节);
- 定位表达式错误:用 Chrome 开发者工具重新复制 XPath/CSS Selector,检查是否有拼写错误;
- 元素是动态生成的:滚动页面或点击其他元素触发元素生成,再定位。
坑 3:元素不可点击(ElementClickInterceptedException)
现象:元素能定位到,但点击时报错 “element click intercepted: Element is not clickable at point”。原因:元素被其他控件遮挡(如弹窗、广告、导航栏),或元素不在可视区域。解决方案:
- 最大化浏览器窗口:
driver.maximize_window(); - 滚动页面到元素可见位置:
# 执行JS滚动到元素 driver.execute_script("arguments[0].scrollIntoView();", element) time.sleep(1) # 等待滚动完成 element.click() - 用 JS 点击元素(绕过遮挡检查):
driver.execute_script("arguments[0].click();", element)
坑 4:Headless 模式下元素定位不到
现象:正常模式能定位到元素,Headless 模式下报错 “找不到元素”。原因:Headless 模式窗口大小默认很小,元素可能被隐藏或未加载。解决方案:
- 配置 Headless 模式时设置窗口大小:
chrome_options.add_argument("--window-size=1920,1080") - 设置 User-Agent,模拟正常浏览器:
chrome_options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36") - 增加等待时间,确保页面加载完成。
坑 5:验证码处理不了(登录卡住)
现象:模拟登录时遇到图形验证码、短信验证码,代码无法自动处理,卡住不动。解决方案:
- 手动验证码:预留时间让用户手动输入,代码:
input("请手动完成验证码,完成后按回车键继续...") - 图形验证码:用 PIL+Tesseract 识别简单验证码,或用第三方接口(如超级鹰、云打码)识别复杂验证码;
- 短信验证码:用短信接码平台(如阿里云短信、腾讯云短信)接收验证码(需付费,适合商业场景);
- Cookie 登录:手动登录后复制 Cookie,在 Selenium 中添加 Cookie,跳过验证码(见 3.2 节)。
坑 6:浏览器启动慢,占用资源多
现象:每次启动 Chrome 都要几秒,且内存占用高,影响爬取效率。解决方案:
- 启用 Headless 模式(无界面运行,见项目 8),资源占用减少 50% 以上;
- 禁用 Chrome 不必要的插件和服务,配置选项:
chrome_options.add_argument("--disable-extensions") # 禁用扩展 chrome_options.add_argument("--disable-plugins") # 禁用插件 chrome_options.add_argument("--no-sandbox") # 禁用沙箱模式(Linux环境推荐) - 复用已打开的 Chrome 浏览器,避免每次重启(进阶技巧,适合长时间爬取)。
坑 7:中文乱码(截图或获取文本时中文显示为 “□”)
现象:截图中中文显示为方框,或element.text获取的中文是乱码。原因:Chrome 缺少中文字体,或页面编码设置错误。解决方案:
- 安装 Chrome 中文字体(Windows/Mac 默认有,Linux 需手动安装 “WenQuanYi Zen Hei”);
- 在代码中设置页面编码(如果是 HTML 页面):
driver.execute_script("document.charset='utf-8';") - 截图时确保浏览器窗口大小足够,中文不被截断。
坑 8:爬取速度过快被封 IP
现象:短时间内多次请求,网站返回 403 错误,IP 被封禁。解决方案:
- 增加等待时间,模拟人类操作:
time.sleep(random.uniform(2, 5)) # 随机等待2-5秒 - 启用 IP 代理,轮换 IP(见进阶部分);
- 轮换 User-Agent,配置 Chrome 选项:
user_agents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15" ] chrome_options.add_argument(f"--user-agent={random.choice(user_agents)}") - 避免频繁点击同一按钮或访问同一 URL,模拟真实用户行为路径。
六、进阶学习:Selenium 高级用法与拓展场景

掌握基础和实战后,可以学习这些高级用法,应对更复杂的需求。
6.1 复用已打开的 Chrome 浏览器(避免每次重启)
场景:长时间爬取时,每次重启 Chrome 很耗时,复用已打开的浏览器能节省时间。操作步骤:
- 关闭所有 Chrome 窗口;
- 打开命令行,执行以下命令(启动 Chrome 并开启调试模式):
- Windows:
chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\ChromeDebugSession" - Mac:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir="/Users/yourname/ChromeDebugSession"
- Windows:
- 代码中连接已打开的 Chrome:
from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 不需要指定Driver路径,复用已打开的浏览器 driver = webdriver.Chrome(options=chrome_options) print("已连接到已打开的Chrome浏览器") driver.get("https://www.xxxx.net/")
6.2 Selenium 结合 IP 代理(应对 IP 封禁)
场景:爬取频繁被封 IP,用代理 IP 轮换解决。代码示例:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 配置代理(替换成你的代理IP和端口)
proxy_ip = "123.45.67.89:8080"
chrome_options = Options()
# 设置HTTP代理
chrome_options.add_argument(f"--proxy-server=http://{proxy_ip}")
# 设置HTTPS代理(如果代理支持)
# chrome_options.add_argument(f"--proxy-server=https://{proxy_ip}")
# 启动Chrome并使用代理
driver = webdriver.Chrome(options=chrome_options)
try:
driver.get("http://httpbin.org/ip") # 测试代理IP是否生效
print("当前IP(代理后):", driver.find_element(By.TAG_NAME, "pre").text)
except Exception as e:
print("代理使用出错:", e)
finally:
driver.quit()
注意事项:选择支持 HTTPS 的代理,免费代理稳定性差,实战推荐用付费代理(如讯代理、阿布云)。
6.3 Selenium 自动化测试场景(拓展用途)
Selenium 不仅能爬取数据,还能做自动化测试,比如测试网站功能是否正常:示例:测试 xxxx登录功能是否正常:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_xxxx_login(username, password):
driver = webdriver.Chrome()
driver.get("https://passport.xxxx.net/login?code=applets")
try:
# 输入账号密码
driver.find_element(By.ID, "alliance-user-name").send_keys(username)
driver.find_element(By.NAME, "alliance-user-password").send_keys(password)
# 点击登录
driver.find_element(By.XPATH, '//*[@id="app"]/div/div[2]/div/div[2]/div[1]/form/div[3]/button').click()
# 验证登录是否成功
WebDriverWait(driver, 10).until(
EC.title_contains("xxxx")
)
print("xxxx登录测试通过!")
return True
except Exception as e:
print(f"xxxx登录测试失败:{e}")
return False
finally:
driver.quit()
# 测试正确账号密码
test_xxxx_login("正确账号", "正确密码")
# 测试错误密码
test_xxxx_login("正确账号", "错误密码")
七、总结与学习建议
7.1 本文核心知识点回顾
- 环境搭建:Chrome+ChromeDriver 配置,解决版本不匹配问题;
- 核心基础:8 种元素定位方式(重点 id、XPath、CSS Selector),5 种元素操作(输入、点击、获取文本),3 种等待机制(显式等待最推荐);
- 实战能力:10 个实战项目覆盖动态页面爬取、表单提交、弹窗处理、验证码滑动、Headless 模式等场景;
- 避坑技巧:解决元素定位不到、不可点击、IP 封禁、验证码等常见问题;
- 进阶拓展:复用浏览器、代理 IP、自动化测试等高级用法。
7.2 学习建议
- 多练实战:不要只看代码,跟着敲每个示例,遇到错误自己排查(比如定位不到元素,先查 iframe、等待时间、定位表达式);
- 善用开发者工具:Chrome 的 Elements、Network 标签是定位元素、分析动态请求的 “神器”,必须熟练使用;
- 记录问题:把自己踩过的坑(如版本不匹配、iframe 切换)和解决方案记下来,形成自己的 “避坑手册”;
- 关注反爬策略:网站反爬会升级,定期学习新的反爬应对方法(如滑动验证码、指纹识别);
- 拓展学习:学完 Selenium 后,可以学 Playwright(微软推出的新一代自动化工具,更稳定)、Scrapy-Splash(Scrapy 结合 Splash 处理动态页面)。
最后,Selenium 的核心是 “模拟真实浏览器行为”,只要你能手动操作浏览器完成的事情,Selenium 都能自动化完成。坚持多练、多查、多总结,你很快就能用 Selenium 搞定各种动态页面爬取和自动化需求!
附录:Selenium 常用 API 汇总
| 类别 | 常用 API | 说明 |
|---|---|---|
| 浏览器操作 | driver.get(url) | 打开网页 |
| driver.quit() | 关闭浏览器 | |
| driver.close() | 关闭当前窗口 | |
| driver.maximize_window() | 最大化窗口 | |
| driver.save_screenshot(path) | 截图 | |
| driver.page_source | 获取页面 HTML | |
| 元素定位 | driver.find_element(By.ID, value) | 定位单个元素 |
| driver.find_elements(By.XPATH, value) | 定位多个元素 | |
| 元素操作 | element.send_keys(text) | 输入文字 |
| element.click() | 点击元素 | |
| element.text | 获取元素文本 | |
| element.get_attribute(name) | 获取元素属性 | |
| 等待机制 | WebDriverWait(driver, timeout) | 显式等待 |
| driver.implicitly_wait(timeout) | 隐式等待 | |
| 窗口 /iframe | driver.switch_to.window(window_name) | 切换窗口 |
| driver.switch_to.frame(frame) | 切换 iframe | |
| 鼠标操作 | ActionChains(driver).click_and_hold(element) | 按住元素 |
| ActionChains(driver).move_by_offset(x, y) | 移动鼠标 | |
| JS 执行 | driver.execute_script(js) | 执行 JavaScript 代码 |
1443

被折叠的 条评论
为什么被折叠?



