伴随着《后来的我们》的上映,这首歌的评论也是一路暴涨。如今让我们趁着这波秋风(虽然已经有点晚了),把这首歌的评论爬下来。虽然之前还打算做出词云可视化出来······然而,还是太懒了
之前爬过豆瓣《霸王别姬》的影评做过这个了,就不想做了QAQ

首先非常感谢之前大佬们贡献,没有他们,我肯定爬不下来这个的。其次这首歌一共12万条评论,但是实际上这部分代码只爬到630页也就是1万多条评论就报了一个错误,但是可以进行改进以得到所有评论。

参考文章链接:https://www.jianshu.com/p/87c022b19669
https://www.zhihu.com/question/36081767
https://blog.csdn.net/qq_28304687/article/details/78678851

  • 分析网页
    打开PC端,搜索《我们》这首歌,打开开发者模式,选择Network

接下来我们来看一下返回正文,也就是Preview内容都包含了什么

事先声明一下:作者本次程序直接拿到了json格式的Comment的全部内容,并未对其进行进一步的解析。
接下来我们看一下此次post请求所需要的各种参数:

parmas和encSecKey是经过加密算法产生的两个参数,幸运的是我们并不是很需要懂它的加密原理,已经有不少的大佬解析过网易云音乐的加密原理了。我们直接拿过来用就可以了。

#如果想要详细了解这部分内容的话,请参考https://www.zhihu.com/question/36081767
也可以参照这个完整的项目,不过是python2写的:https://blog.csdn.net/qq_28304687/article/details/78678851

这里贴一下得到这两个参数的代码:

# 首先生成长度为16的随机字符串作为密钥secKeydef createSecretKey(self,size):return (''.join(map(lambda xx: (hex(ord(xx))[2:]), str(os.urandom(size)))))[0:16]
 # 然后进行aes加密def aesEncrypt(self,text, secKey):pad = 16 - len(text) % 16#print("leix")#print(type(text))#print(type(pad * chr(pad)))if isinstance(text,bytes):#print("type(text)=='bytes'")text=text.decode('utf-8')text = text + str(pad * chr(pad))encryptor = AES.new(secKey, AES.MODE_CBC, '0102030405060708')ciphertext = encryptor.encrypt(text)ciphertext = base64.b64encode(ciphertext)return ciphertext
# 再进行rsa加密def rsaEncrypt(self,text, pubKey, modulus):text = text[::-1]#rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)rs = int(codecs.encode(text.encode('utf-8'),'hex_codec'), 16) ** int(pubKey, 16) % int(modulus, 16)return format(rs, 'x').zfill(256)
# 将明文text进行两次aes加密获得密文encText,因为secKey是在客户端上生成的,所以还需要对其进行RSA加密再传给服务端def encrypted_request(self,text):modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'nonce = '0CoJUm6Qyw8W8jud'pubKey = '010001'text = json.dumps(text)secKey = self.createSecretKey(16)encText = self.aesEncrypt(self.aesEncrypt(text, nonce), secKey)encSecKey = self.rsaEncrypt(secKey, pubKey, modulus)data = {'params': encText,'encSecKey': encSecKey}return data

到这里我们需要的最难拿到的的参数就已经得到了
其他需要的参数还有headers,这个直接赋值headers里的就行了,还有一个offset偏移量的参数,来限制显示不同页的评论。参数可以这样得到

    # 偏移量def get_offset(self, offset):if offset == 0:text = {'rid': '', 'offset': '0', 'total': 'true', 'limit': '20', 'csrf_token': ''}else:text = {'rid': '', 'offset': '%s' % offset, 'total': 'false', 'limit': '20', 'csrf_token': ''}return text

这次我们是真的拿到了所有参数,可以向网页发出request请求,然后拿到我们想要的网页内容了。
请求是这样发出的:

    def get_post_req(self, url, data):try:req = requests.post(url, headers=self.headers, data=data)print("已连接上网易云音乐")except Exception as e:print (url)print(e)if(req==""):print("什么都没有抓取到")else:#print(req.json())#这里我们就得到了所有的json格式的评论了,并把它写进了txt文本with codecs.open(filename, 'a', encoding='utf-8') as f:f.writelines(req.text)print("----------------")return req.json()

接下来只需要把得到的json格式的网页源码进行解析就可以了,用re正则表达式匹配也好,用beautifulsoup解析也行,都不是很难。

下面就贴出本次的全部代码吧:

# -*-coding:utf-8-*-
'author:guoya'
import os
import time
import json
import base64import requestsimport codecs
from Crypto.Cipher import AES
class CommentCrawl(object):'''评论的API封装成一个类,直接传入评论的API,再调用函数get_song_comment()和get_album_comment()即可分别获取歌曲和专辑的评论信息 '''def __init__(self,comment_url):self.comment_url = comment_urlself.headers = {"Referer":"http://music.163.com/song?id=551816010","User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36",}# 生成长度为16的随机字符串作为密钥secKeydef createSecretKey(self,size):return (''.join(map(lambda xx: (hex(ord(xx))[2:]), str(os.urandom(size)))))[0:16]# 进行aes加密def aesEncrypt(self,text, secKey):pad = 16 - len(text) % 16#print("leix")#print(type(text))#print(type(pad * chr(pad)))if isinstance(text,bytes):#print("type(text)=='bytes'")text=text.decode('utf-8')text = text + str(pad * chr(pad))encryptor = AES.new(secKey, AES.MODE_CBC, '0102030405060708')ciphertext = encryptor.encrypt(text)ciphertext = base64.b64encode(ciphertext)return ciphertext# 进行rsa加密def rsaEncrypt(self,text, pubKey, modulus):text = text[::-1]#rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)rs = int(codecs.encode(text.encode('utf-8'),'hex_codec'), 16) ** int(pubKey, 16) % int(modulus, 16)return format(rs, 'x').zfill(256)# 将明文text进行两次aes加密获得密文encText,因为secKey是在客户端上生成的,所以还需要对其进行RSA加密再传给服务端def encrypted_request(self,text):modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'nonce = '0CoJUm6Qyw8W8jud'pubKey = '010001'text = json.dumps(text)secKey = self.createSecretKey(16)encText = self.aesEncrypt(self.aesEncrypt(text, nonce), secKey)encSecKey = self.rsaEncrypt(secKey, pubKey, modulus)data = {'params': encText,'encSecKey': encSecKey}return datadef get_post_req(self, url, data):try:req = requests.post(url, headers=self.headers, data=data)print("已连接上网易云音乐")except Exception as e:print (url)print(e)if(req==""):print("什么都没有抓取到")else:#print(req.json())#这里我们就得到了所有的json格式的评论了,并把它写进了txt文本with codecs.open(filename, 'a', encoding='utf-8') as f:f.writelines(req.text)print("----------------")return req.json()# 偏移量def get_offset(self, offset):if offset == 0:text = {'rid': '', 'offset': '0', 'total': 'true', 'limit': '20', 'csrf_token': ''}else:text = {'rid': '', 'offset': '%s' % offset, 'total': 'false', 'limit': '20', 'csrf_token': ''}return text# 得到json格式的评论def get_json_data(self,url,offset):text = self.get_offset(offset)data = self.encrypted_request(text)json_text = self.get_post_req(url, data)return json_textdef get_song_comment(self):'''某首歌下全部评论 '''comment_info = []data = self.get_json_data(self.comment_url, offset=0)comment_count = data['total']#comment_count = 3if comment_count:comment_info.append(data)if comment_count > 20:for offset in range(20, int(comment_count), 20):print("开始爬取第{}页".format(offset/20))comment = self.get_json_data(self.comment_url, offset=offset)comment_info.append(comment)return comment_infodef get_album_comment(self, comment_count):'''某专辑下全部评论 '''album_comment_info = []if comment_count:for offset in range(0, int(comment_count), 20):comment = self.get_json_data(self.comment_url, offset=offset)album_comment_info.append(comment)return album_comment_infodef save_to_file(list, filname):with codecs.open(filename, 'a', encoding='utf-8') as f:f.writelines(list)print("写入文件成功!")start_time = time.time()
filename = "后来的我们.txt"
comment_url='http://music.163.com/weapi/v1/resource/comments/R_SO_4_551816010?csrf_token='
all_coment=[]
craw_song_pinglun=CommentCrawl(comment_url)
print("开始")
all_coment=craw_song_pinglun.get_song_comment()
print("--------------")end_time = time.time()  # 结束时间
print("程序耗时%f秒." % (end_time - start_time))
print("已完成")

本次程序爬取到630页的报了一个错误。建议优化及改进方案:爬完每页之后sleep几秒,或者尝试多线程爬取,或者换ip。我已经不太想继续研究这个了 。爬取内容和源码已上传到百度云盘。链接:https://pan.baidu.com/s/1gJxxzxFOMQWII4ORNh4f5A) 密码:kmjj

后面这个就和题目无关了。

python3爬取网易云音乐《我们》全部评论相关推荐

  1. 如何用 Python 爬取网易云音乐的 10w+ 评论?附详细代码解读

    在简单学习了Python爬虫之后,我的下一个目标就是网易云音乐.因为本人平时就是用它听的歌,也喜欢看歌里的评论,所以本文就来爬一爬网易云音乐的评论吧! 正式进入主题 首先是找到目标网页并分析网页结构, ...

  2. 爬虫入门——用python爬取网易云音乐热门歌手评论数

    本文参考Monkey_D_Newdun 的文章 https://blog.csdn.net/Monkey_D_Newdun/article/details/79318629 用爬虫获取网易云音乐热门歌 ...

  3. 用python爬取网易云评论最多的歌_巧用Python爬取网易云音乐歌曲全部评论

    一.首先分析数据的请求方式 网易云音乐歌曲页面的URL形式为https://music.163.com/#/song?id=歌曲id号,这里我用Delacey的Dream it possible 为例 ...

  4. 【python】爬虫入门:爬取网易云音乐的歌曲评论、用户歌单、用户听歌记录等

    目录 一.概述 二.爬取流程 1.爬取评论 1.1.资源定位 1.2.爬取准备 1.3.代码实现 2.爬取听歌记录 2.1.资源定位 2.2.爬取准备 2.3.js劫持 三.总结 一.概述 第一次学爬 ...

  5. js逆向之爬取网易云音乐和歌曲评论

    前面我写的文章当中也有网易云音乐的爬取,只不过是借助了外链接口,本篇文章将介绍网易本身的接口进行爬取 ** 1 . 我们要获取的内容 ** 某一个歌单里面的所有歌曲 ** 2. 我们先分析一下歌曲的真 ...

  6. python爬音乐-用python爬取网易云音乐歌曲的歌词

    今天我来分享一下如何用python爬取网易云音乐歌曲的歌词,网易云音乐的歌词的爬取思路同前面介绍过的爬取网易云音乐的歌曲评论的爬取思路一致.由于两者的加密思路都是一致的,因此我们只需分析出被加密了的参 ...

  7. PHP爬虫爬取网易云音乐热门评论

    说起爬虫,恐怕第一个想到的都是Python,PHP的就少之又少. 得空闲下来,自己用PHP做了一个爬虫,爬取网易云音乐的热门评论. 效果图: 下面简单说一下思路 首先,在网易云官网排行榜内,审查元素, ...

  8. python爬取网易云音乐飙升榜音乐_python爬取网易云音乐热歌榜 python爬取网易云音乐热歌榜实例代码...

    想了解python爬取网易云音乐热歌榜实例代码的相关内容吗,FXL在本文为您仔细讲解python爬取网易云音乐热歌榜的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:python,网易热歌榜 ...

  9. python爬取网易云音乐飙升榜音乐_python爬取网易云音乐热歌榜实例代码

    首先找到要下载的歌曲排行榜的链接,这里用的是: https://music.163.com/discover/toplist?id=3778678 然后更改你要保存的目录,目录要先建立好文件夹,例如我 ...

最新文章

  1. Kupu,“document-centric”的开放源码的客户端文本编辑器
  2. 两个rtsp同时抓流_海康摄像头同时添加到两台海康硬盘录像机上
  3. java写一个外网访问的接口_【JAVA基础】一个案例搞懂类、对象、重载、封装、继承、多态、覆盖、抽象和接口概念及区别(中篇)...
  4. 触发器——创建||更新||删除||查看
  5. php 统计一周数据,如何获取本周、上周、本月、上个月数据的起止时间 PHP
  6. 2、ShardingSphere 之 Sharding-JDBC实现水平分表
  7. super.getClass()方法调用返回结果的原因
  8. java设计模式 外观,精掌握Java设计模式之外观模式(10)
  9. Indian Buffet Process(印度自助餐过程)介绍
  10. [java8]时间差
  11. ntp如何确认与服务器偏差_CDH集群时钟偏差问题
  12. 项目在服务器的绝对路径,项目在云服务器上的绝对路径
  13. 清楚理解const_cast类型转换
  14. 自动泊车停车位检测算法
  15. hbase基本操作命令及练习
  16. 解决gradle运行gradle -v命令报Fialed to laod library 'native-platform.dll'错误
  17. 2020年常见的服务器都有哪些?都有什么优缺点?
  18. POI 单元格设置背景颜色失效(背景色设置方式),以及背景颜色生效后单元格边框线消失问题解决
  19. 分享Android单元测试
  20. 前端学习--【训练营】Cisco PT Student模拟dhcp自动分配IP地址实现网络互联

热门文章

  1. 工作中一些软件下载资源:PS等
  2. Web前端开发者,不可不知的几个前端框架,你用过吗?
  3. 枚举与模拟总结--常梓良
  4. 街霸 彩虹 m7 android,街霸2彩虹版
  5. Windows Server 安装python时报策略不允许的解决方案
  6. 嵌入式软件工程师和物联网工程师的区别
  7. 中国石油A股发行价确定 15--16.7元是让利于民
  8. IINA+ for Mac(在IINA播放器上观看直播)
  9. 个人使用HEF4051遇到问题总结
  10. win10pro是什么版本