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

发布时间:2026/9/2 7:16:23
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金曲”、“榜单成绩盘点”类视频或图文内容该项目提供的数据可作为核心素材。数据分析初学者这是一个非常好的练手项目涉及数据爬取、清洗、排序分析和可视化全流程技术栈常见资料丰富。歌迷与音乐爱好者希望系统性地了解喜爱歌手的商业成绩用数据佐证其热门单曲。应用开发者计划开发音乐类小程序或网站需要集成歌手成绩数据模块。使用边界与注意事项数据合规性必须遵守目标数据源如Billboard、维基百科的robots.txt协议和使用条款。避免高频请求建议添加延时尊重网站服务器压力。使用官方API如Spotify API时需注册获取密钥并遵守其用量限制。数据准确性自动抓取的数据可能存在格式不一致或历史变更榜单规则会调整关键数据如冠单周数建议与官方记录进行交叉验证。版权与用途分析产生的结论和可视化图表可用于个人学习或内容创作但原始榜单数据本身可能受版权保护直接大规模商用需谨慎。生成的内容中若引用数据应注明来源。技术局限性完全自动化的抓取可能因网页改版而失效需要维护更新解析逻辑。本项目方法论重于一个永久不变的“工具包”。3. 环境准备与前置条件在开始数据抓取与分析前你需要准备好编程和数据处理环境。基础软件环境操作系统Windows 10/11, macOS, 或 Linux 发行版均可。Python环境推荐安装 Python 3.8 或以上版本。可通过官网或 Anaconda 安装。包管理工具使用pip进行Python库的安装。核心Python库根据你选择的数据源安装相应的库。以下是两种主要路径的依赖路径一网页抓取Billboard/维基百科pip install requests beautifulsoup4 pandas matplotlibrequests: 用于发送HTTP请求获取网页HTML。beautifulsoup4: 用于解析HTML提取所需数据。pandas: 用于数据清洗、排序和保存为CSV。matplotlib: 用于生成成绩可视化图表。路径二Spotify APIpip install spotipy pandas matplotlibspotipy: Spotify官方Python库用于调用其API。你还需要在 Spotify Developer Dashboard 创建一个应用获取CLIENT_ID和CLIENT_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, headersheaders, timeout10) 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}, inplaceTrue) # 筛选出有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], errorscoerce) df_valid df_valid.dropna(subset[Peak Position]) # 按峰值排名升序排序排名1最好 df_sorted df_valid.sort_values(byPeak Position).head(10) # 假设歌曲名列名为 Song top_songs df_sorted[[Song, Peak Position]].reset_index(dropTrue) 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(indexFalse)) # 保存为CSV文件 top_10.to_csv(pink_top10_hot100.csv, indexFalse, encodingutf-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凭证登录 Spotify Developer Dashboard。创建一个新应用获取CLIENT_ID和CLIENT_SECRET。在应用设置中将重定向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_idCLIENT_ID, client_secretCLIENT_SECRET) sp spotipy.Spotify(client_credentials_managerclient_credentials_manager) def get_artist_top_tracks(artist_name): # 搜索歌手 results sp.search(qartist: artist_name, typeartist, limit1) 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(byPopularity, ascendingFalse).reset_index(dropTrue) 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(indexFalse)) top_tracks_df.to_csv(f{artist.lower()}_spotify_top_tracks.csv, indexFalse, encodingutf-8-sig)步骤 3数据关联分析单纯使用Spotify流行度不能完全对应Billboard历史成绩。一个更复杂的思路是从可靠来源如维基百科获取P!nk所有进入过Hot 100的歌曲名单及其峰值排名。使用Spotify API的search功能根据“歌曲名歌手”查询每首歌的popularity、release_date等信息。将两个数据源合并你可以分析“Billboard峰值排名”与“当前Spotify流行度”之间的相关性或者筛选出两者都表现优异的歌曲。6. 数据清洗、排序与TOP 10生成无论从哪种渠道获得原始数据清洗和排序都是关键步骤。清洗常见问题非标准排名数据中可能包含“1 (2)”、“X”、“-”、“—”分别表示峰值排名、在榜周数、未上榜等。需要用字符串处理如.str.extract((\d))提取纯数字。多列数据Billboard数据可能包含“峰值位置”(Peak Pos.)和“在榜周数”(Wks on Chart)需要区分。歌曲名重复混音版、现场版可能与原版并列需要根据分析目标决定是合并还是区分。生成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(byPeak).head(10).reset_index(dropTrue) print(按Billboard Hot 100峰值排名TOP 10:) print(df_sorted_by_peak[[Song, Peak, Weeks]]) # 按在榜周数排序 df_sorted_by_weeks df.sort_values(byWeeks, ascendingFalse).head(10).reset_index(dropTrue) print(\n按在榜周数TOP 10:) print(df_sorted_by_weeks[[Song, Peak, Weeks]]) # 保存结果 df_sorted_by_peak.to_csv(pink_top10_by_peak.csv, indexFalse) df_sorted_by_weeks.to_csv(pink_top10_by_weeks.csv, indexFalse)7. 结果可视化呈现数据表格是给机器看的图表是给人看的。使用matplotlib或seaborn库可以将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], colorskyblue) 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)}, vacenter) plt.tight_layout() plt.savefig(pink_top10_peak_chart.png, dpi300) 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, colorlightcoral, labelPeak Position, alpha0.7) ax1.set_xlabel(Song) ax1.set_ylabel(Peak Position, colordarkred) ax1.set_xticks(x) ax1.set_xticklabels(songs, rotation45, haright) ax1.tick_params(axisy, labelcolordarkred) ax1.invert_yaxis() # 排名轴反向让顶部位置更好 ax2 ax1.twinx() ax2.plot(x, weeks, colorsteelblue, markero, linewidth2, labelWeeks on Chart) ax2.set_ylabel(Weeks on Chart, colorsteelblue) ax2.tick_params(axisy, labelcolorsteelblue) fig.suptitle(P!nk Top 10 Songs: Peak Position vs. Weeks on Chart) fig.legend(locupper left, bbox_to_anchor(0.1, 0.9)) fig.tight_layout() plt.savefig(pink_top10_peak_vs_weeks.png, dpi300) plt.show()8. 常见问题与排查方法在数据抓取和分析过程中你可能会遇到以下问题问题现象可能原因排查方式解决方案运行脚本后无输出或报错ConnectionError网络问题或目标网站屏蔽了请求检查网络连接尝试在浏览器中直接访问目标URL。打印response.status_code。添加headers模拟浏览器在请求间增加time.sleep()延时或使用代理。成功获取网页但找不到表格数据网页结构已更新或表格的class/id已改变使用print(soup.prettify())或浏览器检查工具重新分析目标数据所在的HTML标签结构。更新脚本中的选择器可能需要使用更灵活的查找方式如find_all(table)后通过表格内容文本过滤。数据列名混乱或包含多余字符原始表格结构复杂存在合并单元格或注释打印df.columns和df.head()查看原始数据形态。进行数据清洗如重命名列、删除空行、使用df.iloc选择特定列。Spotify API 返回401或403错误客户端凭证无效、过期或权限不足检查CLIENT_ID和CLIENT_SECRET是否正确是否在Dashboard中设置了重定向URI。重新生成密钥确保认证流程正确。对于需要用户授权的操作需使用SpotifyOAuth而非SpotifyClientCredentials。排名数据无法转换为数字原始数据中包含非数字字符如“X”“(1)”打印出有问题的具体数据值。使用字符串方法如.str.extract((\d))先提取数字部分再用pd.to_numeric(..., errorscoerce)转换。生成的图表中文乱码系统缺少中文字体或matplotlib默认字体不支持中文检查图表标题、标签是否包含中文。在脚本开头添加字体设置plt.rcParams[font.sans-serif] [SimHei, DejaVu Sans](Windows) 或[Arial Unicode MS](macOS)。9. 最佳实践与使用建议为了更高效、稳定地运行此类数据分析项目建议遵循以下实践数据源备份与版本控制将清洗后的干净数据CSV/JSON保存下来。对抓取脚本进行版本控制如使用Git当网站结构变化时可以回退和对比。尊重数据源在抓取公开数据时务必遵守robots.txt规则设置合理的请求间隔例如在循环请求间添加time.sleep(2)避免对服务器造成压力。异常处理与日志记录在脚本中加入try...except块来捕获网络超时、解析错误等异常并记录到日志文件便于后期排查。模块化设计将数据抓取、清洗、分析、可视化写成独立的函数或模块提高代码可读性和复用性。例如可以创建一个billboard_scraper.py模块供其他分析项目调用。结果复核自动化抓取的结果尤其是TOP 10这种结论性数据务必与一两个已知的权威来源如Billboard官网历史榜单进行手动核对确保关键名次无误。扩展性思考本项目的方法论可以轻松迁移。只需修改脚本中的歌手姓名、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和解析规则便可快速启动。数据驱动的洞察力始于一次成功的抓取。