本文已参与「新人创作礼」活动,一起开启掘金创作之路。
其实学爬虫除了采集数据用于学习外,另外一个就是纯爱好而已,今天看了一个不错的视频,内容是如何抓取一些歌曲的评论信息,感觉挺有意思的,想写一篇博客记录一下,以防后面自己想要数据时方便抓取。代码不是很难,难的是一个逆向的分析过程,先把代码放上吧,然后一步步的分析如何逆向破解加密过程。
# 抓取网易云音乐评论
from Crypto.Cipher import AES
from base64 import b64encode
import requests
import json
# 抓取的目标URL
url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="
# 通过网页分析网易的数据加密过程,找到参数信息
data = {
"csrf_token": "",
"cursor": "-1",
"offset": "0",
"orderType": "1",
"pageNo": "1",
"pageSize": "20",
"rid": "R_SO_4_1940362135",
"threadId": "R_SO_4_1940362135"
}
e = "010001"
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
g = "0CoJUm6Qyw8W8jud"
i = "eFl3gmUhVFqEAfhf"
# 定死i产生的结果
def get_encSecKey():
return "2823d70e279ea80f888079ce2872ee577f7ca4c9498911f9a0b6e6d6a2ba24b50df19acf8a0786e5570d8515014a10159f3e61efc85edba6c863be272d87b9ea18393256e44df031d243416999b9d442814b6eed98ee7a0fcfdd5960efdd54bdc0bae2c773407d3e883163339ff6d8a73d5d95d27dde633a3c533998fab9ade4"
# 通过模拟加密过程得到params
def get_params(data):
h = en_params(data, g)
params = en_params(h, i)
return params
# 将数据拼凑成规定的16位格式
def data_to_16(data):
pdata = 16 - len(data) % 16
data += chr(pdata) * pdata
return data
# 模拟加密过程
def en_params(data, key):
iv = "0102030405060708"
en_data = AES.new(key=key.encode('utf-8'), IV=iv.encode('utf-8'), mode=AES.MODE_CBC)
res = en_data.encrypt(data_to_16(data).encode('utf-8')) # 加密内容长度必须是16的倍数
return str(b64encode(res), "utf-8")
# 拿到网页信息
restest = requests.post(url,
data={
"params":get_params(json.dumps(data)),
"encSecKey":get_encSecKey()
}
)
print(restest.text)
# 破解加密过程
# 加密的入口为d
# 第一个参数:i1x就是data数据,第二个参数:010001,第三个参数:00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7,第四个参数:0CoJUm6Qyw8W8jud
# var bKB5G = window.asrsea(JSON.stringify(i1x), buV2x(["流泪", "强"]), buV2x(Rg6a.md), buV2x(["爱心", "女孩", "惊恐", "大笑"]));
'''
function a(a) {
var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
for (d = 0; a > d; d += 1) #循环d次
e = Math.random() * b.length, #取随机数
e = Math.floor(e), #取整
c += b.charAt(e); #按照e的数字取b中的字符位置
return c #返回一个长度为16的字符串
}
# 网上可以搜索的到加密函数
function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(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()
}
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), g和i都是作为加密的密钥传递进去
h.encText = b(h.encText, i), #得到的就是params,经历了两次加密,第一次,将d和g放入b加密得到h,然后将h和i放入b再次加密得到params
h.encSecKey = c(i, e, f), #得到的就是encSeckey,e和f都是定值,变化取决与i,而i是一个随机值,我们可以定死i作为随机产生的一个值
h
}
'''
下面直接上分析过程
首先打开网页,随便找一首歌曲点进去都可以,界面如下
在界面上点击F12,查看网页源代码
按照上面的图示依次点击,我们会得到下面的结果,因为我们需要的是get请求,如框选区域所示,所以我们找到get请求,点击get
点击了之后结果如下,分析一下headers里面的url。一看这个url它就不正经,为啥这么说呢,之前写过爬虫的都知道,这个url它看起来不完整啊,后面明显还有缺失值,缺失的部分如下面第二张图片所示,不过不要紧,要是那么容易对网站也不是好事,下面继续分析
接下来就时开始分析加密过程了
点击箭头所示的链接,将会进入到下面的界面。
看起来乱糟糟的,点击箭头所示,代码将会变为我们喜欢的样子了。
下面就是通过断点调试,找到加密的位置,然后分析加密过程,拼凑参数完成浏览器的请求。
关于断点调试的后面没有截屏了,主要原因是浏览器太卡一直加载不出来,对于整个分析过程写到了代码里面,详细见代码的分析过程。