这是本站的第一篇博客,可能会有很多补不足的地方,后面会持续修改,希望各位看官积极指出错误
1. 准备工具:
- pychram
- vscode(测试javascrip)
- node.js
- 任意浏览器(推荐谷歌或者Edge)
做好这些后要保证电脑上能运行python和Javascript
2. 知识储备:
- python对网页请求过程
- 可以忽略的少量JS语法基础
3. 开始进行网页分析
网址:https://music.163.com/#/discover/toplist?id=3778678(这是网易云热歌榜的评论爬取,网易云的无论是音乐还是评论还是其他的,加密代码都是一样的,仅以此为代表,可以稍加修改爬取不同内容)
进入网站,然后直接F12,然后点击网络,再点刷新,点击只查看Fetch/XHR,如下图所示:
接着通过 预览 查看文件的内容,定位到其中这个 get… 文件 ,,如图:
再查看标头,看里面的请求标头,嗯。。。。。都是正常参数,没有疑似加密的参数
还没完,请求标头中告诉我们,这是一个 POST 请求,所以继续查看提供的表单数据
点击 payload
payload 里面有连个参数,分别是params和encSecKey,一看就知道这是加密参数,既然如此我们进入他的发起程序找到加密位置进行破解
点击进入发起程序 如图:
先点击进入第一个,点击左下角的 { } 对代码增加可读性,然后对代码中蓝色条所在一行打上断点,
重复,对前五个都进行相同 *** 作。
点击刷新,观察出现的提示参数,如图:
发现我们的需要的加密参数在这里,接下来观察如何生成的,如上图,我们注意 bum2x 这个参数,我们的加密参数都来自这个 bum2x ,在上图 13413 这一行当中,生成的方式是
var bUM2x = window.asrsea(JSON.stringify(i6c), bsG7z(["流泪", "强"]), bsG7z(WW3x.md), bsG7z(["爱心", "女孩", "惊恐", "大笑"]));
我们将这行代码分解:
加密函数: window.asrsea() 函数的参数: JSON.stringify(i6c) bsG7z(["流泪", "强"]) bsG7z(WW3x.md) bsG7z(["爱心", "女孩", "惊恐", "大笑"])
先不管这四个参数,我们先看是函数如何加密的,如果简单就用Python重写,太复杂了就直接扣代码,做成JS脚本用Python的execjs包运行,在控制台输入window.asrsea()后直接给出了函数位置,直接进入查看,也可以把鼠标放在window.asrsea上,会自动给出函数位置,点击进入即可,如图
进入后发现该函数其实是一个叫**d(d, e, f, g)**的函数,具体加密逻辑如下:
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 }
我们来分析一下函数实现过程:
- 函数里面有a(), b(),c(),三个未知函数
- 加密过程:i =a(16),h.encText经历了两次b() 函数, h.encSecKey经历了一次c函数。
现在就需要将没有的函数找到用上文的方法,将鼠标放到函数上,可以自动显示位置
这里我们找到了a(),b(),c()函数的加密:
发现了什么,b(),c()里面还有不认识的函数,这样的情况,我们就不能再挨着分析去用python还原函数, 我们可以利用另一个办法,将加密的js代码扣下来放到 js 文件里面,通过执行这个js文件获得加密参数, 这里就需要你的电脑有javascript的执行环境: node.js和VScode来做javascript的编译器,具体配置可以百度,这里不多做解释,我们将扣下来的js代码放入一个粘贴:
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 }
然后,在末尾加上一个执行函数run():
function run(){ dd='' e='' f='' g='' d1=d(dd,e,f,g); data={ params: d1.encText, encSecKey:d1.encSecKey } console.log(data); } run()
然后我们执行一下
Uncaught ReferenceError: CryptoJS is not defined
不出意外出错了,CryptoJS这个函数没有找到,在b()函数中调用了这个函数,则其实是一个外部包引入的函数,需要我们导入,全文也只有这CryptoJS函数需要外部导入,其他的都在文中可以复制得到,我们导入一下:
npm install crypto-js//在终端输入
导入之后,还要再js文章中引入:
CryptoJS=require('crypto-js')
再运行一下:
setMaxDigits is not defined
正常情况,我们回到浏览器,这setMaxDigits()函数在c()里面我们将鼠标放在函数上,按照之前的方法到函数所在的位置,将代码扣下来,粘贴直接,然后缺什么函数就去浏览器位置,找到这个函数然后粘贴过来,这里有个小技巧 :后面代码变多,遇到报错未定义函数时可用ctrl+f 查找函数在哪个函数里面被引用了,再浏览器找 比如:
biToHex is not defined
然后有几百行代码,
我们可以直接ctrl+f:
然后去浏览器,找到这个encryptedString(a, b)函数,然后利用之前的方法定位到函数位置,扣代码,粘贴,
最后大概到370多行代码的时候,成功运行,这里只是成功运行,但是没有输出任何东西,为什么??
我们回到run() 函数,这个函数里面我们放入的参数dd,e,f,g,都是空的,我们接下来需要找到参数具体值
function run(){ dd='' e='' f='' g='' d1=d(dd,e,f,g); data={ params: d1.encText, encSecKey:d1.encSecKey } console.log(data); } run()
还知道我们怎么找到d() 函数的吗
d1=d(dd,e,f,g);
是通过这个:
然后放入里面的参数我们可以通过控制台找到,将四个参数扣下来,
这里还有一个坑,我们看 网络 这块,
什么都没有,所以我们不知道是加载的哪个文件的加密参数,
这里除了batch都有加密参数,我们需要一个一个获得参数,再和文件相对应:
照这样,每个对应起来,还可以发现,只有第一个dd参数发生改变,其他三个是不变的
我们找到我们爬取文件的dd:
"{"rid":"A_PL_0_3778678","threadId":"A_PL_0_3778678","pageNo":"1","pageSize":"20","cursor":"-1","offset":"0","orderType":"1","csrf_token":""}"
然后带入到run()代码中
成功获得加密参数。还有后续文章,请持续关注,谢谢啦,我还是爬虫小白,有表述错误,还请大佬指出,如果对你有帮助还请点一个赞哦,如果文章对你造成了影响,请及时通知,马上修改,个人博客同时发表:点击进入
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)