福州市建设厅网站,电子工程网名,如何查网站的icp备案,萍乡做网站的公司js逆向爬取某音乐网站某歌手的歌曲一、分析网站1、案例介绍2、寻找列表页Ajax入口#xff08;1#xff09;页面展示图。#xff08;2#xff09;寻找部分歌曲信息Ajax的token。#xff08;3#xff09;寻找歌曲链接#xff08;4#xff09;获取歌曲名称和id信息3、寻找…
js逆向爬取某音乐网站某歌手的歌曲一、分析网站1、案例介绍2、寻找列表页Ajax入口1页面展示图。2寻找部分歌曲信息Ajax的token。3寻找歌曲链接4获取歌曲名称和id信息3、寻找网页数据的加密逻辑1寻找歌曲地址出处。2查找表单数据中的关键字3建立生成方法的js文件4编辑“生成构造歌曲地址的表单数据方法”的代码二、开始爬取工作1、构建歌曲地址2、修改JS文件中的参数3、成功获得歌曲链接的地址三、保存并总结一、分析网站
1、案例介绍
爬虫学习已经结束了再继续练习巩固。这一次拿某音乐网站某歌星的歌曲为例进行批量爬取。这里的前端javaScript带有变量名混淆也带有字符串混淆还带有对象键名替换等技术所以爬取起来要花费一定的时间去分析并理清里面的逻辑关系。这次的练习目的很简单思路也不麻烦就是找到歌曲的url地址和歌曲名称再爬取、保存。
2、寻找列表页Ajax入口
1页面展示图。 这里还是用右击“检查”的形式对上面页面进行分析。虽然在“元素”这一栏能找到歌曲的链接及名字但这次源代码里面是找不到的那就意味着用requests爬取不到需要的信息。
2寻找部分歌曲信息Ajax的token。
接着打开“网络”——“Fetch/XHR”刷新之后开始查找列表出现很多含有“token”的列表项按照经验找到“web?csrf_token”点击“预览”找到想要的信息列表。如图。 在爬取类似歌曲信息的时候需要注意的一点就是要关注这些列表中的id信息。在“标头”栏找到请求头“https://music.YouKnowde.com/weapi/cloudsearch/get/web?csrf_token”这个地址也要写入程序里面而且看到下面的请求方法是POST方式。再打开“载荷”栏查看表单数据。如图。 上面表单数据的格式是通过加密后产生的可以查看md5.cn网站比较得出是哪一种加密方式。先用以上信息写一段代码获取一部分信息再做进一步的分析。
import requestsclass Music_Data(object):def __init__(self):super().__init__()self.url https://music.YouKnowde.com/weapi/cloudsearch/get/web?csrf_tokenself.wangyi_url https://music.YouKnowde.com/weapi/song/enhance/player/url/v1?csrf_tokenself.headers {user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36,origin: https://music.YouKnowde.com,referer: https://music.YouKnowde.com/search/}self.data {params: VcB5Z4BiekLvHcWYMKc78nXTiKKCn6eAjm8yfLksGSJr9rPpDKZP8HPJG9BYL33uYq97UL2UDkQdhq6QoKm8dbzvJstjrmn8PDCUwE6azkPUCIhiMnCE5sonqHw8D0OGvEk0N/v3PYGqcc/Cp4HvJmrQoS50BlcA8h7X7Djcal1ku2A03QrOqT4Zkai78O4c95I5rHDxecBZbi8pvA7jji9Gf7mPmOJ1ZqaLvtsbSgCbtyFBUWvzfQqWXKejd8hgFePlM4i/yEWb6Ug5BQg,encSecKey: c2dfcdf582d19c7ec069d8315befe647a0a91af398a44bb994cf69386977115df512627a4f7c4c82ec9a608fe0ea6de0e4063a4bea2a6af703615133b0b64e22adb20484dfa5db22b72866c0ab9529237cfdf9b4eaa8d67294c896de380658fa859167b67c73a35c5d65c97ba839d1a6d1feca697eedf6ef9b6bf2663fc561e3}def get_data_index(self):resp requests.post(urlself.url, dataself.data, headersself.headers)print(resp.text)def run(self):self.get_data_index()if __name__ __main__:music Music_Data()music.run()上面代码自然获取到了歌曲的一些信息代码。如图。 从上面获得结果看刚才乱码形式的表单数据可以不用理会。
3寻找歌曲链接 点击“媒体”——点击播放看到如下结果。 点击这条记录再点击“标头”栏看到请求网址信息复制到地址栏“转到”就能听到歌曲播放。 那么刚才请求网址的链接就是这首歌的播放地址。也就是说这样就成功的找到一首歌的地址链接了。
然后我们看到请求网址的地址比较乱无规则的字符掺杂其中那它到底是怎么来的。
4获取歌曲名称和id信息
还是在开发者工具界面点击“网络”——“Fetch/XHR”——刷新网页并选择“web?csrf_token”——预览就看到字典格式的内容用json中的方法loads改成字典格式进一步获得歌曲名称和id信息。 改写程序中的get_data_index方法由获取源代码进一步改成获取歌曲名称和id的方法。代码如下def get_data_index(self):resp requests.post(urlself.url, dataself.data, headersself.headers)# print(resp.text)# 此处根据web?csrf_token链接汇总的预览栏找到字典形式的信息获取相应歌曲名dict_data json.loads(resp.text)[result][songs]# 而后遍历所有歌曲获取name和idfor data in dict_data:name data[name]id data[id]print(name, id)运行之后成功获取到想要的信息。如图。
3、寻找网页数据的加密逻辑
1寻找歌曲地址出处。
在上面请求网址的地址代码中复制一小段然后搜索即得到两个结果。如图。 经过分析点击第二个结果的链接再点击预览看到下面字典格式的信息里面就有歌曲信息的链接。如图。 再继续点开上图所示的开发者工具中的“标头”它里面的请求网址就是产生这首歌曲地址的请求地址。而且是以POST的请求方式。如图。 再按以上方式找到一首歌曲的地址。即媒体——播放——选中复制一段代码搜索——找到请求网址。然后再点“载荷”一栏得到表单数据也是params和encSecKey两项不过此时的字符串变了。也就是说换了不同的歌曲就更换了不同的表单数据显然每次爬取歌曲都要更换此处的表单数据确实是挺麻烦的事。那么接下来应该怎么做呢答案就是表单数据是网页中JavaScript代码产生的咱们应该继续网页表单数据中params和encSecKey两项的生成机制。即分析明白网页中的这一加密逻辑。
2查找表单数据中的关键字
通过如下方式在源代码js逻辑代码中寻找表单数据中的encSecKey的代码段。步骤如下图。 点开上面会进入源代码里面继续搜索“encSecKey”会找到下图的地方这里就是表单数据生成的代码块。
显然上面代码中使用了字符串混淆和对象键名替换的技术。然后我们分析发现params和encSecKey两个键对应的值里面有一个bMr1x而bMr1x又在上面被var定义好了。再看bMr1x的定义里面又用到了window.asrsea这个方法接着继续搜索关键字window.asrsea看看别处有没有定义。搜索完成就两个结果除了当前应用的这个地方上面不远处就是定义的地方。如图。
在这里我们发现d就是上面定义的函数方法在这里给d函数断点再播放歌曲。因为有断点所以歌曲没有播放马上暂停了得到一系列参数。如图。 我们看到上面代码中又应用了变量名混淆的技术变量名或函数名全部是a、b、c这样的字眼。因为我们需要的是生成表单数据的功能此时只要把这部分代码拿出来形成一个js文件就能为我所用。所以我们复制实现这个功能的这一整个函数即可如图。 在这里插入代码片段。
3建立生成方法的js文件
在PyCharm平台新建一个wyy.js文件把上面复制的JavaScript函数代码粘贴进来再进行适当的增删把它的功能重建。
!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}asrsea d
}();分析上面可知里面定义了a、b、c、d四个函数然后运行完之后得到四个结果。如上图右侧的红色部分。继续分析可以看出经过混淆后代码里面的下面这段其中bMr1x定义完成的功能就是上面js程序的d函数调用完成的功能。 var bMr1x window.asrsea(JSON.stringify(i0x), bsg8Y([流泪, 强]), bsg8Y(TH5M.md), bsg8Y([爱心, 女孩, 惊恐, 大笑]));e0x.data j0x.cr0x({params: bMr1x.encText,encSecKey: bMr1x.encSecKey这样在同一个wyy.js文件里面再写一个函数。因为上述代码里面掺入了变量名混淆、对象键名替换等技术仔细分析就是一个函数调用函数再依次返回数据得到返回值的过程。由此可以建立如下代码 function start() {d:{\id\:\190072\,\c\:\[{\\\id\\\:\\\190072\\\}]\,\csrf_token\:\\}e:010001f:00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7g:0CoJUm6Qyw8W8judvar bMr1x asrsea(JSON.stringify(d),e,f,g)return bMr1x
}上面两段代码是从网页源代码中剥离出来放到wyy.js里面对函数内部运作方法稍加分析之后重新整理合适的代码整个wyy.js代码改成如下形式
!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}asrsea d
}();function start() {var d {ids:[1894007406],level:standard,encodeType:aac,csrf_token:}var e 010001var f 00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7var g 0CoJUm6Qyw8W8judvar bMr1x asrsea(JSON.stringify(d),e,f,g)return bMr1x
}4编辑“生成构造歌曲地址的表单数据方法”的代码
上面得到了歌曲名称和id下面就构建歌曲地址。在程序中重新定义一个函数get_music_url_index然后运行。 上面的代码运行后得到错误。这是因为前面的wyy.js中有一个函数变量没有写入wyy.js程序中还有下面的setMaxDigits等函数如图黄色方框内的方法。 因此索性把CryptoJS开头定义的代码一直复制到与前面函数交界的地方。这里有个技巧选择就容易许多。就是在源代码中的下方有一队大括号{}点击一下一个函数的代码就收缩起来此处选择三个方法CryptoJS、RSAKeyPair和encryptedString正好和前面d函数所在的函数紧挨着。选择好之后复制粘贴到wyy.js的开端。整个代码如下var CryptoJSCryptoJS||function(u,p){var d{},ld.lib{},sfunction(){},tl.Base{extend:function(a){s.prototypethis;var cnew s;ac.mixIn(a);c.hasOwnProperty(init)||(c.initfunction(){c.$super.init.apply(this,arguments)});c.init.prototypec;c.$superthis;return c},create:function(){var athis.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)(this[c]a[c]);a.hasOwnProperty(toString)(this.toStringa.toString)},clone:function(){return this.init.prototype.extend(this)}},rl.WordArrayt.extend({init:function(a,c){athis.wordsa||[];this.sigBytesc!p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var cthis.words,ea.words,jthis.sigBytes;aa.sigBytes;this.clamp();if(j%4)for(var k0;ka;k)c[jk2]|(e[k2]24-8*(k%4)255)24-8*((jk)%4);else if(65535e.length)for(k0;ka;k4)c[jk2]e[k2];else c.push.apply(c,e);this.sigBytesa;return this},clamp:function(){var athis.words,cthis.sigBytes;a[c2]429496729532-8*(c%4);a.lengthu.ceil(c/4)},clone:function(){var at.clone.call(this);a.wordsthis.words.slice(0);return a},random:function(a){for(var c[],e0;ea;e4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),wd.enc{},vw.Hex{stringify:function(a){var ca.words;aa.sigBytes;for(var e[],j0;ja;j){var kc[j2]24-8*(j%4)255;e.push((k4).toString(16));e.push((k15).toString(16))}return e.join()},parse:function(a){for(var ca.length,e[],j0;jc;j2)e[j3]|parseInt(a.substr(j,2),16)24-4*(j%8);return new r.init(e,c/2)}},bw.Latin1{stringify:function(a){var ca.words;aa.sigBytes;for(var e[],j0;ja;j)e.push(String.fromCharCode(c[j2]24-8*(j%4)255));return e.join()},parse:function(a){for(var ca.length,e[],j0;jc;j)e[j2]|(a.charCodeAt(j)255)24-8*(j%4);return new r.init(e,c)}},xw.Utf8{stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error(Malformed UTF-8 data)}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},ql.BufferedBlockAlgorithmt.extend({reset:function(){this.i0xnew r.init;this.yE7x0},Ap8h:function(a){stringtypeof a(ax.parse(a));this.i0x.concat(a);this.yE7xa.sigBytes},mD4H:function(a){var cthis.i0x,ec.words,jc.sigBytes,kthis.blockSize,bj/(4*k),ba?u.ceil(b):u.max((b|0)-this.UZ5e,0);ab*k;ju.min(4*a,j);if(a){for(var q0;qa;qk)this.tt6n(e,q);qe.splice(0,a);c.sigBytes-j}return new r.init(q,j)},clone:function(){var at.clone.call(this);a.i0xthis.i0x.clone();return a},UZ5e:0});l.Hasherq.extend({cfg:t.extend(),init:function(a){this.cfgthis.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this.mk4o()},update:function(a){this.Ap8h(a);this.mD4H();return this},finalize:function(a){athis.Ap8h(a);return this.nZ4d()},blockSize:16,mO4S:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},yD7w:function(a){return function(b,e){return(new n.HMAC.init(a,e)).finalize(b)}}});var nd.algo{};return d}(Math);(function(){var uCryptoJS,pu.lib.WordArray;u.enc.Base64{stringify:function(d){var ld.words,pd.sigBytes,tthis.bD0x;d.clamp();d[];for(var r0;rp;r3)for(var w(l[r2]24-8*(r%4)255)16|(l[r12]24-8*((r1)%4)255)8|l[r22]24-8*((r2)%4)255,v0;4vr.75*vp;v)d.push(t.charAt(w6*(3-v)63));if(lt.charAt(64))for(;d.length%4;)d.push(l);return d.join()},parse:function(d){var ld.length,sthis.bD0x,ts.charAt(64);t(td.indexOf(t),-1!t(lt));for(var t[],r0,w0;wl;w)if(w%4){var vs.indexOf(d.charAt(w-1))2*(w%4),bs.indexOf(d.charAt(w))6-2*(w%4);t[r2]|(v|b)24-8*(r%4);r}return p.create(t,r)},bD0x:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/}})();(function(u){function p(b,n,a,c,e,j,k){bb(na|~nc)ek;return(bj|b32-j)n}function d(b,n,a,c,e,j,k){bb(nc|a~c)ek;return(bj|b32-j)n}function l(b,n,a,c,e,j,k){bb(n^a^c)ek;return(bj|b32-j)n}function s(b,n,a,c,e,j,k){bb(a^(n|~c))ek;return(bj|b32-j)n}for(var tCryptoJS,rt.lib,wr.WordArray,vr.Hasher,rt.algo,b[],x0;64x;x)b[x]4294967296*u.abs(u.sin(x1))|0;rr.MD5v.extend({mk4o:function(){this.cT1xnew w.init([1732584193,4023233417,2562383102,271733878])},tt6n:function(q,n){for(var a0;16a;a){var cna,eq[c];q[c](e8|e24)16711935|(e24|e8)4278255360}var athis.cT1x.words,cq[n0],eq[n1],jq[n2],kq[n3],zq[n4],rq[n5],tq[n6],wq[n7],vq[n8],Aq[n9],Bq[n10],Cq[n11],uq[n12],Dq[n13],Eq[n14],xq[n15],fa[0],ma[1],ga[2],ha[3],fp(f,m,g,h,c,7,b[0]),hp(h,f,m,g,e,12,b[1]),gp(g,h,f,m,j,17,b[2]),mp(m,g,h,f,k,22,b[3]),fp(f,m,g,h,z,7,b[4]),hp(h,f,m,g,r,12,b[5]),gp(g,h,f,m,t,17,b[6]),mp(m,g,h,f,w,22,b[7]),fp(f,m,g,h,v,7,b[8]),hp(h,f,m,g,A,12,b[9]),gp(g,h,f,m,B,17,b[10]),mp(m,g,h,f,C,22,b[11]),fp(f,m,g,h,u,7,b[12]),hp(h,f,m,g,D,12,b[13]),gp(g,h,f,m,E,17,b[14]),mp(m,g,h,f,x,22,b[15]),fd(f,m,g,h,e,5,b[16]),hd(h,f,m,g,t,9,b[17]),gd(g,h,f,m,C,14,b[18]),md(m,g,h,f,c,20,b[19]),fd(f,m,g,h,r,5,b[20]),hd(h,f,m,g,B,9,b[21]),gd(g,h,f,m,x,14,b[22]),md(m,g,h,f,z,20,b[23]),fd(f,m,g,h,A,5,b[24]),hd(h,f,m,g,E,9,b[25]),gd(g,h,f,m,k,14,b[26]),md(m,g,h,f,v,20,b[27]),fd(f,m,g,h,D,5,b[28]),hd(h,f,m,g,j,9,b[29]),gd(g,h,f,m,w,14,b[30]),md(m,g,h,f,u,20,b[31]),fl(f,m,g,h,r,4,b[32]),hl(h,f,m,g,v,11,b[33]),gl(g,h,f,m,C,16,b[34]),ml(m,g,h,f,E,23,b[35]),fl(f,m,g,h,e,4,b[36]),hl(h,f,m,g,z,11,b[37]),gl(g,h,f,m,w,16,b[38]),ml(m,g,h,f,B,23,b[39]),fl(f,m,g,h,D,4,b[40]),hl(h,f,m,g,c,11,b[41]),gl(g,h,f,m,k,16,b[42]),ml(m,g,h,f,t,23,b[43]),fl(f,m,g,h,A,4,b[44]),hl(h,f,m,g,u,11,b[45]),gl(g,h,f,m,x,16,b[46]),ml(m,g,h,f,j,23,b[47]),fs(f,m,g,h,c,6,b[48]),hs(h,f,m,g,w,10,b[49]),gs(g,h,f,m,E,15,b[50]),ms(m,g,h,f,r,21,b[51]),fs(f,m,g,h,u,6,b[52]),hs(h,f,m,g,k,10,b[53]),gs(g,h,f,m,B,15,b[54]),ms(m,g,h,f,e,21,b[55]),fs(f,m,g,h,v,6,b[56]),hs(h,f,m,g,x,10,b[57]),gs(g,h,f,m,t,15,b[58]),ms(m,g,h,f,D,21,b[59]),fs(f,m,g,h,z,6,b[60]),hs(h,f,m,g,C,10,b[61]),gs(g,h,f,m,j,15,b[62]),ms(m,g,h,f,A,21,b[63]);a[0]a[0]f|0;a[1]a[1]m|0;a[2]a[2]g|0;a[3]a[3]h|0},nZ4d:function(){var bthis.i0x,nb.words,a8*this.yE7x,c8*b.sigBytes;n[c5]|12824-c%32;var eu.floor(a/4294967296);n[(c6494)15](e8|e24)16711935|(e24|e8)4278255360;n[(c6494)14](a8|a24)16711935|(a24|a8)4278255360;b.sigBytes4*(n.length1);this.mD4H();bthis.cT1x;nb.words;for(a0;4a;a)cn[a],n[a](c8|c24)16711935|(c24|c8)4278255360;return b},clone:function(){var bv.clone.call(this);b.cT1xthis.cT1x.clone();return b}});t.MD5v.mO4S(r);t.HmacMD5v.yD7w(r)})(Math);(function(){var uCryptoJS,pu.lib,dp.Base,lp.WordArray,pu.algo,sp.EvpKDFd.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfgthis.cfg.extend(d)},compute:function(d,r){for(var pthis.cfg,sp.hasher.create(),bl.create(),ub.words,qp.keySize,pp.iterations;u.lengthq;){ns.update(n);var ns.update(d).finalize(r);s.reset();for(var a1;ap;a)ns.finalize(n),s.reset();b.concat(n)}b.sigBytes4*q;return b}});u.EvpKDFfunction(d,l,p){return s.create(p).compute(d,l)}})();CryptoJS.lib.Cipher||function(u){var pCryptoJS,dp.lib,ld.Base,sd.WordArray,td.BufferedBlockAlgorithm,rp.enc.Base64,wp.algo.EvpKDF,vd.Ciphert.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this.If2x,e,a)},createDecryptor:function(e,a){return this.create(this.brx8p,e,a)},init:function(e,a,b){this.cfgthis.cfg.extend(b);this.UA5Fe;this.J0xa;this.reset()},reset:function(){t.reset.call(this);this.mk4o()},process:function(e){this.Ap8h(e);return this.mD4H()},finalize:function(e){ethis.Ap8h(e);return this.nZ4d()},keySize:4,ivSize:4,If2x:1,brx8p:2,mO4S:function(e){return{encrypt:function(b,k,d){return(stringtypeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return(stringtypeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipherv.extend({nZ4d:function(){return this.mD4H(!0)},blockSize:1});var bp.mode{},xfunction(e,a,b){var cthis.tC6w;c?this.tC6wu:cthis.DV9M;for(var d0;db;d)e[ad]^c[d]},q(d.BlockCipherModel.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this.ua6Ue;this.tC6wa}})).extend();q.Encryptorq.extend({processBlock:function(e,a){var bthis.ua6U,cb.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this.DV9Me.slice(a,ac)}});q.Decryptorq.extend({processBlock:function(e,a){var bthis.ua6U,cb.blockSize,de.slice(a,ac);b.decryptBlock(e,a);x.call(this,e,a,c);this.DV9Md}});bb.CBCq;q(p.pad{}).Pkcs7{pad:function(a,b){for(var c4*b,cc-a.sigBytes%c,dc24|c16|c8|c,l[],n0;nc;n4)l.push(d);cs.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-a.words[a.sigBytes-12]255}};d.BlockCipherv.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var athis.cfg,ba.iv,aa.mode;if(this.UA5Fthis.If2x)var ca.createEncryptor;else ca.createDecryptor,this.UZ5e1;this.eR1xc.call(a,this,bb.words)},tt6n:function(a,b){this.eR1x.processBlock(a,b)},nZ4d:function(){var athis.cfg.padding;if(this.UA5Fthis.If2x){a.pad(this.i0x,this.blockSize);var bthis.mD4H(!0)}else bthis.mD4H(!0),a.unpad(b);return b},blockSize:4});var nd.CipherParamsl.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b(p.format{}).OpenSSL{stringify:function(a){var ba.ciphertext;aa.salt;return(a?s.create([1398893684,1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){ar.parse(a);var ba.words;if(1398893684b[0]1701076831b[1]){var cs.create(b.slice(2,4));b.splice(0,4);a.sigBytes-16}return n.create({ciphertext:a,salt:c})}},ad.SerializableCipherl.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){dthis.cfg.extend(d);var la.createEncryptor(c,d);bl.finalize(b);ll.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},decrypt:function(a,b,c,d){dthis.cfg.extend(d);bthis.HX2x(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},HX2x:function(a,b){returnstringtypeof a?b.parse(a,this):a}}),p(p.kdf{}).OpenSSL{execute:function(a,b,c,d){d||(ds.random(8));aw.create({keySize:bc}).compute(a,d);cs.create(a.words.slice(b),4*c);a.sigBytes4*b;return n.create({key:a,iv:c,salt:d})}},cd.PasswordBasedCiphera.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){lthis.cfg.extend(l);dl.kdf.execute(d,b.keySize,b.ivSize);l.ivd.iv;ba.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){lthis.cfg.extend(l);cthis.HX2x(c,l.format);dl.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.ivd.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();(function(){for(var uCryptoJS,pu.lib.BlockCipher,du.algo,l[],s[],t[],r[],w[],v[],b[],x[],q[],n[],a[],c0;256c;c)a[c]128c?c1:c1^283;for(var e0,j0,c0;256c;c){var kj^j1^j2^j3^j4,kk8^k255^99;l[e]k;s[k]e;var za[e],Fa[z],Ga[F],y257*a[k]^16843008*k;t[e]y24|y8;r[e]y16|y16;w[e]y8|y24;v[e]y;y16843009*G^65537*F^257*z^16843008*e;b[k]y24|y8;x[k]y16|y16;q[k]y8|y24;n[k]y;e?(ez^a[a[a[G^z]]],j^a[a[j]]):ej1}var H[0,1,2,4,8,16,32,64,128,27,54],dd.AESp.extend({mk4o:function(){for(var athis.J0x,ca.words,da.sigBytes/4,a4*((this.bgi6cd6)1),ethis.brW8O[],j0;ja;j)if(jd)e[j]c[j];else{var ke[j-1];j%d?6d4j%d(kl[k24]24|l[k16255]16|l[k8255]8|l[k255]):(kk8|k24,kl[k24]24|l[k16255]16|l[k8255]8|l[k255],k^H[j/d|0]24);e[j]e[j-d]^k}cthis.bse8W[];for(d0;da;d)ja-d,kd%4?e[j]:e[j-4],c[d]4d||4j?k:b[l[k24]]^x[l[k16255]]^q[l[k8255]]^n[l[k255]]},encryptBlock:function(a,b){this.DW9N(a,b,this.brW8O,t,r,w,v,l)},decryptBlock:function(a,c){var da[c1];a[c1]a[c3];a[c3]d;this.DW9N(a,c,this.bse8W,b,x,q,n,s);da[c1];a[c1]a[c3];a[c3]d},DW9N:function(a,b,c,d,e,j,l,f){for(var mthis.bgi6c,ga[b]^c[0],ha[b1]^c[1],ka[b2]^c[2],na[b3]^c[3],p4,r1;rm;r)var qd[g24]^e[h16255]^j[k8255]^l[n255]^c[p],sd[h24]^e[k16255]^j[n8255]^l[g255]^c[p],td[k24]^e[n16255]^j[g8255]^l[h255]^c[p],nd[n24]^e[g16255]^j[h8255]^l[k255]^c[p],gq,hs,kt;q(f[g24]24|f[h16255]16|f[k8255]8|f[n255])^c[p];s(f[h24]24|f[k16255]16|f[n8255]8|f[g255])^c[p];t(f[k24]24|f[n16255]16|f[g8255]8|f[h255])^c[p];n(f[n24]24|f[g16255]16|f[h8255]8|f[k255])^c[p];a[b]q;a[b1]s;a[b2]t;a[b3]n},keySize:8});u.AESp.mO4S(d)})();
function RSAKeyPair(a,b,c){this.ebiFromHex(a),this.dbiFromHex(b),this.mbiFromHex(c),this.chunkSize2*biHighIndex(this.m),this.radix16,this.barrettnew BarrettMu(this.m)}function twoDigit(a){return(10a?0:)String(a)}function encryptedString(a,b){for(var f,g,h,i,j,k,l,cnew Array,db.length,e0;de;)c[e]b.charCodeAt(e),e;for(;0!c.length%a.chunkSize;)c[e]0;for(fc.length,g,e0;fe;ea.chunkSize){for(jnew BigInt,h0,ie;iea.chunkSize;h)j.digits[h]c[i],j.digits[h]c[i]8;ka.barrett.powMod(j,a.e),l16a.radix?biToHex(k):biToString(k,a.radix),gl }return g.substring(0,g.length-1)}function decryptedString(a,b){var e,f,g,h,cb.split( ),d;for(e0;ec.length;e)for(h16a.radix?biFromHex(c[e]):biFromString(c[e],a.radix),ga.barrett.powMod(h,a.d),f0;fbiHighIndex(g);f)dString.fromCharCode(255g.digits[f],g.digits[f]8);return 0d.charCodeAt(d.length-1)(dd.substring(0,d.length-1)),d}function setMaxDigits(a){maxDigitsa,ZERO_ARRAYnew Array(maxDigits);for(var b0;bZERO_ARRAY.length;b)ZERO_ARRAY[b]0;bigZeronew BigInt,bigOnenew BigInt,bigOne.digits[0]1}function BigInt(a){this.digitsbooleantypeof a1a?null:ZERO_ARRAY.slice(0),this.isNeg!1}function biFromDecimal(a){for(var d,e,f,b-a.charAt(0),cb?1:0;ca.length0a.charAt(c);)c;if(ca.length)dnew BigInt;else{for(ea.length-c,fe%dpl10,0f(fdpl10),dbiFromNumber(Number(a.substr(c,f))),cf;ca.length;)dbiAdd(biMultiply(d,lr10),biFromNumber(Number(a.substr(c,dpl10)))),cdpl10;d.isNegb}return d}function biCopy(a){var bnew BigInt(!0);return b.digitsa.digits.slice(0),b.isNega.isNeg,b}function biFromNumber(a){var c,bnew BigInt;for(b.isNeg0a,aMath.abs(a),c0;a0;)b.digits[c]amaxDigitVal,abiRadixBits;return b}function reverseStr(a){var c,b;for(ca.length-1;c-1;--c)ba.charAt(c);return b}function biToString(a,b){var d,e,cnew BigInt;for(c.digits[0]b,dbiDivideModulo(a,c),ehexatrigesimalToChar[d[1].digits[0]];1biCompare(d[0],bigZero);)dbiDivideModulo(d[0],c),digitd[1].digits[0],ehexatrigesimalToChar[d[1].digits[0]];return(a.isNeg?-:)reverseStr(e)}function biToDecimal(a){var c,d,bnew BigInt;for(b.digits[0]10,cbiDivideModulo(a,b),dString(c[1].digits[0]);1biCompare(c[0],bigZero);)cbiDivideModulo(c[0],b),dString(c[1].digits[0]);return(a.isNeg?-:)reverseStr(d)}function digitToHex(a){var b15,c;for(i0;4i;i)chexToChar[ab],a4;return reverseStr(c)}function biToHex(a){var d,b;for(biHighIndex(a),dbiHighIndex(a);d-1;--d)bdigitToHex(a.digits[d]);return b}function charToHex(a){var h,b48,cb9,d97,ed25,f65,g90;return habca?a-b:afga?10a-f:adea?10a-d:0}function hexToDigit(a){var d,b0,cMath.min(a.length,4);for(d0;cd;d)b4,b|charToHex(a.charCodeAt(d));return b}function biFromHex(a){var d,e,bnew BigInt,ca.length;for(dc,e0;d0;d-4,e)b.digits[e]hexToDigit(a.substr(Math.max(d-4,0),Math.min(d,4)));return b}function biFromString(a,b){var g,h,i,j,c-a.charAt(0),dc?1:0,enew BigInt,fnew BigInt;for(f.digits[0]1,ga.length-1;gd;g--)ha.charCodeAt(g),icharToHex(h),jbiMultiplyDigit(f,i),ebiAdd(e,j),fbiMultiplyDigit(f,b);return e.isNegc,e}function biDump(a){return(a.isNeg?-:)a.digits.join( )}function biAdd(a,b){var c,d,e,f;if(a.isNeg!b.isNeg)b.isNeg!b.isNeg,cbiSubtract(a,b),b.isNeg!b.isNeg;else{for(cnew BigInt,d0,f0;fa.digits.length;f)ea.digits[f]b.digits[f]d,c.digits[f]65535e,dNumber(ebiRadix);c.isNega.isNeg}return c}function biSubtract(a,b){var c,d,e,f;if(a.isNeg!b.isNeg)b.isNeg!b.isNeg,cbiAdd(a,b),b.isNeg!b.isNeg;else{for(cnew BigInt,e0,f0;fa.digits.length;f)da.digits[f]-b.digits[f]e,c.digits[f]65535d,c.digits[f]0(c.digits[f]biRadix),e0-Number(0d);if(-1e){for(e0,f0;fa.digits.length;f)d0-c.digits[f]e,c.digits[f]65535d,c.digits[f]0(c.digits[f]biRadix),e0-Number(0d);c.isNeg!a.isNeg}else c.isNega.isNeg}return c}function biHighIndex(a){for(var ba.digits.length-1;b00a.digits[b];)--b;return b}function biNumBits(a){var e,bbiHighIndex(a),ca.digits[b],d(b1)*bitsPerDigit;for(ed;ed-bitsPerDigit0(32768c);--e)c1;return e}function biMultiply(a,b){var d,h,i,k,cnew BigInt,ebiHighIndex(a),fbiHighIndex(b);for(k0;fk;k){for(d0,ik,j0;ej;j,i)hc.digits[i]a.digits[j]*b.digits[k]d,c.digits[i]hmaxDigitVal,dhbiRadixBits;c.digits[ke1]d}return c.isNega.isNeg!b.isNeg,c}function biMultiplyDigit(a,b){var c,d,e,f;for(resultnew BigInt,cbiHighIndex(a),d0,f0;cf;f)eresult.digits[f]a.digits[f]*bd,result.digits[f]emaxDigitVal,debiRadixBits;return result.digits[1c]d,result}function arrayCopy(a,b,c,d,e){var g,h,fMath.min(be,a.length);for(gb,hd;fg;g,h)c[h]a[g]}function biShiftLeft(a,b){var e,f,g,h,cMath.floor(b/bitsPerDigit),dnew BigInt;for(arrayCopy(a.digits,0,d.digits,c,d.digits.length-c),eb%bitsPerDigit,fbitsPerDigit-e,gd.digits.length-1,hg-1;g0;--g,--h)d.digits[g]d.digits[g]emaxDigitVal|(d.digits[h]highBitMasks[e])f;return d.digits[0]d.digits[g]emaxDigitVal,d.isNega.isNeg,d}function biShiftRight(a,b){var e,f,g,h,cMath.floor(b/bitsPerDigit),dnew BigInt;for(arrayCopy(a.digits,c,d.digits,0,a.digits.length-c),eb%bitsPerDigit,fbitsPerDigit-e,g0,hg1;gd.digits.length-1;g,h)d.digits[g]d.digits[g]e|(d.digits[h]lowBitMasks[e])f;return d.digits[d.digits.length-1]e,d.isNega.isNeg,d}function biMultiplyByRadixPower(a,b){var cnew BigInt;return arrayCopy(a.digits,0,c.digits,b,c.digits.length-b),c}function biDivideByRadixPower(a,b){var cnew BigInt;return arrayCopy(a.digits,b,c.digits,0,c.digits.length-b),c}function biModuloByRadixPower(a,b){var cnew BigInt;return arrayCopy(a.digits,0,c.digits,0,b),c}function biCompare(a,b){if(a.isNeg!b.isNeg)return 1-2*Number(a.isNeg);for(var ca.digits.length-1;c0;--c)if(a.digits[c]!b.digits[c])return a.isNeg?1-2*Number(a.digits[c]b.digits[c]):1-2*Number(a.digits[c]b.digits[c]);return 0}function biDivideModulo(a,b){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,cbiNumBits(a),dbiNumBits(b),eb.isNeg;if(dc)return a.isNeg?(fbiCopy(bigOne),f.isNeg!b.isNeg,a.isNeg!1,b.isNeg!1,gbiSubtract(b,a),a.isNeg!0,b.isNege):(fnew BigInt,gbiCopy(a)),new Array(f,g);for(fnew BigInt,ga,hMath.ceil(d/bitsPerDigit)-1,i0;b.digits[h]biHalfRadix;)bbiShiftLeft(b,1),i,d,hMath.ceil(d/bitsPerDigit)-1;for(gbiShiftLeft(g,i),ci,jMath.ceil(c/bitsPerDigit)-1,kbiMultiplyByRadixPower(b,j-h);-1!biCompare(g,k);)f.digits[j-h],gbiSubtract(g,k);for(lj;lh;--l){for(mlg.digits.length?0:g.digits[l],nl-1g.digits.length?0:g.digits[l-1],ol-2g.digits.length?0:g.digits[l-2],phb.digits.length?0:b.digits[h],qh-1b.digits.length?0:b.digits[h-1],f.digits[l-h-1]mp?maxDigitVal:Math.floor((m*biRadixn)/p),rf.digits[l-h-1]*(p*biRadixq),sm*biRadixSquared(n*biRadixo);rs;)--f.digits[l-h-1],rf.digits[l-h-1]*(p*biRadix|q),sm*biRadix*biRadix(n*biRadixo);kbiMultiplyByRadixPower(b,l-h-1),gbiSubtract(g,biMultiplyDigit(k,f.digits[l-h-1])),g.isNeg(gbiAdd(g,k),--f.digits[l-h-1])}return gbiShiftRight(g,i),f.isNega.isNeg!e,a.isNeg(fe?biAdd(f,bigOne):biSubtract(f,bigOne),bbiShiftRight(b,i),gbiSubtract(b,g)),0g.digits[0]0biHighIndex(g)(g.isNeg!1),new Array(f,g)}function biDivide(a,b){return biDivideModulo(a,b)[0]}function biModulo(a,b){return biDivideModulo(a,b)[1]}function biMultiplyMod(a,b,c){return biModulo(biMultiply(a,b),c)}function biPow(a,b){for(var cbigOne,da;;){if(0!(1b)(cbiMultiply(c,d)),b1,0b)break;dbiMultiply(d,d)}return c}function biPowMod(a,b,c){for(var dbigOne,ea,fb;;){if(0!(1f.digits[0])(dbiMultiplyMod(d,e,c)),fbiShiftRight(f,1),0f.digits[0]0biHighIndex(f))break;ebiMultiplyMod(e,e,c)}return d}function BarrettMu(a){this.modulusbiCopy(a),this.kbiHighIndex(this.modulus)1;var bnew BigInt;b.digits[2*this.k]1,this.mubiDivide(b,this.modulus),this.bkplus1new BigInt,this.bkplus1.digits[this.k1]1,this.moduloBarrettMu_modulo,this.multiplyModBarrettMu_multiplyMod,this.powModBarrettMu_powMod}function BarrettMu_modulo(a){var i,bbiDivideByRadixPower(a,this.k-1),cbiMultiply(b,this.mu),dbiDivideByRadixPower(c,this.k1),ebiModuloByRadixPower(a,this.k1),fbiMultiply(d,this.modulus),gbiModuloByRadixPower(f,this.k1),hbiSubtract(e,g);for(h.isNeg(hbiAdd(h,this.bkplus1)),ibiCompare(h,this.modulus)0;i;)hbiSubtract(h,this.modulus),ibiCompare(h,this.modulus)0;return h}function BarrettMu_multiplyMod(a,b){var cbiMultiply(a,b);return this.modulo(c)}function BarrettMu_powMod(a,b){var d,e,cnew BigInt;for(c.digits[0]1,da,eb;;){if(0!(1e.digits[0])(cthis.multiplyMod(c,d)),ebiShiftRight(e,1),0e.digits[0]0biHighIndex(e))break;dthis.multiplyMod(d,d)}return c}var maxDigits,ZERO_ARRAY,bigZero,bigOne,dpl10,lr10,hexatrigesimalToChar,hexToChar,highBitMasks,lowBitMasks,biRadixBase2,biRadixBits16,bitsPerDigitbiRadixBits,biRadix65536,biHalfRadixbiRadix1,biRadixSquaredbiRadix*biRadix,maxDigitValbiRadix-1,maxInteger9999999999999998;setMaxDigits(20),dpl1015,lr10biFromNumber(1e15),hexatrigesimalToCharnew Array(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z),hexToCharnew Array(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f),highBitMasksnew Array(0,32768,49152,57344,61440,63488,64512,65024,65280,65408,65472,65504,65520,65528,65532,65534,65535),lowBitMasksnew Array(0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535);上面代码补充进wyy.js中之后就可以运行生成params和encSecKey这样每首歌曲都会生成这样一对表单数据作为参数再由这些参数构架歌曲的地址了。如图所示。 显然上面得到的结果分别是params的值encText以及encSecKey的值encSecKey这也是表单数据里面的形式。经过一系列操作把表单数据信息的加密逻辑分析明白后再逆向读取用Python重新模拟生成了。再看看下面的代码是不是觉得也不十分陌生了吧。
二、开始爬取工作
1、构建歌曲地址
改写get_music_url_index方法把歌曲id和名称都加入。代码如下 def get_data_index(self):resp requests.post(urlself.url, dataself.data, headersself.headers)# print(resp.text)# 此处根据web?csrf_token链接汇总的预览栏找到字典形式的信息获取相应歌曲名dict_data json.loads(resp.text)[result][songs]# 而后遍历所有歌曲获取name和idfor data in dict_data:name data[name]id data[id]# print(name, id)self.get_music_url_index(id, name)# 定义获取歌曲地址信息的方法注意这里加入歌曲的参数iddef get_music_url_index(self, id, name):content open(wyy.js, r, encodingutf-8).read()data_js execjs.compile(content)sign data_js.call(start, id)# 通过下面打印输出的结果看出来表单数据的构造方法成功了# print(sign)# 应用上面构造的方法生成表单数据data {params: sign[encText],encSecKey: sign[encSecKey]}# 定义歌曲链接,获取源代码resp requests.post(urlself.music_url, datadata, headersself.headers).textmusic_url json.loads(resp)[data][0][url]print(music_url, name)2、修改JS文件中的参数
上面代码写完后相应的wyy.js里面的start函数里面也要加上id参数。如图。
3、成功获得歌曲链接的地址
效果如图。
三、保存并总结
由两段代码构成首先在Music_Data类的前面写一个判断判断根目录下有没有文件夹没有的话就创建。file_name input(请手动创建保存歌曲的文件夹)
if not os.path.exists(file_name):os.mkdir(file_name)再到Music_Data类的里面写一个保存的方法write_music代码如下# 保存
def write_music(self, music_url, name):try:with open(f./{file_name}/name.mp3, wb) as f:resp requests.get(music_url).contentf.write(resp)print(name, ----保存成功)except Exception as e:print(e)运行一下程序得到想要的结果。如图。 打开歌曲所在的文件夹也能看到成功。 总结如下 以上是用js逆向的方法完成歌曲的爬取下载。用到了JavaScript技术那么这个技术也需要熟练掌握不然爬虫技术也是无法突破。本例中首先找到token的信息把里面歌曲的链接地址包括生成这个地址的加密形式的表单数据以及歌曲的id和name都找到。然后进一步寻找表单数据的加密逻辑创建相应的js文件。最后继续编写主程序代码把构建歌曲地址的方法以及保存歌曲的方法写入最后成功运行。当然不用逆向通过分析网页预览源代码用json方法获取字典形式的歌曲url也是能实现爬取歌曲的目的。不过本节学习逆向方法就绕了这么一大弯。真正遇到加密性强的网站本节练习的内容权当是爬虫逆向的入门知识了。注想要源码的问一下anqiuxiguanli