记一次爬虫之网抑云js解密
爬取目标:网易云热评
工具:浏览器开发者工具
浏览器开发者工具简单介绍
2022-01-16-10-07-46.png
- 元素(Elements):用于查看或修改HTML元素的属性、CSS属性、监听事件、断点等。css可以即时修改,即时显示。大大方便了开发者调试页面
- 控制台(Console):控制台一般用于执行一次性代码,查看JavaScript对象,查看调试日志信息或异常信息。还可以当作Javascript API查看用。例如我想查看console都有哪些方法和属性,我可以直接在Console中输入"console"并执行~
- 源代码(Sources):该页面用于查看页面的HTML文件源代码、JavaScript源代码、CSS源代码,此外最重要的是可以调试JavaScript源代码,可以给JS代码添加断点等。
- 网络(Network):网络页面主要用于查看header等与网络连接相关的信息。
这次调试主要用到network模块,这里再具体介绍一下这个模块
- Preserve log记录所有的请求事件,即当刷新后上次的请求不会消失。
XHR
XHR全称XMLHttpRequestXMLHTTP是一组API函数集,可被JavaScript、JScript、VBScript以及其它web浏览器内嵌的脚本语言调用,通过HTTP在浏览器和web服务器之间收发XML或其它数据。XMLHTTP最大的好处在于可以动态地更新网页,它无需重新从服务器读取整个网页,也不需要安装额外的插件。该技术被许多网站使用,以实现快速响应的动态网页应用。
上手实操
- 通过网页源代码查看不到热评的任何信息,然后通过抓包一条条分析请求信息。然后可以看到了一个请求的返回包中包含了热评的JSON信息
- 查看请求头信息,这是爬虫的关键信息
请求的URL:
post请求参数:
- 查看请求时的调用栈,Initiator:发送请求的对象,主要包含Parser和Script
这个就是所有的请求过程,是从下往上进行的。即最上面的是最后请求的调用。
- 点击进入最后一个调用
将代码格式化好后,查看到敏感的一条一句,send(data),点击1处将其设置一个断点,然后展开右边的scope临时变量中的request,查看请求的URL是否为需要的URL,若不是,则点击1处,继续运行到URL为获取评论的URL处即可。
- 继续查看对应URL处的调用过程。然后观察右边的变量过程,直到发现了非加密的参数为止
如图,我们就可以发现参数已经没有加密了,至于这些参数为什么是这些就要去猜测分析了。那便可以肯定的是加密参数的过程就在t2x这个调用中。仔细去分析这个调用过程即可。
- 很明显,可以看到两个变量一个是加密的,一个未加密。更加验证了加密是在这个请求的想法。
- 搜索其中一个加密参数,查看出现在程序的那个地方
可以看到加密过程就是这个window...,再次搜索这个
可以得到最终的加密函数
!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
}();
分析加密过程及相关函数
- 参数分析
var bVj1x = window.asrsea(JSON.stringify(i2x), bsP6J(["流泪", "强"]), bsP6J(Xk0x.md), bsP6J(["爱心", "女孩", "惊恐", "大笑"]));
window.asrsea = d,
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
}
//name就是看这个d函数的执行过程,
//先看传递的参数,
d=i2x={
csrf_token: ""
cursor: "-1"
offset: "0"
orderType: "1"
pageNo: "1"
pageSize: "20"
rid: "R_SO_4_1891469546"
threadId: "R_SO_4_189146"
}
//其他参数就是直接将该函数在控制台运行得到结果即可
e='010001'
f='00e0...很长'
g='0CoJUm6Qyw8W8jud'
//
- i = a(16);这里执行了a函数
function a(a) { //a=16
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 //返回一个随机的16位字符串仅含字母和数字
}
那么就可以使用断点工具,直接使用其中一次的随机字符串即可,可以得到i="4lw8juWopBOnGy23"
- encText使用b函数加密了两次
第一次:encText=b(d, g)
第二次:b(encText,i)
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()
//第一个参数就是JSON数据data。第二个参数也是已知的。
这是个AES加密,第一个参数是e,就是明文数据即data。
第二个参数是c,是秘钥。即b函数的第二个参数,然后有个偏移量d,加密模式是CBC
- encSecKey使用c函数加密了一次
encSecKey = c(i, e, f)
function c(a, b, c) { //i是随机字符串已知且固定,e ,f也已知且固定。
var d, e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d, a)
}
因此这里如果把i固定,那么得到的key也是一定的。
那么便要断点调试,在得到i的时候继续运行以查看key。这个i必须是和key对应的,因为这个i也用于作为data加密的秘钥
python中还原加密过程,使其对应的URL能够接收到正确的参数。
- 先确定encSecKey。由于只要i固定,则key固定。则可以利用浏览器进行断点调试并且单步跳过综合得出i和key
如图,在i后加上断点,接着能在右边的临时变量中得到i值,然后单步跳过得到key值。
- encText的话就是使用python中Crypto.Cipher的AES模块,先创建一个加密器,里面设置好上文所提及的相应秘钥,偏移量,加密方式等。
def enc_params(data, key):
iv = "偏移量"
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") # 转化成字符串返回,
全文到这里差不多就结束了,先挖个坑。听说网易的加密方式都是一个套路,后续打算再看看别的接口,如歌词,甚至歌曲等,敬请看下回分析。
版权声明:本文为原创文章,版权归 Bill's Blog 所有,转载请注明出处!如相关链接出现404,可以在文章下面评论留言。