获取网易云音乐评论

首先分析可以得到网易云音乐的评论不是在网页源代码中存储的,而是通过ajax异步请求得到的数据,浏览器开启F12,刷新网页,发现这个请求返回的数据就是我们想找到的评论数据。
在这里插入图片描述
但是查看其请求头却发现,请求的参数是加密过的,那么如何找到这个加密方法呢?
在这里插入图片描述
在这里插入图片描述
通过查看Initiator我们可以定位到发起这个请求的js文件
在这里插入图片描述

在这里插入图片描述
然后我们在这行打上断点,刷新界面,观察变量的值,我们发现这个值已经被加密处理过来,然后我们查看函数调用的堆栈,一个一个的分析,找到被加密的地方。
在这里插入图片描述
然后找到了加密的地方
在这里插入图片描述
其实window.asrsea就是函数d

function a(a) {
        var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
        for (d = 0; a > d; d += 1)
            e = Math.random() * b.length,
            e = Math.floor(e),
            c += b.charAt(e);
        return c
    }
    function b(a, b) {
        var c = 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
        });
        return f.toString()
    }
    function c(a, b, c) {
        var d, e;
        return setMaxDigits(131),
        d = new RSAKeyPair(b,"",c),
        e = encryptedString(d, a)
    }
    function d(d, e, f, g) {
        var h = {}
          , i = a(16);
        return h.encText = b(d, g),
        h.encText = b(h.encText, i),
        h.encSecKey = c(i, e, f),
        h
    }
    function e(a, b, d, e) {
        var f = {};
        return f.encText = c(a + e, b, d),
        f
    }
    window.asrsea = d,

那么这个时候我们已经知道加密的js代码了,此时只需将这段js代码用python来实现即可。我们首先来看函数d的参数,第一个参数d是将i9b这个变量转成json的字符串,因此我们在python中定义同样的变量即可。

i9b = {
    "csrf_token": "",
	"cursor": "-1",
	"offset": "0",
	"orderType": "1",
	"pageNo": "1",
	"pageSize": "20",
	"rid": "R_SO_4_1901371647",
	"threadId": "R_SO_4_1901371647"
}

第二个参数e,传入的是bsP6J(["流泪", "强"])bsP6J是一个函数

		var bsP6J = function(cxG5L) {
        var m9d = [];
        j9a.bg9X(cxG5L, function(cxF5K) {
            m9d.push(Xk6e.emj[cxF5K])
        });
        return m9d.join("")
    };

我们直接打开浏览器的Console面板,运行这个语句,发现得到的值都是一样的,即字符串"010001"。那我们就声明e = "010001"
在这里插入图片描述
按照此方法可以得到

f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
g = "0CoJUm6Qyw8W8jud"

至此,d函数的参数已经全部确定。
接下来,我们先看函数d中的h.encSecKey的值是如何确定的, h.encSecKey = c(i, e, f),其中的i是由函数函数a返回的,查看函数a的代码可以发现其功能就是返回一个长度为16的字符串,但是是随机的,每次返回的结果是不一样的,由此我们可以得出,在c函数中,这个变量i的值每次都不一样,而e和f的值又是确定的,所以我们只要固定i是固定的,那么c函数返回的值也是固定的,所以我们直接取一次运行的i值,代入函数c中,得到的encSecText作为我们的参数即可。改写成python代码如下:

#随便取一次调试的值即可 
def get_encSecKey():  # 由于i是固定的. 那么encSecText就是固定的.  c()函数的结果就是固定的
    return "1b5c4ad466aabcfb713940efed0c99a1030bce2456462c73d8383c60e751b069c24f82e60386186d4413e9d7f7a9c7cf89fb06e40e52f28b84b8786b476738a12b81ac60a3ff70e00b085c886a6600c012b61dbf418af84eb0be5b735988addafbd7221903c44d027b2696f1cd50c49917e515398bcc6080233c71142d226ebb"

接下来我们分析h.encText是如何得到的,先看函数b

function b(a, b) {  # a是要加密的内容, 
        var c = CryptoJS.enc.Utf8.parse(b) #  # b是秘钥
          , d = CryptoJS.enc.Utf8.parse("0102030405060708")
          , e = CryptoJS.enc.Utf8.parse(a)  # e是数据
          , f = CryptoJS.AES.encrypt(e, c, {  # c 加密的秘钥
            iv: d,  # 偏移量
            mode: CryptoJS.mode.CBC  # 模式: cbc
        });
        return f.toString()
    }
h.encText = b(d, g)  # g秘钥
h.encText = b(h.encText, i)  # 返回的就是params  i也是秘钥

就是将内容进行了两次加密,两次使用的密钥不一样,第二次加密的内容就是第一次加密返回的结果作为参数传入。而b函数查看代码也看出了这个是AES加密,而python中也存在同样的包,对此,可以将加密方法改装成python代码。

# 把参数进行加密
def get_params(data):  # 默认这里接收到的是字符串
    first = enc_params(data, g)
    second = enc_params(first, i)
    return second  # 返回的就是params

# 加密过程
def enc_params(data, key):
    iv = "0102030405060708"
    data = to_16(data)
    aes = AES.new(key=key.encode("utf-8"), IV=iv.encode('utf-8'), mode=AES.MODE_CBC)  # 创建加密器
    bs = aes.encrypt(data.encode("utf-8"))  # 加密, 加密的内容的长度必须是16的倍数
    return str(b64encode(bs), "utf-8")  # 转化成字符串返回,

# 转化成16的倍数, 为下方的加密算法服务
def to_16(data):
    pad = 16 - len(data) % 16
    data += chr(pad) * pad
    return data

所有代码如下

# 需要安装pycrypto:   pip install pycrypto
#coding = utf-8
from Crypto.Cipher import AES
from base64 import b64encode
import requests
import json

url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="

# 请求方式是POST
i9b = {
    "csrf_token": "",
	"cursor": "-1",
	"offset": "0",
	"orderType": "1",
	"pageNo": "1",
	"pageSize": "20",
	"rid": "R_SO_4_1901371647",
	"threadId": "R_SO_4_1901371647"
}

# 服务于d的
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
g = "0CoJUm6Qyw8W8jud"
e = "010001"
i = "d5bpgMn9byrHNtAh"  # 手动固定的. -> 人家函数中是随机的

def get_encSecKey():  # 由于i是固定的. 那么encSecText就是固定的.  c()函数的结果就是固定的
    return "1b5c4ad466aabcfb713940efed0c99a1030bce2456462c73d8383c60e751b069c24f82e60386186d4413e9d7f7a9c7cf89fb06e40e52f28b84b8786b476738a12b81ac60a3ff70e00b085c886a6600c012b61dbf418af84eb0be5b735988addafbd7221903c44d027b2696f1cd50c49917e515398bcc6080233c71142d226ebb"


# 把参数进行加密
def get_params(data):  # 默认这里接收到的是字符串
    first = enc_params(data, g)
    second = enc_params(first, i)
    return second  # 返回的就是params


# 转化成16的倍数, 位下方的加密算法服务
def to_16(data):
    pad = 16 - len(data) % 16
    data += chr(pad) * pad
    return data


# 加密过程
def enc_params(data, key):
    iv = "0102030405060708"
    data = to_16(data)
    aes = AES.new(key=key.encode("utf-8"), IV=iv.encode('utf-8'), mode=AES.MODE_CBC)  # 创建加密器
    bs = aes.encrypt(data.encode("utf-8"))  # 加密, 加密的内容的长度必须是16的倍数
    return str(b64encode(bs), "utf-8")  # 转化成字符串返回,
    
# 发送请求. 得到评论结果
resp = requests.post(url, data={
    "params": get_params(json.dumps(i9b)),
    "encSecKey": get_encSecKey()
})

print(resp.text)

结果如下:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值