11-Python爬虫高阶:Selenium处理动态网页

有些网页内容是用JavaScript动态生成的,requests爬不到怎么办?Selenium来帮你模拟真实浏览器!

普通爬虫 vs Selenium

普通爬虫(requests) Selenium
原理 直接请求服务器 模拟真实浏览器
动态内容 ❌ 拿不到 ✅ 可以获取
速度 较慢
资源占用 较高
适用场景 静态页面 JS动态渲染页面

什么时候用Selenium?

1
2
3
4
5
✅ 滚动加载更多内容
✅ 点击"加载更多"按钮
✅ 模拟登录(需要执行JS)
✅ 验证码处理
✅ 需要等待页面渲染完成

二、安装与配置

1. 安装Selenium

1
pip install selenium

2. 安装浏览器驱动

Selenium需要搭配浏览器驱动使用:

Chrome浏览器(推荐)

1
2
3
4
5
6
7
# 方法1:自动下载(推荐)
pip install webdriver-manager

# 方法2:手动下载
# 1. 查看Chrome版本:chrome://version/
# 2. 下载对应版本的ChromeDriver
# 3. https://googlechromelabs.github.io/chrome-for-testing/

Firefox浏览器

1
pip install geckodriver-autoinstaller

3. 快速开始

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# 自动下载并配置ChromeDriver
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# 访问网页
driver.get('https://www.example.com')

# 获取页面源码(包含JS渲染后的内容)
print(driver.page_source)

# 关闭浏览器
driver.quit()

三、Selenium基础操作

1. 打开和关闭网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# 启动浏览器
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# 打开网页
driver.get('https://www.example.com')

# 打印标题
print(driver.title)

# 获取当前URL
print(driver.current_url)

# 后退
driver.back()

# 前进
driver.forward()

# 刷新
driver.refresh()

# 关闭当前标签页
driver.close()

# 关闭整个浏览器
driver.quit()

2. 元素定位

Selenium有8种定位方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 假设HTML:<input id="username" name="user" class="form-input" type="text">

# 1. By ID(最快)
element = driver.find_element('id', 'username')

# 2. By NAME
element = driver.find_element('name', 'user')

# 3. By CLASS NAME
element = driver.find_element('class name', 'form-input')

# 4. By TAG NAME
elements = driver.find_elements('tag name', 'input') # 返回列表

# 5. By LINK TEXT(链接精确文字)
element = driver.find_element('link text', '查看详情')

# 6. By PARTIAL LINK TEXT(部分文字)
element = driver.find_element('partial link text', '详情')

# 7. By XPATH(最灵活)
element = driver.find_element('xpath', '//input[@id="username"]')

# 8. By CSS SELECTOR
element = driver.find_element('css selector', 'input#username')

3. 常用操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from selenium.webdriver.common.by import By

# 定位元素
element = driver.find_element(By.ID, 'username')

# 获取文本
print(element.text)

# 获取属性
print(element.get_attribute('class')) # form-input
print(element.get_attribute('outerHTML')) # 完整HTML

# 输入文字
element.send_keys('my_username')

# 清空输入框
element.clear()

# 点击按钮
button = driver.find_element(By.ID, 'submit')
button.click()

# 获取元素大小
print(element.size)

# 判断元素是否可见
print(element.is_displayed())

# 判断元素是否可用
print(element.is_enabled())

四、等待机制

页面加载需要时间,必须等待元素出现才能操作。

1. 强制等待(不推荐)

1
2
3
import time

time.sleep(3) # 强制等待3秒

2. 隐式等待(全局生效)

1
driver.implicitly_wait(10)  # 等待最多10秒

3. 显式等待(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

# 等待元素出现
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'content'))
)

# 等待元素可点击
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, 'btn-submit'))
)

# 常用预期条件
EC.presence_of_element_located # 元素出现在DOM中
EC.visibility_of_element_located # 元素可见
EC.element_to_be_clickable # 元素可点击
EC.title_is # 标题是...
EC.text_to_be_present_in_element # 元素包含指定文字

五、实战案例

案例1:爬取滚动加载的页面

很多网站是滚动到下面自动加载更多内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

try:
# 打开目标页面
driver.get('https://example.com/news')

# 等待初始内容加载
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, 'article-item'))
)

# 滚动加载更多
item_count = 0
while True:
# 滚动到页面底部
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')

# 等待新内容加载
time.sleep(2)

# 统计当前文章数量
new_count = len(driver.find_elements(By.CLASS_NAME, 'article-item'))

if new_count == item_count:
# 没有新内容加载了,退出循环
break

item_count = new_count
print(f'已加载 {item_count} 篇文章')

# 获取所有文章标题
articles = driver.find_elements(By.CLASS_NAME, 'article-item')
for i, article in enumerate(articles, 1):
title = article.find_element(By.CLASS_NAME, 'title').text
print(f'{i}. {title}')

print(f'\n🎉 共获取 {len(articles)} 篇文章!')

finally:
driver.quit()

案例2:点击”加载更多”按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import TimeoutException

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

try:
driver.get('https://example.com/products')

while True:
try:
# 查找"加载更多"按钮
load_more = driver.find_element(By.CLASS_NAME, 'load-more-btn')

# 如果按钮可见且可点击
if load_more.is_displayed() and load_more.is_enabled():
load_more.click()
print('✅ 点击了"加载更多"')
time.sleep(2) # 等待加载
else:
break

except Exception:
# 没有更多按钮了
print('✅ 没有更多内容了')
break

# 获取所有产品
products = driver.find_elements(By.CLASS_NAME, 'product-item')
print(f'\n🎉 共获取 {len(products)} 个产品!')

finally:
driver.quit()

案例3:模拟登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import time

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

try:
# 打开登录页
driver.get('https://example.com/login')

# 输入账号密码
driver.find_element(By.NAME, 'username').send_keys('your_account')
driver.find_element(By.NAME, 'password').send_keys('your_password')

# 点击登录按钮
driver.find_element(By.CLASS_NAME, 'login-btn').click()

# 等待登录成功
time.sleep(3)

# 检查是否登录成功
if '欢迎' in driver.page_source:
print('✅ 登录成功!')
else:
print('❌ 登录失败')

finally:
driver.quit()

案例4:处理弹窗和Alert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from selenium import webdriver
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import time

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

try:
driver.get('https://example.com')

# 触发弹窗(示例)
driver.find_element(By.ID, 'show-alert').click()
time.sleep(1)

# 切换到弹窗
alert = driver.switch_to.alert

# 获取弹窗文字
print(alert.text)

# 点击确定
alert.accept()

# 或者点击取消
# alert.dismiss()

finally:
driver.quit()

案例5:切换iframe

1
2
3
4
5
6
7
8
9
10
11
12
# iframe是一种嵌套的网页,需要切换进去才能操作
driver.get('https://example.com')

# 切换到iframe
iframe = driver.find_element(By.CLASS_NAME, 'my-iframe')
driver.switch_to.frame(iframe)

# 现在可以在iframe里操作了
driver.find_element(By.ID, 'content').send_keys('hello')

# 操作完切换回主文档
driver.switch_to.default_content()

案例6:截图和窗口管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 截图整个页面
driver.save_screenshot('page.png')

# 截取某个元素
element = driver.find_element(By.ID, 'content')
element.screenshot('element.png')

# 获取窗口句柄
print(driver.current_window_handle)

# 打开新标签页
driver.execute_script('window.open()')

# 切换到新标签页
windows = driver.window_handles
driver.switch_to.window(windows[-1])

# 获取所有标签页标题
for handle in windows:
driver.switch_to.window(handle)
print(driver.title)

六、Selenium配置选项

无头模式(不显示浏览器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
options.add_argument('--headless') # 无头模式
options.add_argument('--disable-gpu') # 禁用GPU加速
options.add_argument('--window-size=1920,1080') # 设置窗口大小

driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options
)

反检测设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
options = Options()
options.add_argument('--headless')
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)

driver = webdriver.Chrome(options=options)

# 移除webdriver特征
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
})

其他常用配置

1
2
3
4
5
6
7
options = Options()
options.add_argument('--start-maximized') # 最大化启动
options.add_argument('--incognito') # 无痕模式
options.add_argument('--disable-popup-blocking') # 禁止弹窗拦截
options.add_argument('--disable-images') # 不加载图片(加快速度)
options.add_argument('blink-settings=imagesEnabled=false') # 禁用图片
options.add_argument('--proxy-server=http://ip:port') # 代理

七、常见问题

问题 解决方法
元素找不到 加等待时间、用显式等待
元素不可点击 等待元素可点击、滚动到可见
页面加载慢 减少等待时间、禁用图片
被识别为爬虫 用无头模式、换代理、改UA
ChromeDriver不匹配 用webdriver-manager自动匹配
内存占用高 用完及时quit()、用无头模式

八、完整项目:爬取某东商品评论

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import TimeoutException

def scrape_comments(product_url, max_pages=5):
"""爬取商品评论"""

options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1920,1080')

driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options
)

all_comments = []

try:
driver.get(product_url)
print(f'正在爬取: {driver.title}')

# 切换到评论标签
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, 'tab-comment'))
).click()

# 爬取多页评论
for page in range(1, max_pages + 1):
print(f'正在爬取第 {page} 页...')

# 等待评论列表加载
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, 'comment-item'))
)

# 提取当前页评论
comments = driver.find_elements(By.CLASS_NAME, 'comment-item')
for comment in comments:
try:
text = comment.find_element(By.CLASS_NAME, 'comment-text').text
user = comment.find_element(By.CLASS_NAME, 'user-name').text
rating = comment.find_element(By.CLASS_NAME, 'rating').get_attribute('title')
all_comments.append({
'用户': user,
'评分': rating,
'内容': text
})
except:
continue

print(f' ✅ 已获取 {len(all_comments)} 条评论')

# 点击下一页
try:
next_btn = driver.find_element(By.CLASS_NAME, 'next-btn')
if 'disabled' in next_btn.get_attribute('class'):
print('✅ 已到达最后一页')
break
next_btn.click()
time.sleep(2) # 等待加载
except:
print('✅ 没有下一页了')
break

return all_comments

finally:
driver.quit()

# 调用
comments = scrape_comments('https://item.jd.com/100000000.html', max_pages=3)
print(f'\n🎉 共爬取 {len(comments)} 条评论!')

# 保存到文件
import json
with open('comments.json', 'w', encoding='utf-8') as f:
json.dump(comments, f, ensure_ascii=False, indent=2)

九、写在最后

这篇学会了:

1
2
3
4
5
6
7
✅ Selenium安装配置
✅ 元素定位与操作
✅ 显式等待机制
✅ 滚动加载、点击加载更多
✅ 模拟登录、处理弹窗
iframe切换
✅ 无头模式配置

下篇预告:模拟登录深入、验证码处理(图片验证码、滑动验证码)、代理IP池构建。

如果这篇文章对你有帮助,欢迎点赞+在看👍

有问题欢迎留言,我们一起进步!

#AI学习 #Python爬虫 #Selenium #动态网页 #模拟浏览器


11-Python爬虫高阶:Selenium处理动态网页
https://yourname.github.io/2026/02/08/11-Selenium动态网页/
作者
JA
发布于
2026年2月8日
许可协议