- 首先打开网易云音乐,第一步,先看翻页逻辑,因为比较高端的反爬多半都是AJAX异步为主的,果然,评论第二页跟第一页的地址是一样的。AJAX中根据async的值不同分为同步(async = false)和异步(async = true)默认情况下async是true。同步请求即是当前发出请求后,浏览器什么都不能做,必须得等到请求完成返回数据之后,才会执行后续的代码。也就是当JS代码加载到当前AJAX的时候会把页面里所有的代码停止加载,当这个AJAX执行完毕后才会继续运行其他代码。异步请求就当发出请求的同时,浏览器可以继续做任何事,Ajax发送请求并不会影响页面的加载与用户的操作,相当于各走各的,互不影响。
- 先试试能不能拿到数据,比如request的response,会发现,评论数据不在网页里。request对象是服务器对浏览器请求的封装,而response是服务器对服务器响应的封装。request用来取出请求信息,而response则用来添加要返回给浏览器的信息。
- 那么数据在哪呢?现在我们打开chrome浏览器按F12,点进Network->XHR->Preview,刷新抓包一下网页会发现,数据在XHR里面。直接调用这个API接口,返回了空白页面。再来分析这个数据是怎么请求的,切到headers页面,会发现,这是一个post请求,传入了两个参数,一个是params,一个是encSecKey。先试试,直接传入这两个参数,模仿post请求,是否能得到数据呢?答案是可以的。再来看看,下一页的params和encSecKey明显不一样。所以我们现在已经明确了问题,如果我们要实现真正的爬取页面,那么其实就是破解这两个参数。
- 我们所看到的页面,并不是远程服务器加载好再给我们呈现出来的,而是就像正常的下载文件一样。把服务的js文件下载下来,然后在本地浏览器执行。先找到之前抓包文件的Initiator,直接打开这个JS文件,复制,然后再在python里创建JS文件,然后粘贴,然后格式化。再搜索关键字,params和encSecKey。
- 当搜索params的时候,会搜出37个matches。enSecKey有3个。里面的JS函数是难以阅读的形式,所以从简单的地方入手。这里,切入点就是enSecKey,因为无论在里面如何修改,最终出口一定是含有params和enSecKey名字的参数,我们切到下面这个enSecKey位置,有个data关键字,里面正好是params,和enSecKey。很大概率,这是这两个函数的出口,往上面看一下,这是由v9m.be9V这个函数加载的,切回去刚刚那个找JS的地方看,阅读这个JS,params和encText都是由bVZ8R这个函数发起的,上面定义了这个一个bVZ8R函数,我们先不管windows.asrsea是啥,先看后面的几个参数。
var bVZ8R=window.asrsea(JSON.stringify(i9b),bqN1x(["流泪","强"]),bqN1x(Wx4B.md),bqN1x(["爱心","女孩","惊恐","大笑"]));
- 这里有4个参数,我们称之为第一参数、第二参数、第三参数、第四参数 第一参数:JSON.stringify(i9b) 第二参数:bqN1x(["流泪","强"]) 第三参数: bqN1x(Wx4B.md) 第四参数: bqN1x(["爱心","女孩","惊恐","大笑"]) 第二个和第四个参数,我们一眼就看得出,这是传入实参,在python里,这一定是个定值。再看第三个参数,也是一个实参,那么第一参数一定是个变化的参数。
- 如果继续研究下去,有两种发展思路,一个是阅读JS,破解JS加密重构Python代码。这个难度非常大。第二种,用另外一种手段取得加密参数——抓包工具Charles,它相当于一个中介,在实现服务器和你的电脑端交互的时候,Charles作为中间过滤器给你筛选信息。
- 现在需要重写JS代码,在不影响整体运行的情况下,需要知道,传入的这几个参数的运行结果分别是什么。加入一个alert语法弹出这几个参数的运行结果。
alert(JSON.stringify(i9b) "==" bqN1x(["流泪","强"]) "==" bqN1x(Wx4B.md) "==" bqN1x(["爱心","女孩","惊恐","大笑"]))
- 第一步,我们找到JS地址中那个core_3dedbd537c6b7cf4e179...的地址,我们瞧瞧,是在s3.music.126/web/s里面。然后打开小叶壶,对着这个core的JS文件,右键,最下面有个Map Local,点开弹出这个界面,把我们修改好的JS文件更改进去,确定。再刷新一下页面,会发现这几个参数对应的内容都显示出来了,把原弹框复制出来,然后分割。规整化后,你就会发现这几个参数分别是
第一参数:{"rid":"R_SO_4_478106252","offset":"20","total":"false","limit":"20","csrf_token":""} 第二参数:010001 第三参数:00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7 第四参数:0CoJUm6Qyw8W8jud
- 2、3、4是实参,这些数据不会变,变的是第一个。我们还要看window.asrsea是什么东西,大家搜索关键字,然后在上面可以看到定义的一个变量window.asrsea = d。然后会发现,d函数返回的就是encSecKey和encText,然后大家要想清楚这个问题,我们在之前定义了windows.asrsea的四个变量,然后他说windows.asrsea = d。那4个变量分别就是对应 d,e,f,g。关于encText,他要的是d,g两个参数,还有个i,当然你问b又是什么,这些我们都不要去管,这一定是某种加密技术,我们现在只需要知道他传入的是什么参数就行。那么还有一个i,又是啥?上面定义了,i =a(16),a又是啥?其实就是一个16位长度的随机数 说完,那么encText里面含有什么呢?就是d g i。所以encSecKey同理:params:第一参数 第四参数 16位长度的随机数。encSecKey:16位长度随机数 第二参数 第三参数。也就是说encSecKey其实是个常量,随便拷贝一个data里面的数据直接用就完事了。
某云Music——JS破解全过程
2020-09-30 11:17:56
浏览数 (1)