原标题:爬取网易云音乐的评论后,竟有这种发现!

作者 | 志颖

责编 | 胡巍巍

用过网易云音乐听歌的朋友都知道,网易云音乐每首歌曲后面都有很多评论,热门歌曲的评论更是接近百万或者是超过百万条。

现在笔者就来分享一下如何爬取网易云音乐歌曲的全部评论,由于网易云音乐的评论都做了混淆加密处理,因此我们需要深入了解它的加密过程之后,才能爬取到网易云音乐歌曲的全部评论。

首先分析数据的请求方式

网易云音乐歌曲页面的URL形式为https://music。163。com/#/song?id=歌曲ID号,这里我用Delacey的Dream it possible 为例进行讲解,它的URL为https://music。163。com/#/song?id=38592976。接下来开始分析数据的请求方式。

由于网易云音乐的评论是通过Ajax传输,我们打开浏览器的开发者工具(检查元素),选中控制面板中的Network,再点击XHR(捕获AJAX数据),然后点击左上角的重新加载,会看到下面图片中的数据请求列表。

点击R_SO_4_38592976?csrf_token=cdee144903c5a32e6752f50180329fc9这一行,再点击Preview。

现我们所需要的数据就在这JSON格式的数据中,其中Comments中是第一页的全部评论,一共20条,Hot Comments是精彩评论一共有15条,每首歌曲只有第一页评论才有精彩评论。接着看一下它的请求头,点击Headers。

我们发现的它是个Post请求,向下滑你会发现这个Post请求还带有数据。

这些数据都是经过加密处理的,因此我们需要分析它的加密过程来生成相应的参数,然后把加密后的参数加到Post请求中才能获取到我们需要的评论数据。

分析加密过程

通过断点调试发现params和encSecKey是由JS脚本中的Window.asrsea()函数生成的。

我们发现Window.asrsea()函数有4个参数,在浏览器的JS控制台分别对这四个参数进行调试:

后面三个参数是定值,只有第一个参数是控制评论页面偏移量的参数,它是一个变量。笔者经过分析发现第一个参数的形式是:

{"rid":"R_SO_4_38592976","offset":"0","total":"True","limit":"20","csrf_token":""}

下面我来详细讲解这个变量的发现过程:

首先找到core_dfe56728795d119e4d476fd09ea2dc51。JS这个JS脚本,然后将断点打在第12973行,点击第一页评论,页面加载到断点处便停止了。

然后按下电脑的Esc键打开JS控制台,输入i1x,查看第一个变量:

这是第一页的i1x的值,接下来看第二页的(需要点击第2页,然后输入i1x的值):

再看第3页:

再看第4页:

通过这几页的分析,我们可以得到i1x值的变化规律,且可以得到它的一般形式:

{"rid":"R_SO_4_38592976","offset":"0","total":"True","limit":"20","csrf_token":""}

offset和limit是必选参数,其他参数是可选的,其他参数不影响data数据的生成,offset (页面偏移量) = (页数-1) * 20, 注意limit最大值为100,当设为100时,获取第二页时,默认前一页是20个评论,也就是说第二页最新评论有80个,有20个是第一页显示的。因此我们可以构造第一个参数为:

# 偏移量,page是页数

offset = (page-1) * 20

msg = '{ "offset":' + str(offset) + ', "total": "True", "limit": "20", "csrf_token": ""}'

接下来,我们来看一下window.asrsea()函数的整个加密过程:

!function(){

// 函数a生成长度为16的随机字符串

functiona(a){

vard, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";

for(d = 0; a > d; d += 1)

e = Math.random() * b.length,

e = Math.floor(e),

c += b.charAt(e);

returnc

}

// 函数b实现AES加密

functionb(a, b){

varc = CryptoJS.enc.Utf8.parse(b)

, d = CryptoJS.enc.Utf8.parse("0102030405060708")

, e = CryptoJS.enc.Utf8.parse(a)

, f = CryptoJS.AES.encrypt(e, c, {

iv: d,

mode: CryptoJS.mode.CBC

});

returnf.toString()

}

// 函数c实现RSA加密

functionc(a, b, c){

vard, e;

returnsetMaxDigits(131),

d = newRSAKeyPair(b,"",c),

e = encryptedString(d, a)

}

functiond(d, e, f, g){

varh = {}

, i = a(16);

returnh.encText = b(d, g),

h.encText = b(h.encText, i),

h.encSecKey = c(i, e, f),

h

}

functione(a, b, d, e){

varf = {};

returnf.encText = c(a + e, b, d),

f

}

window.asrsea = d,

window.ecnonasr = e

}();

window.asrsea()函数就是上面的d函数,现在我们来看函数d:

functiond(d, e, f, g){

varh = {}

, i = a(16);

returnh.encText = b(d, g), // 第一次AES加密

h.encText = b(h.encText, i), // 第二次AES加密

h.encSecKey = c(i, e, f), // RSA加密

h

}

参数h。encText是经过两次AES加密得到的,h。encSecKey是经过一次RSA加密得到的,其中i是随机生成的长度为16的随机字符串。

生成加密参数

首先我们需要生成长度为16的随机字符串,这里我们仿照上面的java的实现,用Python生成16位长的随机字符串:

# 生成随机字符串

def generate_random_strs(length):

string= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

# 控制次数参数i

i = 0

# 初始化随机字符串

random_strs = ""

whilei < length:

e = random.random() * len(string)

# 向下取整

e = math.floor(e)

random_strs = random_strs + list(string)[e]

i = i + 1

returnrandom_strs

接着用Python实现AES加密,这里要用到PyCrypto库,先安装好这个库:

pipinstall pycrypto

然后导入加密模块:

fromCrypto.Cipher importAES

由于AES加密的明文长度必须是16的倍数,因此我们需要对明文进行必要的填充,以满足它的长度是16的倍数:

# msg是需要加密的明文,如果不是16的倍数则进行填充(paddiing)

padding= 16- len(msg) % 16

# 这里使用padding对应的单字符进行填充

msg= msg + padding * chr(padding)

AES加密的模式是AES。MODE_CBC,初始化向量iv=’0102030405060708′,具体的AES加密:

# AES加密

defAESencrypt(msg, key):

# 如果不是16的倍数则进行填充(paddiing)

padding = 16- len(msg) % 16

# 这里使用padding对应的单字符进行填充

msg = msg + padding * chr(padding)

# 用来加密或者解密的初始向量(必须是16位)

iv = '0102030405060708'

cipher = AES.new(key, AES.MODE_CBC, iv)

# 加密后得到的是bytes类型的数据

encryptedbytes = cipher.encrypt(msg)

# 使用Base64进行编码,返回byte字符串

encodestrs = base64.b64encode(encryptedbytes)

# 对byte字符串按utf-8进行解码

enctext = encodestrs.decode('utf-8')

returnenctext

然后是RSA加密。首先我简单介绍一下RSA的加密过程。在RSA中,明文,密钥和密文都是数字。RSA的加密过程可以用下列的公式来表达,这个公式非常的重要,你只有理解了这个公式,才能用Python实现RSA加密。

密文 = 明文E modN (RSA加密)

RSA的密文是对代表明文的数字的E次方求mod N的结果, 通俗地讲就是将明文和自己做E次乘法,然后将其结果除以N求余数,这个余数就是密文。

下面来看具体的RSA加密代码实现:

# RSA加密

def RSAencrypt(randomstrs, key, f):

# 随机字符串逆序排列

string= randomstrs[::-1]

# 将随机字符串转换成byte类型数据

text= bytes(string, 'utf-8')

seckey = int(codecs.encode(text, encoding='hex'), 16)**int(key, 16) % int(f, 16)

# 返回整数的小写十六进制形式

returnformat(seckey, 'x').zfill(256)

RSA加密后得到的字符串长为256,如果不够长则进行填充(不足部分在左侧添0)。

最后就是获取那两个加密参数:

# 获取参数

def get_params(page):

# msg也可以写成msg = {"offset":"页面偏移量=(页数-1) * 20", "limit":"20"},offset和limit这两个参数必须有(js)

# limit最大值为100,当设为100时,获取第二页时,默认前一页是20个评论,也就是说第二页最新评论有80个,有20个是第一页显示的

# 偏移量

offset = (page-1) * 20

# offset和limit是必选参数,其他参数是可选的,其他参数不影响data数据的生成,最好还是保留

msg = '{"offset":'+ str(offset) + ',"total":"True","limit":"20","csrf_token":""}'

key = '0CoJUm6Qyw8W8jud'

f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'

e = '010001'

enctext = AESencrypt(msg, key)

# 生成长度为16的随机字符串

i = generate_random_strs(16)

# 两次AES加密之后得到params的值

encText = AESencrypt(enctext, i)

# RSA加密之后得到encSecKey的值

encSecKey = RSAencrypt(i, e, f)

returnencText, encSecKey

获取全部评论

上面我们获取到了两个参数encText和encSecKey,利用这两个参数来构造post表单数据(Form Data),即data的值:

params, encSecKey = get_params(page)

data = {'params': params, 'encSecKey': encSecKey}

歌曲评论的URL为:

url= 'https://music.163.com/weapi/v1/resource/comments/R_SO_4_'+ str(songid) + '?csrf_token='

然后把data加到post的参数中去就能获取到json格式的评论数据。

html= requests.post(url, headers=headers, data=data)

至此,获取网易云音乐全部评论的Python爬虫实现原理分析全部完成!

作者:志颖,一名狂热的python爬虫爱好者。

本文系作者投稿,不代表CSDN立场。

征稿啦”

责任编辑:

python爬虫网易云音乐评论再分析_爬取网易云音乐的评论后,竟有这种发现!相关推荐

  1. python爬虫网易云音乐评论再分析_Scrapy爬取网易云音乐和评论(一、思路分析)...

    目录: 前提: scrapy这个框架很多人用过,网上教程也很多,但大多就是爬爬小说这种比较简单且有规律的.尤其大多网站它是可以通过点击下一页的方式爬取下一页,我看到的教程也都是这样的.而网易云的按钮光 ...

  2. python爬虫系列(2):分析Ajax 爬取搜狗高清壁纸

    这次我们来分析一下Ajax(至于Ajax是什么意思请自行百度了,这里就不过多解释),爬取一些高清壁纸,等待下载到本地之后,然后我们再慢慢的筛选这些壁纸.那么这次的目标就是搜狗壁纸,啥1280*720的 ...

  3. python爬取酷狗音乐的mv地址_爬取酷狗音乐.py

    import requests from selenium import webdriver from pyquery import PyQuery as pq #获取歌名 def Access_to ...

  4. Python爬虫: 单网页 所有静态网页 动态网页爬取

    Python爬虫: 单网页 所有静态网页 动态网页爬取 前言:所有页代码主干均来自网上!!!感谢大佬们. 其实我对爬虫还挺感兴趣的,因为我玩instagram(需要科学上网),上过IG的人都知道IG虽 ...

  5. Python爬虫新手入门教学(十七):爬取yy全站小视频

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

  6. python爬虫实战之图灵社区图书信息的爬取(找了久,才找到一个比较好爬取的网站)

    python爬虫实战之图灵社区图书信息的爬取 程序的描述 目标 获取图灵社区(https://www.ituring.com.cn/book)中40本图书的书名 将获取的信息以列表的形式输出到屏幕上, ...

  7. python怎么爬取b站_【Python爬虫实例学习篇】——4、超详细爬取bilibili视频

    [Python爬虫实例学习篇]--4.超详细爬取bilibili视频 由于经常在B站上学习,但无奈于家里网络太差,在线观看卡顿严重,于是萌生了下载视频的想法(如果只是单纯想下载视频,请用you-get ...

  8. Python爬虫新手入门教学(十):爬取彼岸4K超清壁纸

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

  9. Python爬虫新手入门教学(十三):爬取高质量超清壁纸

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. Python爬虫.数据分析.网站开发等案例教程视频免费在线观看 https://space. ...

最新文章

  1. npm install遇到ENOENT: no such file or directory, rename错误
  2. Http与RPC通信协议的比较
  3. mysql root的密码忘了?linux下重置mysql的root用户密码。
  4. 消除文法中一切左递归算法
  5. [转载]中国公历算法
  6. 字符串-长度、计数、位置方法演练
  7. Servlet的运行方式
  8. 将区块链哈希转化为文字标题?IPSE哈希技术Hashlink解释
  9. 用python做tkinter_Python下用Tkinter进行GUI编程
  10. 即将步入2020年,程序员如何在新的一年更进一步?你需要这样做
  11. Java中使用JNI调用本地动态库的方法
  12. 图片复印如何去除黑底_身份证复印机中间有黑线怎么办
  13. 计算机与计算机视觉史话
  14. mybatis-注解及其他
  15. 通俗理解路由器和交换机的区别?
  16. 143120-27-8,CYCLO(-D-TYR-ARG-GLY-ASP-CYS (CARBOXYMETHYL)-OH) SULFOXIDE
  17. 统一网络存储NAS+SAN=FAS
  18. 1_requests请求
  19. 格式工厂怎么将qlv转换成mp4 转换方法最新
  20. 总结几点学习模电难的原因

热门文章

  1. oracle数据库工龄计算公式,Oracle 查询练习
  2. Win11自动删除文件设置方法
  3. 进阶C语言:指针笔试题
  4. 免费虚拟服务器多开软件,云服务器多开模拟器
  5. Mybatis缓存 自定义缓存
  6. exfat linux 编译,嵌入式 linux 基于fuse 的 exfat 文件系统实现
  7. 【动态 | 哈希未来获得节点资本战略投资】
  8. 谨以此文祭奠我第一次赤条条的裸面,全裸那种。。
  9. pc酷狗网页最简洁代码2023最新
  10. el-form 表单 手机号 验证