关于 spotifyscraper
spotifyscraper 是用于获取 Spotify 公开元数据的 Python 库和 MCP 服务,也可读取歌词与播客文字稿。公开数据无需 API 密钥;歌词和文字稿需要可选的 Spotify 账户 Cookie。
主要功能
- 01读取曲目、专辑、艺人、播放列表和播客
- 02跨实体类型搜索
- 03通过 Cookie 获取歌词和播客文字稿
- 04提供同步与异步客户端
- 05提供可选命令行工具
适用场景
- 01为应用获取 Spotify 元数据
- 02搜索 Spotify 公开实体
- 03获取带时间信息的歌词或播客文字稿
- 04通过 MCP 向 AI Agent 提供 Spotify 数据
MCP 相关
可选的 spotifyscraper-mcp 服务向 MCP 客户端开放 SpotifyScraper 能力,包括批量工具和曲目视觉信息工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
SpotifyScraper
无需官方 API 或 API 密钥,即可提取公开的 Spotify 数据——曲目、专辑、艺人、播放列表和播客。
🎧 在浏览器中在线体验 → ——粘贴任意 Spotify 链接,查看 SpotifyScraper 如何提取类型化数据、封面图和试听片段,以及实现这一功能的完整 Python 代码。(了解构建过程。)
SpotifyScraper 会从 Spotify 自己的公开嵌入页面获取匿名令牌,并读取网页播放器使用的相同 JSON 端点,返回类型化的不可变模型。v3 是从头重写的版本,专注于可靠性和简洁、现代的 API。公开数据无需登录;可选的登录后功能(歌词、播客文字稿和账户信息)只需添加你自己的 Spotify sp_dc Cookie——无需密码或 API 密钥。
SpotifyScraper 与官方 API(spotipy)
spotipy 封装了 Spotify 的官方 Web API——如果你需要向用户的帐户写入数据,或读取私有数据/资料库数据,这是合适的选择。SpotifyScraper 读取 Web 播放器已公开的数据,因此无需任何设置。
| SpotifyScraper | spotipy(官方 API) | |
|---|---|---|
| API 密钥/应用注册 | ❌ 不需要 | ✅ 必需 |
| OAuth 流程 | ❌ 不需要 | ✅ 大多数数据都需要 |
| 速率限制配额/计费 | 无 | Spotify 配额 |
| 同步和异步 | ✅ | 仅同步 |
| 完全类型化的不可变模型 | ✅ | 部分支持 |
| 歌词与播客转录文本 | ✅(cookie) | ❌ |
| 面向 Claude/大模型 Agent 的 MCP 服务 | ✅ | ❌ |
| 写入/播放/私有数据 | ❌(仅限公开数据,只读) | ✅ |
需要经过身份验证的写入操作和符合市场区域的数据时,请使用 spotipy;需要快速、免密钥地访问公开元数据、歌词和试听片段,以及可直接使用的 MCP 服务来连接 AI Agent 时,请使用 SpotifyScraper。
受到官方 API 弃用的影响? 自 2024 年 11 月起,Spotify 的
audio-features、recommendations和related-artists端点已对新应用返回403。SpotifyScraper 仍可在无需 API 密钥的情况下返回相关艺人和推荐内容。(它无法恢复audio-features——Spotify 已从所有工具中彻底移除了这些数据。)
安装
pip install spotifyscraper # core (only depends on httpx)
pip install "spotifyscraper[media]" # + cover/preview embedding (mutagen)
pip install "spotifyscraper[browser]" # + Playwright browser fallback & login
pip install "spotifyscraper[cli]" # + the spotifyscraper command-line tool
pip install "spotifyscraper[keyring]" # + store the login cookie in the OS keyring
pip install "spotifyscraper[mcp]" # + the spotifyscraper-mcp MCP server for LLM hosts
pip install "spotifyscraper[all]" # everything
Python 3.10+。
快速入门
from spotify_scraper import SpotifyClient
with SpotifyClient() as client:
track = client.get_track("https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC")
print(track.name, "—", track.artists[0].name)
print(track.duration_ms, "ms |", track.preview_url)
print(track.to_dict()) # JSON-safe dict, if you prefer dicts
每种实体都有专属方法:get_track、get_album、get_artist、get_playlist、get_episode、get_show——每个方法都接受 URL、URI 或纯 ID。
异步
import asyncio
from spotify_scraper import AsyncSpotifyClient
async def main():
async with AsyncSpotifyClient() as client:
track, album = await asyncio.gather(
client.get_track("4uLU6hMCjMI75M1A2tKUQC"),
client.get_album("6N9PS4QXF1D0OWPk0Sxtb4"),
)
print(track.name, "|", album.name)
asyncio.run(main())
下载封面和试听片段
from spotify_scraper import SpotifyClient
with SpotifyClient() as client:
track = client.get_track("4uLU6hMCjMI75M1A2tKUQC")
client.download_cover(track, dest="covers/")
client.download_preview(track, dest="previews/", embed_cover=True) # needs [media]
本地化显示名称
传入 locale——一个 BCP-47 语言标签:可以是单独的语言子标签("de"、"ja"),也可以是语言-地区标签("ja-JP")——以本地化显示名称所用的语言。可以为客户端设置此项,也可以在每次调用时覆盖:
with SpotifyClient(locale="ja-JP") as client: # default for every call
track = client.get_track("4uLU6hMCjMI75M1A2tKUQC")
other = client.get_track("4uLU6hMCjMI75M1A2tKUQC", locale="de-DE") # per-call wins
此值会作为 Accept-Language 标头发送,只会改变名称的拼写。它不是国家/市场代码——单独的 "US" 作为语言没有意义,会被忽略——也不会筛选地区可用性或改变试听 URL:匿名访问 Spotify 时会根据请求 IP 确定国家/地区,其 pathfinder 会静默忽略 market 变量。真正的市场/可用性筛选需要经过身份验证的 Web API,本库并未实现此功能;如需获取特定地区的结果,请将客户端的 proxy 指向目标地区。请参阅本地化指南。
功能
- 所有核心实体 + 播客 — 曲目、专辑、艺人、播放列表、节目、单集。
- 搜索所有实体类型,并返回类型化的
SearchResults。 - 榜单与发现 — 编辑精选榜单、相关艺人、完整的分页唱片目录和专辑推荐。
- 封面颜色与 Canvas — 提取艺术作品的主题配色,并下载曲目的循环 Canvas 视频。
- 署名与演唱会 — 演奏者/词曲作者/制作人,以及艺人即将举行的现场演出。
- 公开用户资料 —
get_user()(姓名、关注者数量、公开播放列表)。 - MCP 服务 — 通过
spotifyscraper-mcp向 Claude/大模型开放所有功能(批量工具 + 一次调用即可完成的get_track_visuals);也提供 ghcr.io 上的容器版本。 - 本地化显示名称 — 传入 BCP-47 语言标签(
locale)以设置名称的语言。 - 歌词与播客文字稿 — 通过 Cookie 认证、与时间同步,一个令牌即可用于两者。
- 浏览器辅助登录 + 会话持久化 — 登录一次,之后即可无头运行(不存储密码)。
- 感知账户状态 —
get_account()/is_premium(),以及无需 Cookie 的session_info()。 - 批量辅助函数 — 复数形式的
get_*s([...]),提供可安全处理部分失败的结果,并管理并发。 - 同步与异步客户端,共用一个无 I/O 核心。
- 类型化的冻结模型,支持 JSON 安全的
to_dict()/from_dict()。 - 双层弹性机制 — 使用 Spotify 的 GraphQL API,并在必要时自动回退到嵌入页面。
- 仅依赖一个核心依赖项(
httpx);媒体和浏览器支持为可选扩展。 - 可选响应缓存 — 按需启用、持久化且令牌安全(仅缓存不含令牌的 pathfinder GET 请求)。
- 内置防封禁机制 — 按主机限流、退避重试、轮换 UA、代理。
- 通过 Playwright 提供浏览器回退,以便在需要真实浏览器时使用。
命令行
安装 cli 扩展后,即可使用 spotifyscraper 命令:
spotifyscraper track 4uLU6hMCjMI75M1A2tKUQC # entity metadata as JSON
spotifyscraper playlist <id> --max-tracks 50 --pretty
spotifyscraper download preview <id> -o ./previews --embed-cover
每条命令都会输出 JSON,因此可以与 jq 等工具组合使用。请参阅
CLI 指南。
批量辅助函数
每个 getter 都有对应的复数形式(get_tracks、get_albums……),可获取多个输入,并为每个输入返回一个 BatchItem——索引一一对应;某个输入无效也不会中止其余请求:
items = client.get_tracks(["4uLU6hMCjMI75M1A2tKUQC", "bad-id"])
ok = [i.result for i in items if i.ok]
failed = {i.value: i.error for i in items if not i.ok}
异步客户端会并发运行这些请求,并受 max_concurrency 限制(默认为
5)。请参阅批量处理指南。
响应缓存
对于重复查询,可按需启用持久缓存。缓存只存储不含令牌的 pathfinder 响应——绝不缓存包含匿名令牌的嵌入页面——因此不会有任何凭据写入磁盘:
from spotify_scraper import SpotifyClient, CacheConfig, FileCache
with SpotifyClient(cache=CacheConfig(store=FileCache())) as client:
client.get_track("4uLU6hMCjMI75M1A2tKUQC") # first call hits the network
client.get_track("4uLU6hMCjMI75M1A2tKUQC") # served from the cache
默认 TTL 为 24h;FileCache 仅依赖标准库,后端可插拔。
请参阅缓存指南。
搜索
search() 会针对所有实体类型运行一次匿名聚合查询,并返回类型化的 SearchResults:
from spotify_scraper import SpotifyClient
with SpotifyClient() as client:
results = client.search("daft punk", types=("track", "artist"), limit=5)
print(results.total, "track matches")
for track in results.tracks:
print(track.name, "—", track.artists[0].name)
搜索结果内容较少(传入 id 调用 get_album()/get_show() 可获取完整实体);
total 是匹配曲目的数量。请参阅
搜索指南。
歌词与文字稿
歌词和播客文字稿需要 Spotify 账户 Cookie(sp_dc);该库会为你处理令牌握手,一个 Cookie 即可用于两者:
from spotify_scraper import SpotifyClient
with SpotifyClient(cookies="cookies.txt") as client: # or cookies={"sp_dc": "..."}
lyrics = client.get_lyrics("4uLU6hMCjMI75M1A2tKUQC")
for line in lyrics.lines:
print(line.start_ms, line.text)
transcript = client.get_transcript("07gKzPFkbvGF0cHoeG7ARS") # a podcast episode
for line in transcript.lines:
print(line.start_ms, line.text)
你的 Cookie 只会发送给 Spotify,且绝不会被记录。没有文字稿的单集会引发 NotFoundError。请参阅
歌词与 Cookie 指南。
浏览器辅助登录
不想手动复制 Cookie?login() 会打开真实浏览器,你只需登录一次,捕获的 sp_dc 就会被保存(不会收集或存储密码)。之后的运行会以无头模式重新连接,非常适合服务器:
from spotify_scraper import SpotifyClient
with SpotifyClient() as client:
client.login() # reuse a valid session, else open a browser
print(client.get_lyrics("4uLU6hMCjMI75M1A2tKUQC").sync_type)
# A later, headless run — no browser needed:
with SpotifyClient.from_saved_session() as client:
account = client.get_account() # who am I?
print(account.product, account.country, client.is_premium())
transcript = client.get_transcript("07gKzPFkbvGF0cHoeG7ARS")
默认情况下,login() 会复用有效的已保存会话(只有第一次需要使用浏览器);from_saved_session() 则完全不需要 browser extra。Cookie 会存储在仅所有者可访问的文件中,或者存入操作系统密钥环(使用 store="keyring" 和 keyring extra)。get_account()/is_premium() 会报告已登录的账户,SpotifyClient.session_info() 则可在不暴露 Cookie 的情况下检查已保存的会话。请参阅已认证会话指南。
路线图
已发布
| 版本 | 范围 |
|---|---|
| 3.0 | 库:所有实体、分页、媒体下载、浏览器回退、文档 |
| 3.1 | 命令行界面 |
| 3.2 | Cookie 身份验证歌词 |
| 3.3 | Cookie 身份验证播客文字稿(get_transcript);浏览器辅助登录、会话持久化与账户感知(get_account/is_premium) |
| 3.4 | 所有实体类型的搜索(search())· 显示语言本地化(locale) |
| 3.5 | 可选响应缓存(cache=CacheConfig(...))· 支持受管理并发的批处理辅助工具 |
| 3.6 | 视觉与发现:封面颜色、Canvas 视频、排行榜、相关艺人、分页唱片目录、推荐、公开个人资料、曲目鸣谢、演唱会 · 一流的 MCP 服务 + 容器镜像 |
| 3.7 | MCP 批处理工具(get_tracks/get_albums/…)· 为视觉前端提供便捷工具 get_track_visuals |
| 3.8 | 维护:依赖项、工具链与 CI 现代化(所有 Actions 均使用当前主版本并固定 SHA)· 文档与 PyPI 反向链接 |
| 3.9 | 发布至官方 MCP 注册表(并支持 Glama/mcp.so/PulseMCP/Smithery 发现)· “vs spotipy” 对比 · 一次性、可选择退出的 CLI 点星提示 |
接下来 — 未来计划会记录在 GitHub 里程碑和 问题中 — 👍 或就你最关注的事项发表意见。计划范围可能会有变更。
可靠性与维护
此库依赖 Spotify 自身的公共端点,因此 Spotify 更改端点时可能会导致其失效。为确保可靠性:
- 我们每天都会运行一次金丝雀测试,针对 Spotify 运行实时测试套件。端点发生变化时,它会自动创建
spotify-breakage问题(并在恢复后关闭),让回归问题在影响到你之前就能显现。 - 在维护者审核下,我们会借助 Claude Code(Anthropic 的编码 Agent)迅速分类并修复故障——这套由 Agent 辅助的工作流也推动着本项目持续发展。持久化查询哈希集中在一个文件(
api/pathfinder.py)中,因此 Spotify 轮换哈希时只需修改一行。 - 每项更改都要通过
ruff+mypy --strict+ 隔离测试套件(覆盖率至少 85%),并在 Linux、macOS 和 Windows 上使用 Python 3.10–3.13 进行测试。
如果你遇到了问题,请提交问题——监控通常已经发现了这些问题。
文档
完整文档、指南和 API 参考:https://spotifyscraper.readthedocs.io
MCP 服务也提供容器版本:
docker run -p 8000:8000 ghcr.io/aliakhtari78/spotifyscraper(设置 SPOTIFY_SP_DC
以启用需要身份验证的工具)。
法律声明
SpotifyScraper 是一个非官方的独立项目,与 Spotify 无关联。它读取公开可用的数据以及 Spotify 发布的约 30 秒试听片段;不会下载完整曲目,也不会规避 DRM。请将其用于教育和个人用途,并遵守 Spotify 的服务条款。请参阅法律声明。
贡献
欢迎贡献——请参阅 CONTRIBUTING.md。本项目采用基于规范优先的方式开发,并使用 OpenSpec;规范位于 openspec/。
Star 历史
如果 SpotifyScraper 帮你省去了官方 API 的 OAuth 流程,点个 ⭐ 能帮助其他开发者发现它,也能告诉我应该继续开发哪些功能。
许可证
MIT © Ali Akhtari — 全栈 AI 工程师(aliakhtari.com)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。