如何整合 Spotify 和 Genius API,使用 Python 轻松抓取歌词
这篇文章最初发表在我的个人博客上。
大家好!
对于这篇文章,我决定谈论我去年编写的一个 Python 脚本,现在我仍然经常使用它。
这种情况很常见:你突然有了一个想法,兴奋不已,却又不知道它是否能如愿以偿。我一开始只是对 Python 有一些了解,并且知道要用哪些 API 来实现这个想法。
我的目标是实现一个脚本,用来获取 Spotify 上当前正在播放的歌曲的歌词。所以,一开始我知道我需要一个接口,让我可以将这个脚本连接到我电脑上运行的 Spotify 服务。另外,由于我是Genius.com的忠实用户,我知道他们有一个庞大的公共 API 可以提供帮助。
对于Spotify的老用户来说,你们可能还记得Spotify曾经在桌面应用中显示歌词的功能吧?真是美好的旧时光。我仍然不明白为什么这项功能被移除了,但现在我们只剩下这个Behind the Lyrics
功能了,它能显示一些
无用我们正在听的歌曲的信息和歌词小片段(似乎仅在移动设备上可用)。
从这里开始,我将按照脚本的实现顺序进行分解。如果您想在继续之前查看完整脚本,可以访问Github 上的这个仓库。那里也会提供运行脚本的说明,但请记住,我也会在本篇文章中指导您完成整个过程 :)
连接到 Spotify
这是我完全不知道该怎么做的事情之一,所以我不得不谷歌搜索才搞定。还好,jooon在 Stackoverflow 上提供的这个答案帮我节省了很多时间,所以,先生,我向你致敬。
基本上,由于我是 Linux 用户,我使用的 Spotify 客户端会自动创建一个名为 MPRIS(媒体播放器远程接口规范)的 D-Bus 接口。
从D-Bus规范页面来看,D-Bus API 通常用于实现一个将被多个客户端程序使用的服务。这种消息系统专为两种特定情况而设计:同一桌面会话中的桌面应用程序之间的通信,以及桌面会话与操作系统(包括任何系统进程)之间的通信(这是我们的情况)。
D-Bus 系统包含多个层级,其中一层由包装器库构成,这正是我们在此使用的工具。为了使 Python 脚本能够与 Spotify 桌面应用程序通信,我们将使用dbus-python包装器库(技术上称为 )。在系统中安装该库后,您可以使用该模块创建一个用于与 Spotify 通信的 dbus-python 模块binding
。libdbus
dbus
SessionBus
如果您使用的是 Ubuntu,并且由于某种原因您没有安装dbus-python
,您可以通过运行以下命令来安装它:apt-get install python-dbus
import dbus
def get_current_song_info():
# kudos to jooon from this stackoverflow question http://stackoverflow.com/a/33923095
session_bus = dbus.SessionBus()
spotify_bus = session_bus.get_object('org.mpris.MediaPlayer2.spotify',
'/org/mpris/MediaPlayer2')
spotify_properties = dbus.Interface(spotify_bus,
'org.freedesktop.DBus.Properties')
metadata = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'Metadata')
return {'artist': metadata['xesam:artist'][0], 'title': metadata['xesam:title']}
在上面的代码中,我们简单地创建了一个SessionBus
实例并使用它来创建一个Interface
Spotify 应用程序。
通过该连接,我们可以提取该会话的元数据,这将为我们提供大量有关当前 Spotify 会话的信息,包括艺术家姓名和当前正在播放的歌曲,这正是我们所需要的。请注意,此方法返回一个包含两个键的字典,artist
分别是 和title
。
连接到 Genius API
由于我们已经有了想要搜索的艺术家和歌曲的名称,我们可以继续向 Genius API 发出请求。
为此,我们需要一个访问令牌,可以通过创建 Genius API 客户端来获取。首先,我们需要注册一个 Genius 帐户(如果您已经有 Genius 帐户,请登录)。之后,您可以前往 Genius API 文档页面来管理您的客户端。创建新客户端的过程非常简单,之后,您最终将获得访问令牌。
一旦您有了访问令牌,我们就可以实施下一个方法。
import requests
def request_song_info(song_title, artist_name):
base_url = 'https://api.genius.com'
headers = {'Authorization': 'Bearer ' + 'INSERT YOUR TOKEN HERE'}
search_url = base_url + '/search'
data = {'q': song_title + ' ' + artist_name}
response = requests.get(search_url, data=data, headers=headers)
return response
此方法接收我们从 Spotify 会话中提取的歌曲和艺术家姓名,并向 Genius API 发送请求。请注意,我们使用了request HTTP 库来发送 GET 请求。
提取歌词
如果一切正常,您现在将拥有一个响应对象,其中包含有关在 API 中找到的所有匹配项的大量信息。
由于我们从请求中获得的对象形状,我们将必须遍历hits
该对象中的键并使用变量寻找完全匹配artist_name
。
# Search for matches in the request response
response = request_song_info(song_title, artist_name)
json = response.json()
remote_song_info = None
for hit in json['response']['hits']:
if artist_name.lower() in hit['result']['primary_artist']['name'].lower():
remote_song_info = hit
break
如果我们在该对象中成功匹配,则意味着我们寻找的歌曲在 API 中可用,并且现在可以在remote_song_info
变量中使用。
即使我们掌握了某首歌的所有信息,你猜怎么着,我们竟然没有歌词!没错,Genius API(就此脚本的实现日期而言)并没有直接提供歌曲的歌词。而且,也没有搜索歌词的端点。
为了避免这种情况,我们实际上必须抓取这首歌所在的网页。在 中remote_song_info
,您将获得该歌曲的 URL。
# Extract lyrics from URL if the song was found
if remote_song_info:
song_url = remote_song_info['result']['url']
从这里我们基本上必须让我们的脚本访问该页面并为我们抓取歌词。
from bs4 import BeautifulSoup
def scrap_song_url(url):
page = requests.get(url)
html = BeautifulSoup(page.text, 'html.parser')
lyrics = html.find('div', class_='lyrics').get_text()
return lyrics
此方法接收歌曲 URL,并使用Beautiful Soup库以更简单的方式从 HTML 文件中提取数据。
在实现此方法的过程中,我必须分析返回的 HTML 结构,以便弄清楚如何使用它来提取代表歌词的文本。我最终使用了div
包含类的lyrics
,该类包含所有歌词。希望他们永远不要更改它的标记 :)
我们终于把歌词打印到控制台了。很酷的是,在抓取过程中,歌词中的每一行都会自动添加一个换行符(\n
)。这样,我们在终端中就能看到一个美观的结构了。
如何使用 Github 仓库
本帖中提到的所有方法都可以在此存储库中找到。
为了在本地使用它,您只需克隆存储库,将访问令牌添加到token.txt
文件,然后在存储库文件夹中运行以下命令即可获取歌曲的歌词。记得打开 Spotify 播放一下 :)
python get-lyric.py
该脚本应该适用于 Python 2.7 和 Python 3。但是,您应该检查您正在使用的版本以及用于安装依赖项的版本。
从存储库中,您可以获得一些额外的功能,例如:
- 自动在文件中提供歌词
lyric-view.txt
。 - 通过传递艺术家和歌曲名称来搜索任何歌曲(此模式不与 Spotify 交互,因此无需打开它)。查看README.md。
我要注意的最后一件事是,如果您在文件中为该命令创建别名,则不必总是在文件夹内获取歌词.bashrc
。
对我来说,我必须将此行添加到我的.bashrc
文件中。
alias lyric="python ~/repos/lyrics-crawler/get-lyric.py"
而且,我必须在脚本代码中对token.txt
和文件使用绝对路径。lyric-view.txt
有了它,我可以简单地从任何目录运行命令lyric
并获取通过 Spotify 播放的歌曲的歌词。
希望这篇文章对你有帮助。如果你对这个仓库有任何建议或功能,请告诉我,或者提交 Pull Request,我将不胜感激 :)
谢谢!
鏂囩珷鏉yu簮锛�https://dev.to/willamesoares/how-to-integrate-spotify-and-genius-api-to-easily-crawl-song-lyrics-with-python-4o62