news 2026/9/4 23:05:47

Python实战:从维基百科与Spotify API抓取并分析歌手Billboard榜单数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python实战:从维基百科与Spotify API抓取并分析歌手Billboard榜单数据

这次我们来看一个音乐数据分析项目,它聚焦于解析美国歌手P!nk在Billboard Hot 100榜单上的历史成绩。对于音乐爱好者、数据分析师或内容创作者来说,手动整理一位歌手几十年的打榜数据既繁琐又容易出错。这个项目通过程序化方式,快速、准确地提取了P!nk成绩最好的10首单曲,并提供了排名、峰值位置、在榜周数等关键指标。

本文将带你快速了解如何获取和使用这类音乐榜单数据。核心在于方法而非特定工具:我们将演示从公开数据源(如Billboard官网、维基百科)或音乐API(如Spotify、Last.fm)中提取、清洗和分析数据的基本流程。整个过程不依赖特定闭源软件,重点在于数据获取的逻辑、清洗的步骤以及可视化的呈现。无论你是想复现P!nk的成绩分析,还是将其方法论应用于其他歌手,都能从中获得一套清晰的实操指南。

1. 核心能力速览

能力项说明
项目类型音乐榜单数据抓取与分析脚本/项目
数据来源Billboard官网、维基百科信息框、音乐平台API(如Spotify)等公开数据源
核心功能1. 自动或半自动获取指定歌手的Hot 100打榜记录
2. 按成绩(如最高排名、在榜时长)进行排序与筛选
3. 输出结构化数据(如JSON、CSV)和可视化图表
技术门槛基础Python编程能力,了解HTTP请求和HTML解析(如BeautifulSoup)或API调用
环境依赖Python 3.7+, requests, beautifulsoup4/pandas (用于网页抓取), 或 spotipy (用于Spotify API)
输出形式列表、表格、图表(如条形图、趋势图)
适合场景个人音乐研究、内容创作素材准备、数据分析练习、粉丝向应用开发

2. 适用场景与使用边界

这个数据分析项目主要适合以下几类人群:

  • 音乐内容创作者与博主:需要快速、准确地制作“歌手TOP 10金曲”、“榜单成绩盘点”类视频或图文内容,该项目提供的数据可作为核心素材。
  • 数据分析初学者:这是一个非常好的练手项目,涉及数据爬取、清洗、排序分析和可视化全流程,技术栈常见,资料丰富。
  • 歌迷与音乐爱好者:希望系统性地了解喜爱歌手的商业成绩,用数据佐证其热门单曲。
  • 应用开发者:计划开发音乐类小程序或网站,需要集成歌手成绩数据模块。

使用边界与注意事项:

  1. 数据合规性:必须遵守目标数据源(如Billboard、维基百科)的robots.txt协议和使用条款。避免高频请求,建议添加延时,尊重网站服务器压力。使用官方API(如Spotify API)时,需注册获取密钥并遵守其用量限制。
  2. 数据准确性:自动抓取的数据可能存在格式不一致或历史变更(榜单规则会调整),关键数据(如冠单周数)建议与官方记录进行交叉验证。
  3. 版权与用途:分析产生的结论和可视化图表可用于个人学习或内容创作,但原始榜单数据本身可能受版权保护,直接大规模商用需谨慎。生成的内容中若引用数据,应注明来源。
  4. 技术局限性:完全自动化的抓取可能因网页改版而失效,需要维护更新解析逻辑。本项目方法论重于一个永久不变的“工具包”。

3. 环境准备与前置条件

在开始数据抓取与分析前,你需要准备好编程和数据处理环境。

基础软件环境:

  • 操作系统:Windows 10/11, macOS, 或 Linux 发行版均可。
  • Python环境:推荐安装 Python 3.8 或以上版本。可通过官网或 Anaconda 安装。
  • 包管理工具:使用pip进行Python库的安装。

核心Python库:根据你选择的数据源,安装相应的库。以下是两种主要路径的依赖:

  • 路径一:网页抓取(Billboard/维基百科)

    pip install requests beautifulsoup4 pandas matplotlib
    • requests: 用于发送HTTP请求获取网页HTML。
    • beautifulsoup4: 用于解析HTML,提取所需数据。
    • pandas: 用于数据清洗、排序和保存为CSV。
    • matplotlib: 用于生成成绩可视化图表。
  • 路径二:Spotify API

    pip install spotipy pandas matplotlib
    • spotipy: Spotify官方Python库,用于调用其API。
    • 你还需要在 Spotify Developer Dashboard 创建一个应用,获取CLIENT_IDCLIENT_SECRET

网络条件:需要能够正常访问目标数据源网站(如billboard.com,wikipedia.org)或API端点。

4. 数据获取方法一:从维基百科抓取

维基百科上歌手的页面通常有一个“单曲成绩”的信息框,里面包含了Billboard Hot 100的峰值排名数据,这是一个结构相对清晰的数据源。

步骤 1:分析页面结构访问P!nk的维基百科页面,找到单曲表格。使用浏览器的“检查”功能(F12),查看表格的HTML结构。通常这类表格会有特定的class,如wikitable

步骤 2:编写抓取脚本创建一个Python脚本,例如pink_billboard_scraper.py

import requests from bs4 import BeautifulSoup import pandas as pd def scrape_pink_top_songs(): url = "https://en.wikipedia.org/wiki/Pink_(singer)" headers = {'User-Agent': 'Mozilla/5.0'} # 模拟浏览器访问 try: response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 检查请求是否成功 except requests.RequestException as e: print(f"请求失败: {e}") return None soup = BeautifulSoup(response.content, 'html.parser') # 寻找所有wikitable表格,通常单曲成绩表是其中一个 tables = soup.find_all('table', {'class': 'wikitable'}) target_table = None # 需要人工识别哪个表格包含Billboard Hot 100列。这里假设第二个wikitable是单曲表。 # 实际情况可能需要遍历 tables 并查找包含“Billboard Hot 100”文本的表头。 if len(tables) > 1: target_table = tables[1] # 这是一个假设,需要根据实际页面调整索引 if not target_table: print("未找到目标数据表格。") return None # 将表格转换为pandas DataFrame,它会自动处理表头和多行 df_list = pd.read_html(str(target_table)) if not df_list: return None df = df_list[0] # 清洗数据:重命名列,筛选出包含Hot 100数据的行和列 # 假设DataFrame中有一列名为“US”或“Billboard Hot 100” # 这里需要根据实际抓取到的列名进行调整,这是一个通用化示例 print("抓取到的原始列名:", df.columns.tolist()) # 假设我们找到了Hot 100峰值排名列,并重命名 # 例如,如果列名是 'US',我们将其改为 'Hot 100 Peak' if 'US' in df.columns: df.rename(columns={'US': 'Hot 100 Peak'}, inplace=True) # 筛选出有Hot 100排名的行(非空值),并提取歌曲名、峰值排名 # 注意:原始数据可能包含“X”(未上榜)或“-”等字符,需要清洗 df_valid = df[df['Hot 100 Peak'].notna()].copy() # 将排名转换为数字,忽略非数字字符 df_valid['Peak Position'] = pd.to_numeric(df_valid['Hot 100 Peak'].astype(str).str.extract('(\d+)')[0], errors='coerce') df_valid = df_valid.dropna(subset=['Peak Position']) # 按峰值排名升序排序(排名1最好) df_sorted = df_valid.sort_values(by='Peak Position').head(10) # 假设歌曲名列名为 'Song' top_songs = df_sorted[['Song', 'Peak Position']].reset_index(drop=True) return top_songs if __name__ == '__main__': top_10 = scrape_pink_top_songs() if top_10 is not None: print("P!nk Billboard Hot 100 成绩最好的10首单曲(基于维基百科数据):") print(top_10.to_string(index=False)) # 保存为CSV文件 top_10.to_csv('pink_top10_hot100.csv', index=False, encoding='utf-8-sig') print("\n数据已保存至 'pink_top10_hot100.csv'")

步骤 3:运行与调整运行脚本python pink_billboard_scraper.py。由于维基百科表格结构可能变化,上述代码中的表格索引和列名可能需要你根据实际的print输出进行调整。核心逻辑是:定位表格 -> 转换为DataFrame -> 清洗排名数据 -> 排序取TOP 10。

5. 数据获取方法二:使用Spotify API搜索与排序

如果你希望获取更丰富的歌曲信息(如流行度、发行年份)并结合榜单成绩进行分析,Spotify API是一个很好的选择。但请注意,Spotify API不直接提供Billboard排名,我们需要通过歌曲的流行度(popularity)等指标进行间接排序,或与其他数据源结合。

步骤 1:设置Spotify API凭证

  1. 登录 Spotify Developer Dashboard。
  2. 创建一个新应用,获取CLIENT_IDCLIENT_SECRET
  3. 在应用设置中,将重定向URI设置为http://localhost:8888/callback(用于授权流程)。

步骤 2:编写脚本获取歌手热门歌曲创建一个新脚本pink_spotify_analysis.py

import spotipy from spotipy.oauth2 import SpotifyClientCredentials import pandas as pd # 替换为你自己的凭证 CLIENT_ID = 'your_client_id' CLIENT_SECRET = 'your_client_secret' # 认证 client_credentials_manager = SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) def get_artist_top_tracks(artist_name): # 搜索歌手 results = sp.search(q='artist:' + artist_name, type='artist', limit=1) if not results['artists']['items']: print(f"未找到歌手: {artist_name}") return None artist = results['artists']['items'][0] artist_id = artist['id'] print(f"找到歌手: {artist['name']} (ID: {artist_id})") # 获取该歌手的热门歌曲(根据Spotify内部算法,可能与全球流媒体数据相关) top_tracks = sp.artist_top_tracks(artist_id) tracks_info = [] for track in top_tracks['tracks']: track_data = { 'Song Name': track['name'], 'Album': track['album']['name'], 'Release Date': track['album']['release_date'], 'Popularity': track['popularity'], # Spotify流行度指数 (0-100) 'Track ID': track['id'] } tracks_info.append(track_data) df = pd.DataFrame(tracks_info) # 按流行度降序排序 df_sorted = df.sort_values(by='Popularity', ascending=False).reset_index(drop=True) return df_sorted if __name__ == '__main__': artist = "Pink" top_tracks_df = get_artist_top_tracks(artist) if top_tracks_df is not None: print(f"{artist} 在Spotify上最热门的10首歌曲:") print(top_tracks_df.head(10).to_string(index=False)) top_tracks_df.to_csv(f'{artist.lower()}_spotify_top_tracks.csv', index=False, encoding='utf-8-sig')

步骤 3:数据关联分析单纯使用Spotify流行度不能完全对应Billboard历史成绩。一个更复杂的思路是:

  1. 从可靠来源(如维基百科)获取P!nk所有进入过Hot 100的歌曲名单及其峰值排名。
  2. 使用Spotify API的search功能,根据“歌曲名+歌手”查询每首歌的popularityrelease_date等信息。
  3. 将两个数据源合并,你可以分析“Billboard峰值排名”与“当前Spotify流行度”之间的相关性,或者筛选出两者都表现优异的歌曲。

6. 数据清洗、排序与TOP 10生成

无论从哪种渠道获得原始数据,清洗和排序都是关键步骤。

清洗常见问题:

  1. 非标准排名:数据中可能包含“1 (2)”、“X”、“-”、“—”,分别表示峰值排名、在榜周数、未上榜等。需要用字符串处理(如.str.extract('(\d+)'))提取纯数字。
  2. 多列数据:Billboard数据可能包含“峰值位置”(Peak Pos.)和“在榜周数”(Wks on Chart),需要区分。
  3. 歌曲名重复:混音版、现场版可能与原版并列,需要根据分析目标决定是合并还是区分。

生成TOP 10的逻辑:通常,定义“成绩最好”有以下几种维度,你可以选择其一或综合判断:

  • 峰值排名最高(数字最小):这是最直接的定义。按“Peak Position”升序排序取前10。
  • 在榜周数最长:代表歌曲的持久生命力。按“Weeks on Chart”降序排序取前10。
  • 综合评分:可以设计一个简单公式,例如Score = (101 - Peak Position) * Weeks on Chart,同时考虑排名和持久度,然后按Score降序排序。

假设我们有一个清洗好的DataFramedf,包含Song,Peak,Weeks三列,按峰值排名生成TOP 10的代码如下:

# 按峰值排名排序 (1为最好) df_sorted_by_peak = df.sort_values(by='Peak').head(10).reset_index(drop=True) print("按Billboard Hot 100峰值排名TOP 10:") print(df_sorted_by_peak[['Song', 'Peak', 'Weeks']]) # 按在榜周数排序 df_sorted_by_weeks = df.sort_values(by='Weeks', ascending=False).head(10).reset_index(drop=True) print("\n按在榜周数TOP 10:") print(df_sorted_by_weeks[['Song', 'Peak', 'Weeks']]) # 保存结果 df_sorted_by_peak.to_csv('pink_top10_by_peak.csv', index=False) df_sorted_by_weeks.to_csv('pink_top10_by_weeks.csv', index=False)

7. 结果可视化呈现

数据表格是给机器看的,图表是给人看的。使用matplotlibseaborn库可以将TOP 10数据直观展示。

生成水平条形图(比较峰值排名):

import matplotlib.pyplot as plt import pandas as pd # 假设 df_top10 是之前生成的按峰值排名排序的DataFrame df_top10 = pd.read_csv('pink_top10_by_peak.csv') plt.figure(figsize=(10, 6)) # 绘制水平条形图,让歌曲名在y轴显示更清晰 bars = plt.barh(df_top10['Song'], df_top10['Peak'], color='skyblue') plt.xlabel('Billboard Hot 100 Peak Position (数字越小越好)') plt.title('P!nk: Top 10 Songs by Billboard Hot 100 Peak Position') plt.gca().invert_yaxis() # 让排名最好的(数字最小)显示在最上面 # 在条形末端添加排名数字 for bar, peak in zip(bars, df_top10['Peak']): plt.text(bar.get_width() + 0.3, bar.get_y() + bar.get_height()/2, f'{int(peak)}', va='center') plt.tight_layout() plt.savefig('pink_top10_peak_chart.png', dpi=300) plt.show()

生成组合图表(排名与周数):

fig, ax1 = plt.subplots(figsize=(12, 7)) songs = df_top10['Song'] peak = df_top10['Peak'] weeks = df_top10['Weeks'] x = range(len(songs)) ax1.bar(x, peak, color='lightcoral', label='Peak Position', alpha=0.7) ax1.set_xlabel('Song') ax1.set_ylabel('Peak Position', color='darkred') ax1.set_xticks(x) ax1.set_xticklabels(songs, rotation=45, ha='right') ax1.tick_params(axis='y', labelcolor='darkred') ax1.invert_yaxis() # 排名轴反向,让顶部位置更好 ax2 = ax1.twinx() ax2.plot(x, weeks, color='steelblue', marker='o', linewidth=2, label='Weeks on Chart') ax2.set_ylabel('Weeks on Chart', color='steelblue') ax2.tick_params(axis='y', labelcolor='steelblue') fig.suptitle('P!nk Top 10 Songs: Peak Position vs. Weeks on Chart') fig.legend(loc='upper left', bbox_to_anchor=(0.1, 0.9)) fig.tight_layout() plt.savefig('pink_top10_peak_vs_weeks.png', dpi=300) plt.show()

8. 常见问题与排查方法

在数据抓取和分析过程中,你可能会遇到以下问题:

问题现象可能原因排查方式解决方案
运行脚本后无输出或报错ConnectionError网络问题,或目标网站屏蔽了请求检查网络连接,尝试在浏览器中直接访问目标URL。打印response.status_code添加headers模拟浏览器,在请求间增加time.sleep()延时,或使用代理。
成功获取网页但找不到表格数据网页结构已更新,或表格的class/id已改变使用print(soup.prettify())或浏览器检查工具,重新分析目标数据所在的HTML标签结构。更新脚本中的选择器,可能需要使用更灵活的查找方式,如find_all('table')后通过表格内容文本过滤。
数据列名混乱或包含多余字符原始表格结构复杂,存在合并单元格或注释打印df.columnsdf.head()查看原始数据形态。进行数据清洗,如重命名列、删除空行、使用df.iloc选择特定列。
Spotify API 返回401403错误客户端凭证无效、过期或权限不足检查CLIENT_IDCLIENT_SECRET是否正确,是否在Dashboard中设置了重定向URI。重新生成密钥,确保认证流程正确。对于需要用户授权的操作,需使用SpotifyOAuth而非SpotifyClientCredentials
排名数据无法转换为数字原始数据中包含非数字字符(如“X”,“(1)”)打印出有问题的具体数据值。使用字符串方法(如.str.extract('(\d+)'))先提取数字部分,再用pd.to_numeric(..., errors='coerce')转换。
生成的图表中文乱码系统缺少中文字体或matplotlib默认字体不支持中文检查图表标题、标签是否包含中文。在脚本开头添加字体设置:plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'](Windows) 或['Arial Unicode MS'](macOS)。

9. 最佳实践与使用建议

为了更高效、稳定地运行此类数据分析项目,建议遵循以下实践:

  1. 数据源备份与版本控制:将清洗后的干净数据(CSV/JSON)保存下来。对抓取脚本进行版本控制(如使用Git),当网站结构变化时,可以回退和对比。
  2. 尊重数据源:在抓取公开数据时,务必遵守robots.txt规则,设置合理的请求间隔(例如,在循环请求间添加time.sleep(2)),避免对服务器造成压力。
  3. 异常处理与日志记录:在脚本中加入try...except块来捕获网络超时、解析错误等异常,并记录到日志文件,便于后期排查。
  4. 模块化设计:将数据抓取、清洗、分析、可视化写成独立的函数或模块,提高代码可读性和复用性。例如,可以创建一个billboard_scraper.py模块,供其他分析项目调用。
  5. 结果复核:自动化抓取的结果,尤其是TOP 10这种结论性数据,务必与一两个已知的权威来源(如Billboard官网历史榜单)进行手动核对,确保关键名次无误。
  6. 扩展性思考:本项目的方法论可以轻松迁移。只需修改脚本中的歌手姓名、URL或搜索关键词,即可用于分析Taylor Swift、The Beatles等任何歌手的榜单成绩。你还可以尝试整合多个数据源,比如将Billboard排名与Spotify流媒体数据、音乐评分网站Metacritic的乐评分相结合,进行多维度的音乐作品分析。

10. 总结与下一步

通过这个项目,我们完成了一次从数据获取到可视化呈现的完整数据分析流水线。核心收获不在于P!nk具体的TOP 10歌单是什么(这个结果可能因数据源和排序标准而异),而在于掌握了一套可复用的方法:如何从互联网上定位并提取结构化数据,如何清洗杂乱的真实世界数据,如何根据业务逻辑(定义“成绩最好”)进行排序筛选,以及如何将结果用图表清晰表达。

最值得尝试的下一步是扩展分析维度。例如,除了Hot 100,还可以抓取Billboard 200专辑榜数据;除了峰值排名,可以分析歌曲的“进榜-爬升-峰值-衰退”完整曲线;除了P!nk,可以构建一个对比工具,输入两位歌手,自动输出他们在榜单成绩上的对比报告。

最容易踩的坑是对网页结构变化的低估。公开网站的改版可能会让你的抓取脚本一夜失效。因此,核心数据(如最终的TOP 10列表)建议定期备份,并将解析逻辑写得相对健壮,比如不依赖绝对的位置索引,而是寻找包含特定关键词的表格标题行。

建议将本次实践的代码保存为模板,下次当你需要分析其他歌手、其他榜单(如UK Singles Chart)甚至其他领域(如电影票房、应用商店排名)的数据时,只需更换目标URL和解析规则,便可快速启动。数据驱动的洞察力,始于一次成功的抓取。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 16:56:42

TPU-GF打印全解析:玻璃纤维增强TPU的调参技巧与工程应用

做机械结构件、工装或者机器人相关毕业设计的朋友,应该都有过这种纠结:想要柔性缓冲,想到 TPU,但纯 TPU 往往偏软、偏粘、受热容易变形;想要高刚性和耐温,想到碳纤尼龙或者 PC,但这类材料韧性又…

作者头像 李华
网站建设 2026/9/5 0:59:25

计算机芯片分类全解析:从CPU到NPU,看懂硬件选型

1. 先搞清楚“详解芯片”到底要解决什么问题如果你刚接触硬件,或者想快速理解不同芯片的用途和区别,那这篇文章就是为你准备的。很多人一听到“计算机芯片”就觉得是CPU,或者觉得太复杂不想看。其实,芯片的世界很清晰,…

作者头像 李华
网站建设 2026/9/4 20:49:07

2026年IRC技术生态发展:Node.js机器人、WebSocket网关与React Native客户端实践

这次我们来看一个关于 IRC 技术生态在 2026 年上半年的发展综述。IRC 作为历史悠久的实时通信协议,其核心价值在于开放、去中心化和低延迟。进入 2026 年,IRC 并未被现代即时通讯工具完全取代,反而在开发者社区、开源项目协作、机器人自动化以…

作者头像 李华
网站建设 2026/9/3 9:34:20

AngusKit:2026 年私有化研发套件怎么选

采购会上,我们组对着六张功能表逐项打勾。Git 一套、制品一套、扫描若干、测试再拼两个工具,Agent 再开一个云账号。账面上每一项都不贵,看起来什么都齐了。但真到了发版窗口里,评审截图、扫描 PDF、手点记录还是对不齐。别先数工…

作者头像 李华
网站建设 2026/9/3 9:36:08

Android后台保活全攻略:从进程优先级到厂商ROM的实战指南

简介:一份面向Android开发者的后台服务保活资料包,围绕如何降低进程被系统回收风险、如何在进程被杀后重新拉活等难题,整理了前台服务、绑定服务、JobScheduler/WorkManager、AlarmManager、广播拉活等多种实现思路。包内KeepLiveDemo工程包含…

作者头像 李华
网站建设 2026/9/4 17:58:50

AI Agent接管70% PR背后:Uber的成本控制与工程实践

最近 Uber 的一个实践数据在技术圈讨论度很高:70% 的代码 PR 由 AI Agent 接管,同时 AI 相关账单保持零增长。这两个数字放在一起,才是真正值得研究的现象。很多人习惯把注意力放在 70% 上,觉得这是 AI 写代码能力的证明&#xff…

作者头像 李华