Python抓取网易云音乐热搜榜热评

引子

啊~最有个小姐姐要做微信公众号,她需要优质的句子、文章,于是我想到了网易云每首伤感歌曲下面的评论,嗯~很感人,甚至有的时候真的感觉这里就是能触及我心灵最柔软的地方,正好这几天在学习python,于是我开始了我精彩的表演

准备


好像没什么可准备的,我是win10操作系统、python 3.6.4、浏览器用的自带的edge和chrome

开始

分析测试

初探

打开浏览器,网易云音乐>>排行榜>>云音乐热搜榜>>随便打开一首歌>>F12进入开发人员工具,刷新页面



从上图的F12开发人员工具截图中我们可以看到,很多的链接,我们一个一个去找到底是哪个链接的正文响应返回了评论信息,下图中我们在某个链接中找到了包含评论的 响应正文,和请求正文


将上图中响应正文的文本拷贝到notepad++中格式化,格式化后我们观察到 评论是在hotComments节点下的content的值


探果

通过上面的查探,我们可以得出以下几个有用的信息:
1.该歌曲的链接http://music.163.com/#/song?id=523251118 后面的id应该表示歌曲的id
2.返回包含评论的响应正文的链接为http://music.163.com/weapi/v1/resource/comments/R_SO_4_523251118?csrf_token= 并且链接中 R_SO_4_后面的数字,可以看出就是这首歌曲的id
3.评论在响应正文 的hotComments节点下的content
4.请求正文中的两个参数 encSecKey和params

通过上面得出的信息,我们可以简单的写个脚本测试一下


从上图中我们可以看到可以正常接受我们想要的响应正文,用红框圈出来的是这首歌曲的id,那么现在我们只是获取到了一首歌的评论,要想获取热搜榜搜友歌曲的评论,就需要获得 所有歌曲的id,然后执行遍历就好了

接下来我们就去搞所有的歌曲,获取所有热搜榜歌曲的id


再探

打开网易云音乐>>排行榜>>云音乐热搜榜>>F12开发人员工具>>刷新>>找到包含热搜榜歌曲的响应正文的链接

观察上面的<ul>标签,我们发现里面的<a>标签的href属性值就是我们想要获得的歌曲id,现在id有了但是又不是单纯的歌曲id列表,所以我们要用正则表达式匹配所有的歌曲名字和id,像这样
#使用正则表达式匹配正文响应
    reg1 = r'<ul class="f-hide"><li><a href="/song\?id=\d*?">.*</a></li></ul>'
    result_contain_songs_ul = re.compile(reg1).findall(r.text)
    result_contain_songs_ul = result_contain_songs_ul[0]

    reg2 = r'<li><a href="/song\?id=\d*?">(.*?)</a></li>'
    reg3 = r'<li><a href="/song\?id=(\d*?)">.*?</a></li>'
    hot_songs_name = re.compile(reg2).findall(result_contain_songs_ul)
    hot_songs_id = re.compile(reg3).findall(result_contain_songs_ul)
链接的请求标头

探果

通过第二次观察我们得出以下信息:
1.网易云音乐热搜榜链接 http://music.163.com/discover/toplist?id=3778678
2.请求标头没有额外的信息
3.歌曲名和id需要用正则表达式匹配

好了,通过两次的观察和分析我们可以开始写脚本了,再来简单测试一下(算了直接贴代码了)



代码

import re
import requests
import json

def get_all_hotsongs():
    """抓热搜榜所有歌曲"""
    url = 'http://music.163.com/discover/toplist?id=3778678'
    headers = {
        'Cookie':'__e_=1515461191756; _ntes_nnid=af802a7dd2cafc9fef605185da6e73fb,1515461190617; _ntes_nuid=af802a7dd2cafc9fef605185da6e73fb; JSESSIONID-WYYY=HMyeRdf98eDm%2Bi%5CRnK9iB%5ChcSODhA%2Bh4jx5t3z20hhwTRsOCWhBS5Cpn%2B5j%5CVfMIu0i4bQY9sky%5CsvMmHhuwud2cDNbFRD%2FHhWHE61VhovnFrKWXfDAp%5CqO%2B6cEc%2B%2BIXGz83mwrGS78Goo%2BWgsyJb37Oaqr0IehSp288xn5DhgC3Cobe%3A1515585307035; _iuqxldmzr_=32; __utma=94650624.61181594.1515583507.1515583507.1515583507.1; __utmc=94650624; __utmz=94650624.1515583507.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=94650624.4.10.1515583507',
        'Host':'music.163.com',
        'Refere':'http://music.163.com/',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    }
    r = requests.get(url,headers=headers)

    #使用正则表达式匹配正文响应
    reg1 = r'<ul class="f-hide"><li><a href="/song\?id=\d*?">.*</a></li></ul>'
    result_contain_songs_ul = re.compile(reg1).findall(r.text)
    result_contain_songs_ul = result_contain_songs_ul[0]

    reg2 = r'<li><a href="/song\?id=\d*?">(.*?)</a></li>'
    reg3 = r'<li><a href="/song\?id=(\d*?)">.*?</a></li>'
    hot_songs_name = re.compile(reg2).findall(result_contain_songs_ul)
    hot_songs_id = re.compile(reg3).findall(result_contain_songs_ul)

    #返回歌曲名 歌曲id
    return hot_songs_name,hot_songs_id

def get_hotcommnets(hot_songs_name,hot_songs_id):
    """抓热搜榜歌曲热评"""
    url = 'http://music.163.com/weapi/v1/resource/comments/R_SO_4_'+hot_songs_id+'?csrf_token='
    headers = {
        'Host':'music.163.com',
        'Proxy-Connection':'keep-alive',
        'Origin':'http://music.163.com',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)',
        'Content-Type':'application/x-www-form-urlencoded',
        'Accept':'*/*',
        'Referer':'http://music.163.com/song?id='+hot_songs_id+'',
        'Accept-Encoding':'gzip, deflate',
        'Accept-Language':'zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cookie':'__e_=1515461191756; _ntes_nnid=af802a7dd2cafc9fef605185da6e73fb,1515461190617; _ntes_nuid=af802a7dd2cafc9fef605185da6e73fb; _iuqxldmzr_=32; __utmc=94650624; __utmz=94650624.1515628584.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; JSESSIONID-WYYY=TO%2BtUvrTWONNwB%2BgzDpfjFDiggKiS%2FfpMYNam%2BWGooHNka%2BwMhdsT%5CY%2Fn%2FpSMJwo4skFIK1T%2FNjd95lbGHWMQr5d5qcMRPB9SVKWK8UuBs1OGugZ4lFwipwjwWbCepSw%5CjWv31i1Qt%5CWWwtrFzzktj8CdCzniAw%5CgFCElUJnsQygY0MA%3A1515635604215; __utma=94650624.61181594.1515583507.1515630648.1515633862.4; __utmb=94650624.2.10.1515633862'
    }
    data = {
        'params':'cG5yxYo1s0E9Eqv4QWJLM0fdPiJr0+GfKwqcGPulhOtGJ16gEBopaMhe6XeVNKDigMlpCaV7vrDNQLIOPIaTpAjlcJv+hjdCek6nL0ODfHt9ZEmtkTmU4r/+SA6Vno+o+c4EaPvhghNUXRMdVM/LltKvVanwOSvVhcqUPw9qij1d1akcxweLOWf1hKh2/q/m',
        'encSecKey':'a6c21ac04a44dca0e68174f9dfa85537a2694ecf7b43bdcd46a90836209a3d68008b430b54751bc0f56b12b6da38a265afcef1edbf687d70d1eb853144e920fea28e19a8c6145b7bad33e40d077e8a689b4bf67b367db815278af4ef227b02d85e609007106b7fc4a547bf96a1b90b0eda85bca6cc79ca6fc6559d00060d4184'
    }
    
    #postdata = data.encode('utf-8')
    response = requests.post(url,data=data,headers=headers)
    #print(response.text)

    #格式化响应正文hotComments热评节点
    hotcomments = json.loads(response.text)['hotComments']
    #print(hotcomments)

    #遍历热评内容 保存到当前目录文本
    num = 0
    with open('./song_comments.txt','a',encoding='utf-8') as f:
        f.write('《'+hot_songs_name+'》:'+'\n')
        for i in hotcomments:
            num+=1
            #print(str(num))
            f.write(str(num)+'.'+i['content']+'\n')
            #f.write(i['content']+'\n')
        f.write('\n====================================================\n\n')

#调用方法 获得歌曲名 歌曲id
hot_songs_name,hot_songs_id = get_all_hotsongs()
#print(len(hot_songs_name))


#循环遍历抓取所有热搜热评
num = 0
while num < len(hot_songs_name):
    print('正在抓取网易云音乐热搜榜第%d首歌曲热评...'%(num+1))
    get_hotcommnets(hot_songs_name[num],hot_songs_id[num])
    print('第%d首歌曲热评抓取成功'%(num+1))
    num+=1

#print(hot_songs_name[0],hot_songs_id[0])
#get_hotcommnets(hot_songs_name[0],hot_songs_id[0])







  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
基于Node.js,提供网易云所有API接口数据,包括:登录,获取用户信息 , 歌单,收藏,mv, dj 数量 获取用户歌单 获取用户电台 获取用户关注列表 获取用户粉丝列表 获取用户动态 获取用户播放记录 获取精品歌单 获取歌单详情 搜索 搜索建议 获取歌词 歌曲评论 收藏单曲到歌单 专辑评论 歌单评论 mv 评论 电台节目评论 banner 获取歌曲详情 获取专辑内容 获取歌手单曲 获取歌手 mv 获取歌手专辑 获取歌手描述 获取相似歌手 获取相似歌单 相似 mv 获取相似音乐 获取最近 5 个听了这首歌的用户 获取每日推荐歌单 获取每日推荐歌曲 私人 FM 签到 喜欢音乐 垃圾桶 歌单 ( 网友精选碟 ) 新碟上架 门歌手 最新 mv 推荐 mv 推荐歌单 推荐新音乐 推荐电台 推荐节目 独家放送 mv 排行 获取 mv 数据 播放 mv/视频 排行榜 歌手榜 云盘 电台 - 推荐 电台 - 分类 电台 - 分类推荐 电台 - 订阅 电台 - 详情 电台 - 节目 给评论点赞 获取动态 搜列表(简略) 发送私信 发送私信歌单 新建歌单 收藏/取消收藏歌单 歌单分类 收藏的歌手列表 订阅的电台列表 相关歌单推荐 付费精选接口 音乐是否可用检查接口 登录状态 获取视频播放地址 发送/删除评论 门评论 视频评论 退出登录 所有榜单 所有榜单内容摘要 收藏视频 收藏 MV 视频详情 相关视频 关注用户 新歌速递 喜欢音乐列表(无序) 收藏的 MV 列表 获取最新专辑 听歌打卡 获取视频标签下的视频 已收藏专辑列表 获取动态评论 歌单收藏者列表 云盘歌曲删除 门话题 电台 - 推荐类型 电台 - 非门类型 电台 - 今日优选 心动模式/智能播放 转发动态 删除动态 分享歌曲、歌单、mv、电台、电台节目到动态 通知-私信 通知-评论 通知-@我 通知-通知 设置 云盘数据详情 私信内容 我的数字专辑 batch批量请求接口 获取视频标签列表 全部mv 网易出品mv 收藏/取消收藏专辑 专辑动态信息 搜列表(详细) 更换绑定手机 检测手机号码是否已注册 初始化昵称 更新歌单描述 更新歌单名 更新歌单标签 默认搜索关键词 删除歌单 电台banner 用户电台 门电台 电台 - 节目详情 电台 - 节目榜 电台 - 新晋电台榜/门电台榜 类别门电台 云村热评 电台24小时节目榜 电台24小时主播榜 电台最主播榜 电台主播新人榜 电台付费精品榜 歌手门50首歌曲
好的,这是一个比较常见的爬虫案例,我可以给你提供一个基本的代码框架,但需要提醒的是,网易云音乐有反爬措施,如果你频繁地爬取数据可能会被封禁IP,所以请合理使用爬虫工具。 首先,你需要安装requests和BeautifulSoup库,可以使用pip命令进行安装。 ```python pip install requests pip install beautifulsoup4 ``` 然后,你可以使用下面的代码来爬取网易云音乐歌榜评论: ```python import requests from bs4 import BeautifulSoup # 设置请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} # 获取歌曲ID def get_music_id(): url = 'https://music.163.com/discover/toplist?id=3778678' response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') music_id = soup.select('#song-list-pre-cache ul li a')[0]['href'] return music_id.split('=')[1] # 获取评论数据 def get_comments(): music_id = get_music_id() url = f'https://music.163.com/weapi/v1/resource/comments/R_SO_4_{music_id}?csrf_token=' data = { 'params': 'v3NN7cNlbVqjU3s3VH8Q8J2ubwbi+2XQdSvLsZ9VOM2JF8C9F+uLX2zO5S0vC/KyPgOznLWc9jXj7J6zZr6fBm0qzrY+7uZPnQbrI+UWqJbIM2vO7W3JjV9Ri5Jv5sT5mUgGqHh+XyB4uh0zvGh9ZJ8yL4Yx/5RxE0KfGJjFtUwLrUqH6PQeGKvTfcTcXAAeX', 'encSecKey': '3c2a73e4d9c3f4b7f43e5d285b329f8b796e58f099a21d9e0cb8fb0f8c3b835e0f3c9e73a5b6c7c2c4a2c35a2e7d6b5d4a2c9f8f7d4d6f0a28c1d8a7e9f354d0d3bdcacf3e5a96e8f3ec6b7ba1a0d9f3d9c9f5e7ab6f9c7a3f9c1a9f95e6cbebcf0e6e7e7d1d1f6e4b9a2cb5f9e', 'encText': 'id=3778678&offset=0&total=false&limit=20&csrf_token=' } response = requests.post(url, headers=headers, data=data) comments_json = response.json() comments = [comment['content'] for comment in comments_json['comments']] return comments if __name__ == '__main__': comments = get_comments() print(comments) ``` 代码中,我们首先通过requests库发送请求,使用BeautifulSoup库解析HTML,获取网易云音乐歌榜的歌曲ID。然后,我们构造POST请求,向指定歌曲的评论API发送请求,获取评论数据。 最后,我们打印出获取到的评论数据。 注意,代码中的data字典中的参数是经过加密的,如果有需要可以使用Fiddler等工具进行抓包分析。另外,获取到的评论数据是JSON格式,我们可以通过json库进行解析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值