Python 网易云音乐评论爬虫

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AmazingUU/article/details/83832213

引言

之前网易云音乐和农夫山泉合作,将热门评论印在农夫山泉上引爆了朋友圈。于是想爬取一下网易云的评论。网上搜了一下,对于网易云评论的爬虫不少,主要参考这篇文章:对网易云音乐参数(params,encSecKey)的分析 。在此基础上,添加了爬取云音乐飙升榜中歌曲,再去爬取这些歌曲的评论。在做项目的过程中还是遇到了一些问题,在此记录下来

思路

  1. 爬取云音乐飙升榜中的歌曲相关信息
  2. 爬取对应歌曲的热门评论
  3. 爬取对应歌曲的前20条最新评论

问题

1. 云音乐飙升榜中歌曲信息是JS动态生成,直接爬取拿不到

最开始是想从界面上爬取数据,但是发现榜单歌曲是JS动态生成的,需要分析JS代码后才能获取。Google后发现网易云有提供现成的接口api,直接可以用,返回的是JSON格式数据,省去分析JS的过程了。

# 排行榜api,本项目爬取云音乐飙升榜
# http://music.163.com/api/playlist/detail?id=2884035 # 网易原创歌曲榜
# http://music.163.com/api/playlist/detail?id=19723756 # 云音乐飙升榜
# http://music.163.com/api/playlist/detail?id=3778678 # 云音乐热歌榜
# http://music.163.com/api/playlist/detail?id=3779629 # 云音乐新歌榜
# 歌单api
# http://music.163.com/api/playlist/detail?id=123415635 # 云音乐歌单——【华语】中国风的韵律,中国人的印记
# http://music.163.com/api/playlist/detail?id=122732380 # 云音乐歌单——那不是爱,只是寂寞说的谎

2. Fiddler的代理问题

利用Fiddler在线调试的时候,直接在Chrome中刷新,发现没有抓取到core.js。
没有core.js
查找资料,发现虽然Fiddler安装好就能用,但是抓的HTTPS过程不全,还需要在Chrome中配置一下。
配置方法:Fiddler Chrome配置和抓包
在SwitchyOmega插件中切换为Fiddler代理后,还需要注意的是,不能直接刷新界面,这样Fiddler还是抓不到,要点击SwitchyOmega中设置的代理,通过这种方式刷新界面,Fiddler就能抓到core.js了。
有core.js
同样使用Fiddler的AutoResponder时,将浏览器JS替换为本地JS,也要用这种方式刷新界面,consloe中才会有日志输出

3. 将网易云JS中加密方法转为Python实现遇到的问题

原文中对于第二个参数encSecKey固定为同一个值,虽然可以拿到返回的数据,但是不知道用固定值爬取的数据多了,会不会直接给我IP封掉,所以还是用Python实现了encSecKey值的获取方法,代码如下:

def RSA_encrypt(n_str, e_str, random_str):  # RSA加密
    n = int(n_str, 16)  # RSA modulus,RSA算法中大素数相乘的结果,16进制
    e = int(e_str, 16)  # RSA算法中的e,和n一起组成公钥(n,e),16进制
    cryptor = RSA.construct((n, e))  # 构造加密器
    # 网易云JS中的encryptedString()将16位随机字符串倒序了,所以要生成与JS一样的密文,这里也要倒序,而且下面加密时,要求为字节,所以编码为ascii码
    text = random_str[::-1].encode('ascii')
    encrypt_text = cryptor.encrypt(text, '')[0]  # 网易云JS中第二个参数为空,这里也为空。查看encrypt()源码发现会返回两个值,第一个是密文,第二个值总为空
    encrypt_text = binascii.b2a_hex(encrypt_text).decode('utf-8')  # encrypt_text为二进制,转为十六进制然后再解码成字符串才是最后要post的密文
    return encrypt_text
    
def get_encSecKey(random_str, second_params, third_params):  # 产生POST的第二个参数
    encSecKey = RSA_encrypt(third_params, second_params, random_str)
    return encSecKey

这里用的是RSA加密,需要注意的是网易云JS中将输入的16位随机字符串倒序了,所以这里在加密之前也要将其倒序,并且转为byte类型。
获取第一个参数params时用的是AES加密,网易云JS中采用了两次加密,第二次加密直接对第一次加密结果进行加密,但在Python中第一次加密之后的结果为byte类型,第二次加密之前需要将其转为String类型,否则会报TypeError: can’t concat str to bytes,代码如下:

def AES_encrypt(text, key):  # AES加密
    iv = '0102030405060708'
    pad = 16 - (len(text) % 16)  # 明文补足为16的倍数,如果正好是16的倍数,再补16位
    text += pad * chr(pad)  # chr()返回对应数值的ascii码,如果少一位,补充一个数值1对应的ascii,如果少两位,补充两个数字2对应的ascii,以此类推
    encryptor = AES.new(key, AES.MODE_CBC, iv)  # key为密钥,iv为初始偏移量
    encrypt_text = encryptor.encrypt(text)  # 加密
    encrypt_text = base64.b64encode(encrypt_text)  # 二级制编码,用64个字符来表示任意二进制数据
    return encrypt_text
    
def get_params(first_param, forth_param, random_str):  # 产生POST的第一个参数
    encText = AES_encrypt(first_param, forth_param).decode('utf-8')  # AES加密出来是byte类型,再次加密时需要先将其转为String
    params = AES_encrypt(encText, random_str)
    return params

总结

本项目主要的时间花费在分析网易云音乐的JS源码上,搞清楚了JS源码是怎么请求数据的,后面爬虫就很顺利了,后面有时间还是要学一学JS,对于提高爬虫效率有很大的帮助。

项目地址

网易云音乐评论爬虫
上面是项目地址,觉得还可以的话,给个star哦

参考资料

对网易云音乐参数(params,encSecKey)的分析

解析网易云音乐的加密方式

python3.x爬取网易云音乐,超详细版

python爬虫实例–网易云音乐排行榜爬虫

猜你喜欢

转载自blog.csdn.net/AmazingUU/article/details/83832213