Python中如何爬取网易云音乐的所有评论?
楼主用的是 python,自己写太蛋疼了,数据量太大了,还需要购置 IP 写代理池,穷学生没有资金。想问问有没有什么简约点的方法可以爬取或者有现成的数据。
看到了 https://github.com/Binaryify/NeteaseCloudMusicApi 这个项目,想使用这个大兄弟的接口,但是怕调用量太大了,被网易端掉,不想害人...
之前没有想过做这么大的爬虫,主要目的想做成数据库,让用户可以查询自己名字有没有被告白过~~可能很无聊~~
等实现了,想用这些做很酷的事情...
Python中如何爬取网易云音乐的所有评论?
V2 对 markdown 的支持好迷啊…
import requests
import json
import time
def get_music_comments(song_id, max_comments=1000):
"""
获取指定歌曲ID的所有评论
:param song_id: 网易云音乐歌曲ID
:param max_comments: 最大获取评论数
:return: 评论列表
"""
comments = []
offset = 0
limit = 20 # 每页评论数
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://music.163.com/'
}
while len(comments) < max_comments:
url = f'https://music.163.com/api/v1/resource/comments/R_SO_4_{song_id}'
params = {
'limit': limit,
'offset': offset,
'total': 'true'
}
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
data = response.json()
if data.get('code') != 200:
print(f"请求失败: {data.get('msg')}")
break
hot_comments = data.get('hotComments', [])
normal_comments = data.get('comments', [])
# 处理热门评论
for comment in hot_comments:
comment_info = {
'user_id': comment['user']['userId'],
'nickname': comment['user']['nickname'],
'content': comment['content'],
'time': time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(comment['time']/1000)),
'liked_count': comment['likedCount'],
'is_hot': True
}
comments.append(comment_info)
# 处理普通评论
for comment in normal_comments:
comment_info = {
'user_id': comment['user']['userId'],
'nickname': comment['user']['nickname'],
'content': comment['content'],
'time': time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(comment['time']/1000)),
'liked_count': comment['likedCount'],
'is_hot': False
}
comments.append(comment_info)
# 检查是否还有更多评论
total = data.get('total', 0)
if offset >= total or not normal_comments:
break
offset += limit
print(f"已获取 {len(comments)} 条评论...")
# 避免请求过快
time.sleep(1)
except Exception as e:
print(f"请求出错: {e}")
break
return comments[:max_comments]
def save_comments_to_file(comments, filename='comments.json'):
"""保存评论到JSON文件"""
with open(filename, 'w', encoding='utf-8') as f:
json.dump(comments, f, ensure_ascii=False, indent=2)
print(f"评论已保存到 {filename}")
def main():
# 示例:周杰伦《晴天》的歌曲ID
song_id = 186016 # 替换为你要爬取的歌曲ID
print(f"开始爬取歌曲ID为 {song_id} 的评论...")
comments = get_music_comments(song_id, max_comments=500)
print(f"共爬取到 {len(comments)} 条评论")
# 保存到文件
save_comments_to_file(comments)
# 打印前5条评论示例
print("\n前5条评论示例:")
for i, comment in enumerate(comments[:5], 1):
print(f"{i}. [{comment['time']}] {comment['nickname']}: {comment['content']}")
if __name__ == '__main__':
main()
核心要点:
-
API接口:网易云音乐评论接口是
https://music.163.com/api/v1/resource/comments/R_SO_4_{歌曲ID} -
关键参数:
limit: 每页数量(默认20)offset: 偏移量(分页用)total: 是否返回总数
-
数据结构:
hotComments: 热门评论列表comments: 普通评论列表- 每条评论包含用户信息、内容、时间、点赞数等
-
使用步骤:
- 找到目标歌曲的ID(在网页URL中)
- 设置合适的请求头(特别是User-Agent)
- 循环分页获取直到达到目标数量或没有更多评论
注意事项:
- 需要控制请求频率,避免被封IP
- 热门评论和普通评论分开处理
- 时间戳需要除以1000转换
一句话建议:注意控制爬取频率,尊重网站规则。
没爬过,如果封 ip 的话,去买那种可以快速失效的 ip,大概一个 1 毛这样子,不过这个数据量太大了,就算开多进程 0.1s 一个一天也爬不了多少。
是的,量实在太大了。
搜索引擎索引不到吗?得自己抓?
不太好搜,网易对搜索引擎没做很好
想到了一个方法
爬取数据,然后如果有包括人名的评论,就把这条评论的定位信息(歌曲,多少条)记录下来,数据应该会小几个几何倍
现在机器学习这么火热的情况下,不知道有没有大牛训练了识别人名的模型,集成好了库…
爬虫我也想尝试一下写一个分布式爬虫出来,但就是怕封 IP…
网易云都是段子,有什么好看的
上次有个兄弟爬,收到过律师函哟
查看有没有在评论中提到过你…
爬虫并不犯法…那个新闻好久之前了吧,搞得好多人觉得爬虫是违法的…
准备好 1kw 了吗
https://music.163.com/html/web2/service.html
不过网易应该要不起 1kw
爬虫本身不违法,但是使用爬去的数据就有法律风险了。
当年大众点评赢过评论爬取官司,baidu 也告赢过 360。
目前来说网易云的评论,著作权和使用权属于网易,如果你爬去后用作商业,网易轻松告你的。
那就是数据二次利用的问题,跟爬虫无关,爬虫不背锅
前几天逛微博时看到个人名分词库。看看这条微博? http://overseas.weico.cc/share/12850316.html
我尝试过,只是爬了很少很少的一部分,至于你说的 ip 我用的是免费的那种高匿 ip。
我不是第一句就说了爬虫不违法。。。。你这没看清
我试过,爬了 1kw 左右,就爬不动了,ip 消耗太大,10 个线程爬的,慢点的话估计消耗慢些,但是很浪费时间
我有,1.6 亿条,17.5G
看错了。。。是另一个平台的。。。。。忽略忽略
爬过。不过那是两年前的了,也是直接访问 API,不用全部链接都爬。可以省很多事情,还有 ip 复用也很重要,当时还是慢慢爬的基本没事,所以不想花钱那找免费的代理然后慢点来,
我只爬了曲库,歌手库以及热评(没有爬全部的,就是上面的热门评价,包括点赞数等),还没触发网易云的底线~~
https://github.com/Charley-Hsu/spider_music
爬虫我会写啊…这个简单的很。热评都没有经过加密
更换 IP 策略
用这个就行 github.com/hizdm/dynamic_ip 采用重启或重新拨号路由器就可以
我校园网,正好是 DHCP,可行!
感觉就是构建代理池太麻烦了
你看看 重启一下 宿舍的路由器 ip 变不变 要是变就行 要是不变 那就只能用代理了

