You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Selenium和BeautifulSoup爬取Spotify播放列表时无法滚动加载更多歌曲的问题排查

使用Selenium和BeautifulSoup爬取Spotify播放列表时无法滚动加载更多歌曲的问题排查

我来帮你排查这个问题!你遇到的情况在爬取动态渲染的音乐平台页面时很常见,Spotify的页面结构和滚动逻辑有它自己的特点,咱们一步步分析原因和解决办法:


一、核心问题分析

1. 滚动目标元素错误

Spotify的播放列表歌曲列表是放在独立的滚动容器里的,不是整个页面的body元素。你现在操作body发送PAGE_DOWN,可能根本没触发歌曲列表区域的滚动,自然加载不出后续的歌曲。

2. 固定次数滚动不够灵活

你用了固定30次的循环滚动,但不同播放列表的歌曲数量差异很大,而且Spotify每次滚动加载的歌曲数也不是固定值,固定次数要么可能不足,要么会做无用功;另外固定的sleep(1)时间也可能不够,网络慢的时候新内容还没加载完成就继续滚动了。

3. 动态class名不可靠

你用的btE2c3IKaOXZ4VNAb8WQ这个class名是Spotify动态生成的,每次刷新页面都可能变化,这会导致你只能抓到初始加载的30首歌,后续加载的歌曲要么因为class名变化找不到,要么直接定位失败。


二、修复后的代码示例

下面是调整后的代码,针对上述问题做了优化:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import csv
from bs4 import BeautifulSoup

# 初始化浏览器驱动
driver = webdriver.Chrome()
driver.get("SPOTIFY PLAYLIST URL")
time.sleep(3)  # 先等待页面基础内容加载完成

# 定位Spotify的歌曲列表滚动容器(这个是实际承载歌曲的可滚动区域)
# 用XPATH定位带有role="grid"且标注为歌曲列表的容器,比动态class稳定
scroll_container = driver.find_element(By.XPATH, '//div[@role="grid" and contains(@aria-label, "歌曲")]')

# 循环滚动到底部,直到没有新内容加载
last_height = driver.execute_script("return arguments[0].scrollHeight", scroll_container)
while True:
    # 用JS直接滚动到容器底部,比模拟按键更可靠
    driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scroll_container)
    time.sleep(2)  # 等待新内容加载,可根据网络情况调整时长
    new_height = driver.execute_script("return arguments[0].scrollHeight", scroll_container)
    if new_height == last_height:
        # 容器高度不再变化,说明没有更多歌曲了
        break
    last_height = new_height

# 解析页面内容
soup = BeautifulSoup(driver.page_source, 'html.parser')

# 用稳定的属性定位歌曲(Spotify的歌曲名元素带有data-testid="track-name"属性)
songs = soup.find_all("div", attrs={"data-testid": "track-name"})

# 检查抓取结果
if not songs:
    print("未找到歌曲,请检查元素属性或页面结构是否有变化。")
else:
    print(f"共找到 {len(songs)} 首歌曲。")

# 写入CSV文件
with open('songs.csv', 'w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['SONGS'])
    for song in songs:
        song_text = song.get_text(strip=True)
        print(song_text)
        writer.writerow([song_text])

# 关闭浏览器
driver.quit()

三、关键优化点说明

  1. 精准定位滚动容器:直接找到承载歌曲列表的滚动容器,而不是操作整个页面body,确保滚动动作能触发歌曲加载。
  2. 动态判断滚动结束:通过对比滚动容器的高度变化,自动停止滚动,不管播放列表有多少首歌都能加载完全。
  3. 使用稳定的元素定位:用data-testid="track-name"这种平台预留的测试属性定位歌曲,避免动态class名带来的定位失效问题。

备注:内容来源于stack exchange,提问作者BouckleyBoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:34:32