
本文详解 Selenium 爬虫中常见的作用域与缩进错误,指出 new_music 字典构建和 append() 操作必须置于循环体内,同时纠正 By.CLASS_NAME 的误用,推荐改用更精准的 By.CSS_SELECTOR 定位策略。
本文详解 selenium 爬虫中常见的作用域与缩进错误,指出 `new_music` 字典构建和 `append()` 操作必须置于循环体内,同时纠正 `by.class_name` 的误用,推荐改用更精准的 `by.css_selector` 定位策略。
在使用 Selenium 进行网页数据抓取时,一个高频陷阱是:本意想为每条记录创建独立字典并追加到列表中,结果却只得到最后一个元素。这通常并非逻辑缺陷,而是 Python 缩进引发的作用域误解——关键代码未正确嵌套在 for 循环内。
回顾原始代码问题:
for music in musics:
title = ... # ✅ 在循环内获取字段
album = ...
artist = ...
duration = ...
print(title, album, artist, duration)
new_music = { ... } # ❌ 缩进错误!此行在循环外执行
songs.append(new_music) # ❌ 同样在循环外,仅执行一次由于 new_music = {...} 和 songs.append(...) 未缩进至 for 循环内部,Python 将其视为循环结束后才执行的单次操作。此时 title、album 等变量仅保留最后一次迭代的值,最终列表 songs 中仅存一个字典。
✅ 正确做法是将字典构建与追加操作严格缩进至循环体中:
from selenium import webdriver
from selenium.webdriver.common.by import By
url = 'https://open.spotify.com/playlist/37i9dQZF1DXbTop77dnX35'
driver = webdriver.Chrome() # 推荐 Chrome(Edge 需确保驱动兼容)
driver.get(url)
# 使用 CSS_SELECTOR 替代错误拼接的 CLASS_NAME(更稳定、语义清晰)
song_elements = driver.find_elements(By.CSS_SELECTOR, ".IjYxRc5luMiDPhKhZVUH.UpiE7J6vPrJIa59qxts4")
songs = [] # 初始化空列表
for song in song_elements:
try:
title = song.find_element(By.CLASS_NAME, "btE2c3IKaOXZ4VNAb8WQ").text
album = song.find_element(By.CLASS_NAME, "_TH6YAXEzJtzSxhkGSqu").text
# 注意:含空格或复合类名时,By.CLASS_NAME 不支持,必须用 CSS_SELECTOR
artist = song.find_element(By.CSS_SELECTOR, ".Text__TextElement-sc-if376j-0.gYdBJW.encore-text-body-small").text
duration = song.find_element(By.CLASS_NAME, "PAqIqZXvse_3h6sDVxU0").text
print(f"✅ {title} — {artist} | {album} | {duration}")
# ✅ 字典构建与追加均在循环内
new_music = {
'title': title,
'album': album,
'artist': artist,
'duration': duration
}
songs.append(new_music)
except Exception as e:
print(f"⚠️ 提取失败: {e}")
continue
print(f"\n? 共采集 {len(songs)} 首歌曲")
print(songs[:3]) # 打印前3条示例? 关键注意事项:
- 缩进即逻辑:Python 依赖缩进来定义代码块作用域。append() 必须与 for 下的其他语句保持相同缩进层级。
-
定位器选择要严谨:
- By.CLASS_NAME 仅接受单个、不带点号的纯类名(如 "btE2c3IKaOXZ4VNAb8WQ"),传入 .class1.class2 会触发隐式 CSS 转换,属非预期行为,易失效;
- 对多类组合、嵌套结构或含空格的类名,务必使用 By.CSS_SELECTOR(如 ".class1.class2" 或 ".encore-text-body-small")。
- 异常防护不可少:真实网页存在动态加载、元素缺失等风险,建议用 try...except 包裹关键提取逻辑,避免单条失败中断整个流程。
- 资源善后:爬取完成后应调用 driver.quit() 释放浏览器资源(教程中省略,生产环境务必添加)。
通过修正缩进与定位策略,你将获得结构清晰、可直接用于数据分析或存储的完整字典列表——这才是批量网页抓取的正确打开方式。


















