查看源代码
找到目标url
有两个参数被加密了
search 加密参数params:
可以看出这是一个加密函数,并传递了4个参数.
第一个参数是url的参数,其他参数都是定值.
第一个参数
data={
"rid": "R_SO_4_26305527",
"threadId": "R_SO_4_26305527"}
windows.asrsea()的处理过程
!function() {
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,
window.ecnonasr = e
}();
通过读a函数,我们发现a函数是生成一个a(传进来的参数)位的字符串,也就是说d中的i将会是一个随机数
我们可以让页面继续运行,然后得到i和对应的h.encSecKey这样我们就可以在python中将这两个变量写死。
得到i和encSecKey:
i="gcbRwuLzJcbzxAPC"
def get_ensSecKey():
return "24caa54f2cccf556753a02162ae1f2c37d9ae4af3289e9b773100a3c2d284b94232ac513680119fdb38b3551f18f1e6bb6fd00d49507502da30df2e0d361e01c702be2dd4b31a97a25e95f00e2cdd5663a6ba0e6b328dd073d1c5e1b2a0278accce59c3645065ef1f61e965ef505e8f9842e8f1e0680242e511b8fc37aadc522"
看b函数可以看出是AES加密CBC模式
模拟b函数获得 params参数
from Cryptodome.Cipher import AES
import json
from base64 import b64encode
import requests
# 第一个参数
data={
"rid": "R_SO_4_26305527",
"threadId": "R_SO_4_26305527"}
# 第二个参数
e = '010001'
# 第三个参数
f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
# 第四个参数
g = '0CoJUm6Qyw8W8jud'
i="gcbRwuLzJcbzxAPC"
def get_ensSecKey():
return "24caa54f2cccf556753a02162ae1f2c37d9ae4af3289e9b773100a3c2d284b94232ac513680119fdb38b3551f18f1e6bb6fd00d49507502da30df2e0d361e01c702be2dd4b31a97a25e95f00e2cdd5663a6ba0e6b328dd073d1c5e1b2a0278accce59c3645065ef1f61e965ef505e8f9842e8f1e0680242e511b8fc37aadc522"
def get_params(data):
first=enc_params(data,g); #d中的第一次加密
secend=enc_params(first,i);#d中的第二次加密
return secend;
def to_16(data):
pad=16-len(data)%16;
data+=chr(pad)*pad
return data
#模拟加密过程
def enc_params(data,key):
#key 密钥, iv=偏移量,# AES.MODE_CBC 表示模式是CBC模式
aes = AES.new(key=key.encode('utf-8'),iv="0102030405060708".encode('utf-8'),mode=AES.MODE_CBC)
data = to_16(data)#需要加密的内容
bs = aes.encrypt(data.encode('utf-8')) #加密内容,加密的内容长度必须是16的倍数
return str(b64encode(bs),"utf-8")#加密后得到字节数据,以base64编码方式解码, 得到加密字符串!
爬取评论内容
url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token='
resp = requests.post(url, data={
"params": get_params(json.dumps(data)),
"encSecKey": get_ensSecKey()
})
resp.encoding = 'utf-8'
dic = resp.json();
comments = dic['data']['hotComments']
for comment in comments:
content = comment['content']
print(content)