使用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()
三、关键优化点说明
- 精准定位滚动容器:直接找到承载歌曲列表的滚动容器,而不是操作整个页面body,确保滚动动作能触发歌曲加载。
- 动态判断滚动结束:通过对比滚动容器的高度变化,自动停止滚动,不管播放列表有多少首歌都能加载完全。
- 使用稳定的元素定位:用
data-testid="track-name"这种平台预留的测试属性定位歌曲,避免动态class名带来的定位失效问题。
备注:内容来源于stack exchange,提问作者BouckleyBoy
相关产品推荐
相关产品推荐

