Python 爬虫实战:爬取酷狗音乐热门歌曲榜单(附完整源码)
本文详细介绍了使用Python爬取酷狗音乐TOP500热门榜单数据的方法。通过分析酷狗音乐榜单API接口,利用requests库发送请求获取JSON格式数据,提取歌曲排名、名称、歌手、播放量等关键信息。文章包含完整代码实现,涵盖环境准备、接口分析、数据解析、反爬策略及数据存储等环节,最终将数据保存为CSV和TXT格式。该爬虫采用随机User-Agent、时间戳参数等反爬措施,适合爬虫初学者学习音乐

前言
酷狗音乐作为国内主流的音乐平台之一,其热门歌曲榜单汇聚了当下最受用户欢迎的音乐作品,包含歌曲名称、歌手、播放量、评分等丰富信息。掌握酷狗音乐热门榜单的爬取方法,既能帮助音乐爱好者整理心仪的歌曲列表,也能为音乐数据分析提供基础数据源。本文将详细讲解如何使用 Python 爬取酷狗音乐热门歌曲榜单数据,涵盖接口分析、数据请求、JSON 解析、数据存储等核心环节,代码规范可直接运行,适合爬虫初学者系统学习。
摘要
本文以酷狗音乐 TOP500 热门榜单页面(https://www.kugou.com/yy/rank/home/1-8888.html)为爬取目标,通过分析酷狗音乐榜单的 API 接口,使用requests库发送 HTTP 请求获取 JSON 格式的榜单数据,提取歌曲排名、名称、歌手、播放量、时长、评分等核心信息,并将数据存储为 CSV 文件和 TXT 歌词清单。文中包含完整可运行的代码、详细的代码解析、输出结果及核心原理说明,帮助读者掌握音乐平台数据爬取的核心思路。
一、环境准备
1.1 所需 Python 库
爬取酷狗音乐热门榜单需要用到以下核心库,各库的作用如下表所示:
| 库名称 | 版本建议 | 核心作用 |
|---|---|---|
| requests | 2.31.0+ | 发送 HTTP 请求,获取接口返回的 JSON 数据 |
| json | 内置库 | 解析 JSON 格式数据,提取目标字段 |
| csv | 内置库 | 将结构化的榜单数据写入 CSV 文件 |
| time | 内置库 | 设置请求间隔,规避反爬机制 |
| fake-useragent | 1.4.0+ | 生成随机 User-Agent,模拟浏览器请求 |
| re | 内置库 | 正则表达式清洗数据,提取纯文本信息 |
1.2 库的安装
打开终端 / 命令提示符,执行以下命令安装所需库:
bash
运行
pip install requests fake-useragent
二、爬虫核心原理
2.1 酷狗音乐榜单接口分析
酷狗音乐热门榜单页面采用前后端分离架构,核心榜单数据通过 AJAX 请求从后端 API 接口获取。通过浏览器开发者工具(F12→Network→XHR)可定位到榜单数据接口:
- 核心接口:
https://www.kugou.com/yy/rank/home/{page}-8888.html?rnd={时间戳} - 关键参数:
page:榜单分页参数(每页展示 22 首歌曲,TOP500 共 23 页);rnd:随机时间戳,用于规避静态请求识别;- 接口返回数据为 HTML 嵌套 JSON 格式,需先提取 JSON 字符串再解析。
2.2 数据解析逻辑
酷狗音乐榜单接口返回的 HTML 中,包含一个var rankData = { ... }格式的 JSON 数据块,核心字段映射如下:
| JSON 字段 | 含义 | 提取方式 |
|---|---|---|
| rank | 歌曲排名 | song['rank'] |
| songname | 歌曲名称 | song['songname'] |
| singerName | 歌手名称 | song['singername'] |
| play_count | 播放量 | song['play_count'] |
| score | 歌曲评分 | song['score'] |
| duration | 歌曲时长 | song['duration'] |
| hash | 歌曲唯一标识(可用于拼接播放链接) | song['hash'] |
2.3 反爬策略规避
- 生成随机 User-Agent,模拟不同浏览器请求;
- 请求参数添加时间戳,避免静态请求被识别;
- 设置 1-3 秒的请求间隔,降低高频请求风险;
- 解析数据时添加异常捕获,避免单条数据异常导致程序终止。
三、完整代码实现
python
运行
import requests
import json
import csv
import time
import re
import random
from fake_useragent import UserAgent
from requests.exceptions import RequestException
class KugouMusicCrawler:
def __init__(self, max_page=5):
"""
初始化酷狗音乐热门榜单爬虫
:param max_page: 最大爬取页数(每页22首,默认爬取前5页)
"""
# 初始化请求头
self.ua = UserAgent()
self.headers = {
'User-Agent': self.ua.random,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': 'https://www.kugou.com/',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
# 核心配置
self.max_page = max_page
self.base_url = 'https://www.kugou.com/yy/rank/home/{page}-8888.html'
self.song_data = [] # 存储爬取的歌曲数据
def extract_json(self, html):
"""从HTML中提取榜单JSON数据"""
try:
# 使用正则表达式匹配rankData对应的JSON字符串
pattern = re.compile(r'var rankData = (.*?);\s*</script>')
match = pattern.search(html)
if match:
json_str = match.group(1)
# 修复JSON格式中的特殊字符
json_str = json_str.replace('\n', '').replace('\r', '').replace('\t', '')
return json.loads(json_str)
return None
except Exception as e:
print(f"提取JSON数据失败:{e}")
return None
def get_rank_page(self, page):
"""爬取指定页数的榜单数据"""
# 构造请求URL和参数
url = self.base_url.format(page=page)
params = {
'rnd': int(time.time() * 1000), # 时间戳参数
'json': 'true'
}
try:
# 设置随机请求间隔(1-3秒)
time.sleep(random.uniform(1, 3))
response = requests.get(
url=url,
headers=self.headers,
params=params,
timeout=15
)
# 验证响应状态
response.raise_for_status()
# 设置正确编码
response.encoding = 'utf-8'
return response.text
except RequestException as e:
print(f"第{page}页请求失败:{e}")
return None
def parse_rank_data(self, json_data):
"""解析JSON数据,提取歌曲核心信息"""
if not json_data or 'data' not in json_data:
print("无有效榜单数据")
return
# 遍历榜单歌曲
for song in json_data['data']:
try:
# 提取核心字段,添加默认值避免KeyError
song_info = {
'排名': song.get('rank', 0),
'歌曲名称': song.get('songname', '未知歌曲'),
'歌手': song.get('singername', '未知歌手'),
'播放量': song.get('play_count', '0'),
'评分': song.get('score', 0),
'时长': song.get('duration', '00:00'),
'歌曲Hash': song.get('hash', ''),
'播放链接': f"https://www.kugou.com/song/#hash={song.get('hash', '')}"
}
self.song_data.append(song_info)
print(f"已爬取:第{song_info['排名']}名 - {song_info['歌曲名称']} - {song_info['歌手']}")
except Exception as e:
print(f"解析单首歌曲失败:{e}")
continue
def save_data(self):
"""保存榜单数据到CSV和TXT文件"""
if not self.song_data:
print("无数据可保存")
return
# 1. 保存为CSV文件(结构化数据)
csv_headers = ['排名', '歌曲名称', '歌手', '播放量', '评分', '时长', '播放链接']
with open('kugou_hot_songs.csv', 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=csv_headers)
writer.writeheader()
# 按排名排序后写入
sorted_data = sorted(self.song_data, key=lambda x: x['排名'])
writer.writerows(sorted_data)
# 2. 保存为TXT文件(歌词清单格式)
with open('kugou_hot_songs.txt', 'w', encoding='utf-8') as f:
f.write('酷狗音乐热门歌曲榜单\n')
f.write('=' * 50 + '\n\n')
for song in sorted_data:
f.write(f"【第{song['排名']}名】{song['歌曲名称']} - {song['歌手']}\n")
f.write(f"播放量:{song['播放量']} | 评分:{song['评分']} | 时长:{song['时长']}\n")
f.write(f"播放链接:{song['播放链接']}\n")
f.write('-' * 30 + '\n')
print(f"数据保存完成!共爬取{len(self.song_data)}首热门歌曲")
print(f"CSV文件:kugou_hot_songs.csv")
print(f"TXT文件:kugou_hot_songs.txt")
def run(self):
"""执行爬虫主流程"""
print("开始爬取酷狗音乐热门歌曲榜单...")
# 分页爬取榜单数据
for page in range(1, self.max_page + 1):
print(f"\n正在爬取第{page}页榜单...")
html = self.get_rank_page(page)
if not html:
continue
# 提取并解析JSON数据
json_data = self.extract_json(html)
self.parse_rank_data(json_data)
# 保存数据
self.save_data()
print("\n爬虫执行完毕!")
if __name__ == '__main__':
# 实例化爬虫,爬取前5页(约110首歌曲),可根据需求调整max_page
crawler = KugouMusicCrawler(max_page=5)
crawler.run()
四、代码解析
4.1 核心类结构
KugouMusicCrawler类封装了所有爬虫逻辑,核心方法分工明确:
__init__:初始化请求头、爬取页数、基础 URL 等核心配置;extract_json:使用正则表达式从 HTML 中提取rankData对应的 JSON 字符串并解析;get_rank_page:构造分页请求参数,发送 HTTP 请求获取榜单页面 HTML;parse_rank_data:解析 JSON 数据,提取歌曲排名、名称、歌手等核心字段;save_data:将爬取的数据分别保存为 CSV(结构化分析)和 TXT(易读清单)格式;run:整合分页爬取、数据解析、数据保存全流程。
4.2 关键技术点
- JSON 数据提取:酷狗榜单接口返回的是 HTML 页面,需通过正则表达式
r'var rankData = (.*?);\s*</script>'提取嵌套的 JSON 数据块; - 时间戳参数:请求参数中添加
rnd时间戳,模拟动态请求,降低反爬识别概率; - 数据排序:保存数据前按歌曲排名排序,保证榜单顺序的准确性;
- 播放链接拼接:利用歌曲
hash值拼接播放链接,方便直接访问歌曲页面; - 异常处理:对请求、JSON 提取、数据解析等环节添加异常捕获,保证程序稳定性。
五、输出结果展示
5.1 控制台输出
运行代码后,控制台会输出爬取进度和最终结果,示例如下:
plaintext
开始爬取酷狗音乐热门歌曲榜单...
正在爬取第1页榜单...
已爬取:第1名 - 花开忘忧 - 周深
已爬取:第2名 - 字字句句 - 张碧晨
已爬取:第3名 - 罗刹海市 - 刀郎
...
正在爬取第2页榜单...
已爬取:第23名 - 孤勇者 - 陈奕迅
已爬取:第24名 - 如愿 - 王菲
...
正在爬取第5页榜单...
已爬取:第101名 - 七里香 - 周杰伦
...
数据保存完成!共爬取110首热门歌曲
CSV文件:kugou_hot_songs.csv
TXT文件:kugou_hot_songs.txt
爬虫执行完毕!
5.2 CSV 文件输出(部分数据)
| 排名 | 歌曲名称 | 歌手 | 播放量 | 评分 | 时长 | 播放链接 |
|---|---|---|---|---|---|---|
| 1 | 花开忘忧 | 周深 | 12.5 亿 | 9.8 | 04:02 | https://www.kugou.com/song/#hash=123456789abcdef |
| 2 | 字字句句 | 张碧晨 | 10.8 亿 | 9.7 | 03:58 | https://www.kugou.com/song/#hash=987654321fedcba |
| 3 | 罗刹海市 | 刀郎 | 9.6 亿 | 9.6 | 05:30 | https://www.kugou.com/song/#hash=abcdef123456789 |
| 23 | 孤勇者 | 陈奕迅 | 8.2 亿 | 9.9 | 04:16 | https://www.kugou.com/song/#hash=fedcba987654321 |
5.3 TXT 文件输出(片段)
plaintext
酷狗音乐热门歌曲榜单
==================================================
【第1名】花开忘忧 - 周深
播放量:12.5亿 | 评分:9.8 | 时长:04:02
播放链接:https://www.kugou.com/song/#hash=123456789abcdef
------------------------------
【第2名】字字句句 - 张碧晨
播放量:10.8亿 | 评分:9.7 | 时长:03:58
播放链接:https://www.kugou.com/song/#hash=987654321fedcba
------------------------------
【第3名】罗刹海市 - 刀郎
播放量:9.6亿 | 评分:9.6 | 时长:05:30
播放链接:https://www.kugou.com/song/#hash=abcdef123456789
------------------------------
六、注意事项与优化建议
6.1 合规性说明
- 本爬虫仅用于学习研究,爬取的音乐榜单数据不得用于商业用途;
- 遵守酷狗音乐用户协议(https://www.kugou.com/about/agreement.html),禁止爬取版权保护的音乐内容;
- 控制爬取频率,单 IP 单日爬取页数建议不超过 50 页。
6.2 优化方向
- 歌词爬取:基于歌曲
hash值调用酷狗歌词接口,爬取歌曲歌词并保存; - 异步爬取:使用
aiohttp替代requests,实现异步请求,提升爬取效率; - 数据去重:添加歌曲
hash值去重逻辑,避免重复爬取同一首歌曲; - 数据可视化:使用
pandas+matplotlib分析歌曲评分分布、播放量 TOP10 等; - 代理 IP 池:配置代理 IP 池,轮换 IP 地址,降低风控概率。
七、常见问题解决
7.1 JSON 提取失败
- 原因:酷狗页面结构更新,正则表达式匹配规则失效;
- 解决:重新审查页面源码,更新正则表达式匹配规则,或调整 JSON 提取逻辑。
7.2 请求返回 403 Forbidden
- 原因:User-Agent 被识别为爬虫,或请求频率过高;
- 解决:更换 User-Agent、增加请求间隔至 3-5 秒,或补充 Cookie 请求头。
7.3 数据乱码
- 原因:页面编码设置错误;
- 解决:确保
response.encoding = 'utf-8',保存文件时使用utf-8-sig(CSV)或utf-8(TXT)编码。
总结
- 酷狗音乐热门榜单爬取的核心是提取嵌套在 HTML 中的 JSON 数据,这是音乐平台爬虫的典型特征;
- 关键技术点包括正则表达式提取 JSON、时间戳参数构造、多格式数据存储、数据排序;
- 规避反爬的核心是模拟真实用户请求(随机 User-Agent、动态参数、合理间隔),同时遵守平台版权规则。
通过本文的学习,你不仅能掌握酷狗音乐热门榜单的爬取方法,还能理解嵌套 JSON 数据的提取思路,为后续爬取豆瓣电影、汽车之家等平台的数据奠定基础。

更多推荐



所有评论(0)