当前位置: 首页 > news >正文

网站优化就是seo郑州做网站要多少钱

网站优化就是seo,郑州做网站要多少钱,中信建设有限责任公司哈萨克斯坦分公司,做网站首页文件JS渗透之咪咕登录 每篇前言#xff1a;咪咕登录参数对比 captcha参数enpassword参数搜索enpassword参数搜索J_RsaPsd参数setPublic函数encrypt加密函数运行时可能会遇到的问题此部分改写的最终形态JS代码#xff1a;运行结果python编写脚本运行此JS代码#xff1a;运行结果咪咕登录参数对比 captcha参数enpassword参数搜索enpassword参数搜索J_RsaPsd参数setPublic函数encrypt加密函数运行时可能会遇到的问题此部分改写的最终形态JS代码运行结果python编写脚本运行此JS代码运行结果 loginID 参数步骤同上面的enpassword一步步搜索会发现找到了图中的J_RsaAccout,这个就是loginID参数的加密我们继续一步步分析会发现此参数的加密方式和刚刚的enpassword的加密方式一模一样那处理方法不就简单了 运行结果 FingerPrint和FingerPrintDetail参数找到指纹加密的主函数会发现就在刚刚的函数下面分析函数功能修改FingerPrint的JS函数运行结果 编写爬虫脚本1首先编写脚本构造出post表单2然后编写脚本发送请求并通过获取响应判断是否登录成功第一步直接向其发送请求观察响应是否为登录成功的界面第二步所以下面我们要做的就是通过分析浏览器登录找到一系列的重定向的URL并找到最终返回登录成功界面的URL第三步构造登录成功之后的重定向URL并通过依此请求模拟网站登录时候的一次次重定向跳转最终达到获取咪咕登录成功的界面 3观察可知登录成功 项目源码链接 每篇前言 作者介绍【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 本文已收录于爬虫进阶实战系列教程专栏《爬虫进阶实战系列教程》热门专栏推荐《Python全栈系列教程》、《爬虫从入门到精通系列教程》、《爬虫进阶实战系列教程》、《Scrapy框架从入门到实战》、《Flask框架从入门到实战》、《Django框架从入门到实战》、《Tornado框架从入门到实战》、《前端系列教程》。​本专栏面向广大程序猿为的是大家都做到Python全栈技术从入门到精通穿插有很多实战优化点。订阅专栏后可私聊进一千多人Python全栈交流群手把手教学问题解答 进群可领取Python全栈教程视频 多得数不过来的计算机书籍基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。加入我一起学习进步一个人可以走的很快一群人才能走的更远 咪咕登录 之前的请求中找数据: 上级页面搜索: 静态页面搜索参数内容 本级页面:Network里搜索内容 复杂登录特点: 参数多加密参数来源复杂多次请求 简单拓展 Ajax请求的底层是基于XMLHttpRequests对象实现所以在抓包时有两个特征页面不刷新 请求类型为xhr。 参数对比 captcha参数 这个值对应的是验证码的数据第一次登录时并没有这个验证码提交空值给表单就可以了验证码是账号或密码输错导致登录失败的时候会出现。这个时候会给服务器发送一条请求返回值就是验证码经过base64编码后的数据。 enpassword参数 通过观察两次请求的参数可以看出来enpassword参数是不相同的所以这个参数显然是动态变化生成的再仔细观察一下发现这个值每个字符的范围都是0-9和a-f通过我们的经验可以猜想这个参数是16进制的字符串而且很有可能是经过加密的。 搜索enpassword参数 但是搜索发现都是HTML源码里显然不可能包含此参数的值。经验可知此参数肯定是JS动态生成的所以我们就看HTML源码中此参数对应的代码既然name值参数搜索没用那么就来搜索一下class的值J_RsaPsd 搜索J_RsaPsd参数 分析JS文件,会发现三个地方都有此参数而且结构几乎一致所以为了找到目标数据我们将这三个都打上断点进行观察执行观察会停在哪一个上那我们就只分析那一个即可 执行过程分析可知是个RSA加密 分析最近的一个函数当选中var b $(this)这句时密码输入框标记选中可知此句是将密码赋值给b。 进入db函数 这里看不出有什么东西先跳过不管。 setPublic函数 这里需要传入两个参数这两个值在上一个请求的response中可以得到而且都是固定值。 这两个参数可以作为固定值写在代码里。 encrypt加密函数 传进去的参数b.val()在console中执行发现就是我们在密码框中输入的明文。 encrypt函数实际就是gb函数 这里是将gb函数赋值给db对象的原型对象下面又把db对象赋值给c.RSAKey这就是最开始定义c的语句。 gb函数执行到c.toString(16)的时候就得到了加密结果 改写JS加密基本逻辑下面的代码就写入改写的JS代码中 function getEncryptedPwd(pwd, modulus, publicExponent) {c new RSAKey;c.setPublic(modulus, publicExponent);var d c.encrypt(pwd);return d; }pwd传入明文密码modulus和publicExponent是固定值现在只要把里面有关联的函数复制出来再进行调试就可以了。 这里是RSA加密函数定义的起止位置注意我们复制两个大括号内部的所有代码 Python调用JS加密函数最终编写爬虫文件中使用 def make_encrypt_password(self, password, modulus, publicExponent):生成加密后的密码Args:password (str): 输入框内输入的原始密码modulus (str): rsa加密参数两个质数的乘积固定值前一个请求获得publicExponent (str): rsa加密参数大于1的奇数固定值前一个请求获得Returns:str: 加密后的密码return self.js_object.call(getEncryptedPwd, password, modulus, publicExponent)运行时可能会遇到的问题 遇到的错误1 报错 解决方法 把alert中的中文删去 遇到的错误2 报错 解决方法 定义navigator和window 遇到的错误3 报错 解决方法 修改如下代码 此部分改写的最终形态JS代码 var navigator {},window{};function d(a, b, c) {null ! a (number typeof a ? this.fromNumber(a, b, c) : null b string ! typeof a ? this.fromString(a, 256) : this.fromString(a, b)) } function e() {return new d(null) } function f(a, b, c, d, e, f) {for (; --f 0; ) {var g b * this[a] c[d] e;e Math.floor(g / 67108864),c[d] 67108863 g}return e } function g(a, b, c, d, e, f) {for (var g 32767 b, h b 15; --f 0; ) {var i 32767 this[a], j this[a] 15, k h * i j * g;i g * i ((32767 k) 15) c[d] (1073741823 e),e (i 30) (k 15) h * j (e 30),c[d] 1073741823 i}return e } function h(a, b, c, d, e, f) {for (var g 16383 b, h b 14; --f 0; ) {var i 16383 this[a], j this[a] 14, k h * i j * g;i g * i ((16383 k) 14) c[d] e,e (i 28) (k 14) h * j,c[d] 268435455 i}return e } function i(a) {return nb.charAt(a) } function j(a, b) {var c ob[a.charCodeAt(b)];return null c ? -1 : c } function k(a) {for (var b this.t - 1; b 0; --b)a[b] this[b];a.t this.t,a.s this.s } function l(a) {this.t 1,this.s 0 a ? -1 : 0,a 0 ? this[0] a : -1 a ? this[0] a this.DV : this.t 0 } function m(a) {var b e();return b.fromInt(a),b } function n(a, b) {var c;if (16 b)c 4;else if (8 b)c 3;else if (256 b)c 8;else if (2 b)c 1;else if (32 b)c 5;else {if (4 ! b)return void this.fromRadix(a, b);c 2}this.t 0,this.s 0;for (var e a.length, f !1, g 0; --e 0; ) {var h 8 c ? 255 a[e] : j(a, e);0 h ? - a.charAt(e) (f !0) : (f !1,0 g ? this[this.t] h : g c this.DB ? (this[this.t - 1] | (h (1 this.DB - g) - 1) g,this[this.t] h this.DB - g) : this[this.t - 1] | h g,g c,g this.DB (g - this.DB))}8 c 0 ! (128 a[0]) (this.s -1,g 0 (this[this.t - 1] | (1 this.DB - g) - 1 g)),this.clamp(),f d.ZERO.subTo(this, this) } function o() {for (var a this.s this.DM; this.t 0 this[this.t - 1] a; )--this.t } function p(a) {if (this.s 0)return - this.negate().toString(a);var b;if (16 a)b 4;else if (8 a)b 3;else if (2 a)b 1;else if (32 a)b 5;else {if (4 ! a)return this.toRadix(a);b 2}var c, d (1 b) - 1, e !1, f , g this.t, h this.DB - g * this.DB % b;if (g-- 0)for (h this.DB (c this[g] h) 0 (e !0,f i(c)); g 0; )b h ? (c (this[g] (1 h) - 1) b - h,c | this[--g] (h this.DB - b)) : (c this[g] (h - b) d,0 h (h this.DB,--g)),c 0 (e !0),e (f i(c));return e ? f : 0 } function q() {var a e();return d.ZERO.subTo(this, a),a } function r() {return this.s 0 ? this.negate() : this } function s(a) {var b this.s - a.s;if (0 ! b)return b;var c this.t;if (b c - a.t,0 ! b)return this.s 0 ? -b : b;for (; --c 0; )if (0 ! (b this[c] - a[c]))return b;return 0 } function t(a) {var b, c 1;return 0 ! (b a 16) (a b,c 16),0 ! (b a 8) (a b,c 8),0 ! (b a 4) (a b,c 4),0 ! (b a 2) (a b,c 2),0 ! (b a 1) (a b,c 1),c } function u() {return this.t 0 ? 0 : this.DB * (this.t - 1) t(this[this.t - 1] ^ this.s this.DM) } function v(a, b) {var c;for (c this.t - 1; c 0; --c)b[c a] this[c];for (c a - 1; c 0; --c)b[c] 0;b.t this.t a,b.s this.s } function w(a, b) {for (var c a; c this.t; c)b[c - a] this[c];b.t Math.max(this.t - a, 0),b.s this.s } function x(a, b) {var c, d a % this.DB, e this.DB - d, f (1 e) - 1, g Math.floor(a / this.DB), h this.s d this.DM;for (c this.t - 1; c 0; --c)b[c g 1] this[c] e | h,h (this[c] f) d;for (c g - 1; c 0; --c)b[c] 0;b[g] h,b.t this.t g 1,b.s this.s,b.clamp() } function y(a, b) {b.s this.s;var c Math.floor(a / this.DB);if (c this.t)return void (b.t 0);var d a % this.DB, e this.DB - d, f (1 d) - 1;b[0] this[c] d;for (var g c 1; g this.t; g)b[g - c - 1] | (this[g] f) e,b[g - c] this[g] d;d 0 (b[this.t - c - 1] | (this.s f) e),b.t this.t - c,b.clamp() } function z(a, b) {for (var c 0, d 0, e Math.min(a.t, this.t); e c; )d this[c] - a[c],b[c] d this.DM,d this.DB;if (a.t this.t) {for (d - a.s; c this.t; )d this[c],b[c] d this.DM,d this.DB;d this.s} else {for (d this.s; c a.t; )d - a[c],b[c] d this.DM,d this.DB;d - a.s}b.s 0 d ? -1 : 0,-1 d ? b[c] this.DV d : d 0 (b[c] d),b.t c,b.clamp() } function A(a, b) {var c this.abs(), e a.abs(), f c.t;for (b.t f e.t; --f 0; )b[f] 0;for (f 0; f e.t; f)b[f c.t] c.am(0, e[f], b, f, 0, c.t);b.s 0,b.clamp(),this.s ! a.s d.ZERO.subTo(b, b) } function B(a) {for (var b this.abs(), c a.t 2 * b.t; --c 0; )a[c] 0;for (c 0; c b.t - 1; c) {var d b.am(c, b[c], a, 2 * c, 0, 1);(a[c b.t] b.am(c 1, 2 * b[c], a, 2 * c 1, d, b.t - c - 1)) b.DV (a[c b.t] - b.DV,a[c b.t 1] 1)}a.t 0 (a[a.t - 1] b.am(c, b[c], a, 2 * c, 0, 1)),a.s 0,a.clamp() } function C(a, b, c) {var f a.abs();if (!(f.t 0)) {var g this.abs();if (g.t f.t)return null ! b b.fromInt(0),void (null ! c this.copyTo(c));null c (c e());var h e(), i this.s, j a.s, k this.DB - t(f[f.t - 1]);k 0 ? (f.lShiftTo(k, h),g.lShiftTo(k, c)) : (f.copyTo(h),g.copyTo(c));var l h.t, m h[l - 1];if (0 ! m) {var n m * (1 this.F1) (l 1 ? h[l - 2] this.F2 : 0), o this.FV / n, p (1 this.F1) / n, q 1 this.F2, r c.t, s r - l, u null b ? e() : b;for (h.dlShiftTo(s, u),c.compareTo(u) 0 (c[c.t] 1,c.subTo(u, c)),d.ONE.dlShiftTo(l, u),u.subTo(h, h); h.t l; )h[h.t] 0;for (; --s 0; ) {var v c[--r] m ? this.DM : Math.floor(c[r] * o (c[r - 1] q) * p);if ((c[r] h.am(0, v, c, s, 0, l)) v)for (h.dlShiftTo(s, u),c.subTo(u, c); c[r] --v; )c.subTo(u, c)}null ! b (c.drShiftTo(l, b),i ! j d.ZERO.subTo(b, b)),c.t l,c.clamp(),k 0 c.rShiftTo(k, c),0 i d.ZERO.subTo(c, c)}} } function D(a) {var b e();return this.abs().divRemTo(a, null, b),this.s 0 b.compareTo(d.ZERO) 0 a.subTo(b, b),b } function E(a) {this.m a } function F(a) {return a.s 0 || a.compareTo(this.m) 0 ? a.mod(this.m) : a } function G(a) {return a } function H(a) {a.divRemTo(this.m, null, a) } function I(a, b, c) {a.multiplyTo(b, c),this.reduce(c) } function J(a, b) {a.squareTo(b),this.reduce(b) } function K() {if (this.t 1)return 0;var a this[0];if (0 (1 a))return 0;var b 3 a;return b b * (2 - (15 a) * b) 15,b b * (2 - (255 a) * b) 255,b b * (2 - ((65535 a) * b 65535)) 65535,b b * (2 - a * b % this.DV) % this.DV,b 0 ? this.DV - b : -b } function L(a) {this.m a,this.mp a.invDigit(),this.mpl 32767 this.mp,this.mph this.mp 15,this.um (1 a.DB - 15) - 1,this.mt2 2 * a.t } function M(a) {var b e();return a.abs().dlShiftTo(this.m.t, b),b.divRemTo(this.m, null, b),a.s 0 b.compareTo(d.ZERO) 0 this.m.subTo(b, b),b } function N(a) {var b e();return a.copyTo(b),this.reduce(b),b } function O(a) {for (; a.t this.mt2; )a[a.t] 0;for (var b 0; b this.m.t; b) {var c 32767 a[b], d c * this.mpl ((c * this.mph (a[b] 15) * this.mpl this.um) 15) a.DM;for (c b this.m.t,a[c] this.m.am(0, d, a, b, 0, this.m.t); a[c] a.DV; )a[c] - a.DV,a[c]}a.clamp(),a.drShiftTo(this.m.t, a),a.compareTo(this.m) 0 a.subTo(this.m, a) } function P(a, b) {a.squareTo(b),this.reduce(b) } function Q(a, b, c) {a.multiplyTo(b, c),this.reduce(c) } function R() {return 0 (this.t 0 ? 1 this[0] : this.s) } function S(a, b) {if (a 4294967295 || 1 a)return d.ONE;var c e(), f e(), g b.convert(this), h t(a) - 1;for (g.copyTo(c); --h 0; )if (b.sqrTo(c, f),(a 1 h) 0)b.mulTo(f, g, c);else {var i c;c f,f i}return b.revert(c) } function T(a, b) {var c;return c 256 a || b.isEven() ? new E(b) : new L(b),this.exp(a, c) } function U() {this.i 0,this.j 0,this.S new Array } function V(a) {var b, c, d;for (b 0; 256 b; b)this.S[b] b;for (c 0,b 0; 256 b; b)c c this.S[b] a[b % a.length] 255,d this.S[b],this.S[b] this.S[c],this.S[c] d;this.i 0,this.j 0 } function W() {var a;return this.i this.i 1 255,this.j this.j this.S[this.i] 255,a this.S[this.i],this.S[this.i] this.S[this.j],this.S[this.j] a,this.S[a this.S[this.i] 255] } function X() {return new U } function Y(a) {qb[rb] ^ 255 a,qb[rb] ^ a 8 255,qb[rb] ^ a 16 255,qb[rb] ^ a 24 255,rb sb (rb - sb) } function Z() {Y((new Date).getTime()) } function $() {if (null pb) {for (Z(),pb X(),pb.init(qb),rb 0; rb qb.length; rb)qb[rb] 0;rb 0}return pb.next() } function _(a) {var b;for (b 0; b a.length; b)a[b] $() } function ab() {} function bb(a, b) {return new d(a,b) } function cb(a, b) {if (b a.length 11)return alert(Message too long for RSA),null;for (var c new Array, e a.length - 1; e 0 b 0; ) {var f a.charCodeAt(e--);128 f ? c[--b] f : f 127 2048 f ? (c[--b] 63 f | 128,c[--b] f 6 | 192) : (c[--b] 63 f | 128,c[--b] f 6 63 | 128,c[--b] f 12 | 224)}c[--b] 0;for (var g new ab, h new Array; b 2; ) {for (h[0] 0; 0 h[0]; )g.nextBytes(h);c[--b] h[0]}return c[--b] 2,c[--b] 0,new d(c) } function db() {this.n null,this.e 0,this.d null,this.p null,this.q null,this.dmp1 null,this.dmq1 null,this.coeff null } function eb(a, b) {null ! a null ! b a.length 0 b.length 0 ? (this.n bb(a, 16),this.e parseInt(b, 16)) : alert() } function fb(a) {return a.modPowInt(this.e, this.n) } function gb(a) {var b cb(a, this.n.bitLength() 7 3);if (null b)return null;var c this.doPublic(b);if (null c)return null;var d c.toString(16);return 0 (1 d.length) ? d : 0 d } var hb, ib 0xdeadbeefcafe, jb 15715070 (16777215 ib); jb Microsoft Internet Explorer navigator.appName ? (d.prototype.am g, hb 30) : jb Netscape ! navigator.appName ? (d.prototype.am f, hb 26) : (d.prototype.am h, hb 28), d.prototype.DB hb, d.prototype.DM (1 hb) - 1, d.prototype.DV 1 hb; var kb 52; d.prototype.FV Math.pow(2, kb), d.prototype.F1 kb - hb, d.prototype.F2 2 * hb - kb; var lb, mb, nb 0123456789abcdefghijklmnopqrstuvwxyz, ob new Array; for (lb 0.charCodeAt(0), mb 0; 9 mb; mb)ob[lb] mb; for (lb a.charCodeAt(0), mb 10; 36 mb; mb)ob[lb] mb; for (lb A.charCodeAt(0), mb 10; 36 mb; mb)ob[lb] mb; E.prototype.convert F, E.prototype.revert G, E.prototype.reduce H, E.prototype.mulTo I, E.prototype.sqrTo J, L.prototype.convert M, L.prototype.revert N, L.prototype.reduce O, L.prototype.mulTo Q, L.prototype.sqrTo P, d.prototype.copyTo k, d.prototype.fromInt l, d.prototype.fromString n, d.prototype.clamp o, d.prototype.dlShiftTo v, d.prototype.drShiftTo w, d.prototype.lShiftTo x, d.prototype.rShiftTo y, d.prototype.subTo z, d.prototype.multiplyTo A, d.prototype.squareTo B, d.prototype.divRemTo C, d.prototype.invDigit K, d.prototype.isEven R, d.prototype.exp S, d.prototype.toString p, d.prototype.negate q, d.prototype.abs r, d.prototype.compareTo s, d.prototype.bitLength u, d.prototype.mod D, d.prototype.modPowInt T, d.ZERO m(0), d.ONE m(1), U.prototype.init V, U.prototype.next W; var pb, qb, rb, sb 256; if (null qb) {qb new Array,rb 0;var tb;if (window.crypto window.crypto.getRandomValues) {var ub new Uint8Array(32);for (window.crypto.getRandomValues(ub),tb 0; 32 tb; tb)qb[rb] ub[tb]}if (Netscape navigator.appName navigator.appVersion 5 window.crypto) {var vb window.crypto.random(32);for (tb 0; tb vb.length; tb)qb[rb] 255 vb.charCodeAt(tb)}for (; sb rb; )tb Math.floor(65536 * Math.random()),qb[rb] tb 8,qb[rb] 255 tb;rb 0,Z() } ab.prototype.nextBytes _, db.prototype.doPublic fb, db.prototype.setPublic eb, db.prototype.encrypt gb, RSAKey dbfunction getEncryptedPwd(pwd, modulus, publicExponent) {c new RSAKey;c.setPublic(modulus, publicExponent);var d c.encrypt(pwd);return d; } 运行结果 python编写脚本运行此JS代码 import execjspassword 123 # 模拟的密码随便写的 modulus 00833c4af965ff7a8409f8b5d5a83d87f2f19d7c1eb40dc59a98d2346cbb145046b2c6facc25b5cc363443f0f7ebd9524b7c1e1917bf7d849212339f6c1d3711b115ecb20f0c89fc2182a985ea28cbb4adf6a321ff7e715ba9b8d7261d1c140485df3b705247a70c28c9068caabbedbf9510dada6d13d99e57642b853a73406817 publicExponent 010001def make_execjs_object():with open(en_pwd.js, r) as f:js f.read()return execjs.compile(js)js_object make_execjs_object()a js_object.call(getEncryptedPwd, password, modulus, publicExponent) print(a) 运行结果 loginID 参数 步骤同上面的enpassword一步步搜索会发现找到了图中的J_RsaAccout,这个就是loginID参数的加密我们继续一步步分析会发现此参数的加密方式和刚刚的enpassword的加密方式一模一样那处理方法不就简单了 JS加密账号函数直接将下面的JS函数加入刚刚自己改写的JS代码文件中即可 function getEncryptedAccount(account, modulus, publicExponent) {c new RSAKey;c.setPublic(modulus, publicExponent);var d c.encrypt(account);return d; }Python调用JS加密函数编写爬虫脚本文件时用以下函数调用JS文件生成所需参数形同enpassword的写法 def make_encrypt_account(self, account, modulus, publicExponent):生成加密后的账号Args:account (str): 输入框内输入的账号modulus (str): 同上publicExponent (str): 同上Returns:str: 加密后的账号return self.js_object.call(getEncryptedAccount, account, modulus, publicExponent)运行结果 FingerPrint和FingerPrintDetail参数 找到指纹加密的主函数会发现就在刚刚的函数下面 分析函数功能 这里比较不好理解的是$.fingerprint.details和$.fingerprint.result这两个变量的定义位置是下面图片这里 这两个值也都是固定值据观察其中c的值就是使用者计算机的一些属性只要计算机不换这些值就是固定的所以我们直接传固定值即可它也不知道你电脑信息是啥样的呀而且d的值是根据c的值得出的所以也可以写死后面编写爬虫代码时直接复制此处的值即可 修改FingerPrint的JS函数 function rsaFingerprint(a, b, details, result) { //details和result是固定值直接作为参数传进来赋值 此处的a和b的值通过观察可知就是a.result.modulus和a.result.publicExponent这俩值前面获取过var c details, d result, e c.length, f , g new RSAKey;g.setPublic(a, b);for (var h g.encrypt(d), i 0; e i; i 117)f g.encrypt(c.substr(i, 117));// return {// details: f,// result: h// }return {fingerPrintDetail: f, //这里代码会返回字典类型的数据直接可以合并到表单里所以直接修改为表单里可以用的key值。当然不改也可fingerPrint: h} }Python调用JS加密函数 def make_rsa_fingerprint(self, modulus, publicExponent, details, result):生成rsa指纹参数Args:details (str): 请求headers信息result (str): headers的加密信息如果headers不改变这个值也是固定的Returns (dict):details: 加密后的fingerprint_details信息fingerPrintDetail表单参数result: 加密后的fingerprint_result信息fingerPrint表单参数return self.js_object.call(rsaFingerprint, modulus, publicExponent, details, result)运行结果 编写爬虫脚本 1首先编写脚本构造出post表单 import requests import jsonimport execjsclass Migu_login(object):def __init__(self, account, password):modules 00833c4af965ff7a8409f8b5d5a83d87f2f19d7c1eb40dc59a98d2346cbb145046b2c6facc25b5cc363443f0f7ebd9524b7c1e1917bf7d849212339f6c1d3711b115ecb20f0c89fc2182a985ea28cbb4adf6a321ff7e715ba9b8d7261d1c140485df3b705247a70c28c9068caabbedbf9510dada6d13d99e57642b853a73406817publicExponent 010001# 获取FingerPrint和FingerPrintDetail参数中JS函数所需的参数c和ddetails_params {user_agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89,language:zh-CN,color_depth:24,pixel_ratio:1.25,hardware_concurrency:8,resolution:1536,864,available_resolution:1536,834,timezone_offset:-480,session_storage:1,local_storage:1,indexed_db:1,open_database:1,cpu_class:unknown,navigator_platform:Win32,do_not_track:unknown,regular_plugins:Chrome PDF Plugin::Portable Document Format::application/x-google-chrome-pdf~pdf,Chrome PDF Viewer::,webgl_vendor:Google Inc.~ANGLE (Intel(R) UHD Graphics 620 Direct3D11 vs_5_0 ps_5_0),adblock:false,has_lied_languages:false,has_lied_resolution:false,has_lied_os:false,has_lied_browser:false,touch_support:0,false,false,js_fonts:Arial,Arial Black,Arial Narrow,Arial Unicode MS,Book Antiqua,Bookman Old Style,Calibri,Cambria,Cambr}result_params 984eb0bda24963a23008f493d58a84e0headers {Accept: application/json, text/javascript, */*; q0.01,Accept-Encoding: gzip, deflate, br,Accept-Language: zh-CN,zh;q0.9,en;q0.8,Cache-Control: no-cache,Connection: keep-alive,Host: passport.migu.cn,Origin: https://passport.migu.cn,Referer: https://passport.migu.cn/login?sourceid208003apptype0forceAuthnfalseisPassivefalseauthTypeMiguPassportpasswordControl0displaywebrefererhttps://www.migu.cn/logintype1qqnullweibonullalipaynullweixinnullandPassnullphoneNumbercallbackURLhttps%3A%2F%2Fwww.migu.cn%2FrelayState,Sec-Fetch-Dest: empty,Sec-Fetch-Mode: cors,Sec-Fetch-Site: same-origin,User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36,X-Requested-With: XMLHttpRequest,}self.form {# 需要传递的构造出来的参数先写空后面再使用update即可sourceID: 208003,appType: 0,relayState: ,loginID:, # 加密后的账号enpassword: , # 加密后的密码captcha: ,rememberMeBox: 1,fingerPrint: , # 指纹fingerPrintDetail:, # 指纹detailisAsync: True,}# 开启会话保持连接self.session requests.Session()self.session.headers headersself.get_cookie()# Python执行JS代码生成所需参数并更新进表单self.js_object self.compile_js()update_form self.make_rsa_fingerprint(modules, publicExponent, details_params, result_params)update_form[loginID] self.make_encrypt_account(account, modules, publicExponent)update_form[enpassword] self.make_encrypt_password(password, modules, publicExponent)self.form.update(update_form)def compile_js(self):python直接执行本地编写的JS代码:return:with open(en_pwd.js, r) as f:js f.read()return execjs.compile(js)def get_cookie(self):为了让会话携带cookie所以进行如下操作。因为使用的session会话技术所以即使不return也携带了cookie等一系列参数。:return:url https://passport.migu.cn/self.session.get(url)return self.session.cookiesdef make_encrypt_password(self, password, modulus, publicExponent):生成加密后的密码Args:password (str): 输入框内输入的原始密码modulus (str): rsa加密参数两个质数的乘积固定值前一个请求获得publicExponent (str): rsa加密参数大于1的奇数固定值前一个请求获得Returns:str: 加密后的密码return self.js_object.call(getEncryptedPwd, password, modulus, publicExponent)def make_encrypt_account(self, account, modulus, publicExponent):生成加密后的账号Args:account (str): 输入框内输入的账号modulus (str): 同上publicExponent (str): 同上Returns:str: 加密后的账号return self.js_object.call(getEncryptedAccount, account, modulus, publicExponent)def make_rsa_fingerprint(self, modulus, publicExponent, details, result):生成rsa指纹参数Args:details (str): 请求headers信息result (str): headers的加密信息如果headers不改变这个值也是固定的Returns (dict):details: 加密后的fingerprint_details信息fingerPrintDetail表单参数result: 加密后的fingerprint_result信息fingerPrint表单参数return self.js_object.call(rsaFingerprint, modulus, publicExponent, details, result) 2然后编写脚本发送请求并通过获取响应判断是否登录成功 分析可知我们应该向如上图中的url携带表单发送post请求 第一步直接向其发送请求观察响应是否为登录成功的界面 def login(self):登录函数:return: url https://passport.migu.cn/authnresponse self.session.post(url, dataself.form)print(response.text)if __name__ __main__:# 注意账号密码放在了info.txt中with open(info.txt, r) as f:info json.loads(f.read())act info[account]pwd info[password]mg Migu_login(act,pwd)mresponse mg.login()观察响应分析可知当我们登录成功之后页面进行了重定向而不是直接返回给我们登录成功的界面 第二步所以下面我们要做的就是通过分析浏览器登录找到一系列的重定向的URL并找到最终返回登录成功界面的URL 第一个登录成功之后出现的URL很容易知道这就是登录后的重定向其URL的构造只需要拼接token参数即可token参数在刚刚的响应中又存在直接提取即可 第二个登录成功之后出现的URL多次测试可知其URL是固定值 第三个登录成功之后出现的URL图一中多次测试也可知其URL是固定值图二中可知此URL刚好是由上一个URL跳转来的图三可知此URL的响应刚好是登录成功的界面 第三步构造登录成功之后的重定向URL并通过依此请求模拟网站登录时候的一次次重定向跳转最终达到获取咪咕登录成功的界面 def login(self):登录函数:return:url https://passport.migu.cn/authnresponse self.session.post(url, dataself.form)response_dict json.loads(response.text)token response_dict.get(result,{}).get(token, )if not token:returnrest_url [https://passport.migu.cn/portal/sso/authn?callbackURLrelayStatetoken{}.format(token),https://passport.migu.cn/portal/sso/authn_success?relateToMiguPassport1callbackURLrelayState,https://passport.migu.cn/portal/home/profile?sourceid100001,https://passport.migu.cn/portal/home/profile?sourceid100001,]for ru in rest_url:response self.session.get(ru)return responseif __name__ __main__:with open(info.txt, r) as f:info json.loads(f.read())act info[account]pwd info[password]mg Migu_login(act,pwd)mresponse mg.login()print(mresponse.text)3观察可知登录成功 项目源码链接 代码 链接https://pan.baidu.com/s/1zM19dGyvEpX4BuXsr_8s7Q 提取码xkxh 复制这段内容后打开百度网盘手机App操作更方便哦
http://www.hkea.cn/news/14548380/

相关文章:

  • 东莞网站关键词优化收费wordpress author.php
  • 河池网站制作公司品牌营销咨询公司
  • 邯郸网站设计报价网站如何做后台
  • 个人网站建设方案书模板市场营销策略国内外研究现状
  • 网站推广方案注意事项建设银行网站未响应
  • 网站建设哪些会影响价格百度公司的企业文化
  • 百度权重查询爱站网禁止搜索引擎抓取wordpress的目录
  • 房地产网站 模板南通制作手机网站
  • 室内设计网站图片空壳网站清理
  • 网站开发实训基本要求如何自己制作网站
  • 使用万网怎么做网站吴忠网页设计
  • 河北怀来县建设局网站网站建设小程序定制开发
  • 自己建网站备案国内比百度好的搜索引擎
  • 阿里云搭建多个网站建筑招聘
  • 网站调用wordpress建设网站需要注册证书吗
  • wordpress 4.9 站群南京网络推广公司排行榜
  • 注册网址怎么注册步骤长沙百度seo代理
  • 网站开发周期表重庆网站外包
  • 西安 医疗网站建设拓者吧室内设计网站
  • 电商网站开发技术难点网站 兼容性
  • 亚马逊的海外网站怎么做网站设计图
  • 海淘网站开发怎样建个自己的网站
  • 网站怎么做301wordpress登录你将在2秒引导
  • 物流企业网站建设方案wordpress 过滤钩子
  • 美食网站源代码网站外链作用
  • 门户网站的案例分析腾讯企业邮箱网页版登录入口
  • 内销网站怎么做2345网址导航智能主板
  • 做网站运营很累吧wordpress 屏蔽工具条
  • 简述网站推广的方法广告设计公司实践报告
  • 市场监督管理局不处理问题怎么办seo排名优化培训怎样