原文链接 模仿登录系列 | QQ空间模仿登录mp.weixin.电话.com/s/Awnj0x_E7XJtbOW_7OBwbA 本系列所有代码均在那 CharlesPikachu/DecryptLogingithub.com/CharlesPikachu/DecryptLogin 原理简介
那里,我们简单介绍下模仿登录QQ空间的原理。一般地,QQ空间能够通过手机QQ扫码登录和账号密码登录。但是账号密码登录有时候需要验证码,为了包管登录的胜利率,我们选择扫码登录的体例。
起首,进入登录界面:
https://xui.ptlogin2.电话.com/cgi-bin/xlogin?proxy_url=https://qzs.电话.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=https://qzs.电话.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=手机QQ空间&pt_qr_link=https://z.qzone.com/download.html&self_regurl=https://qzs.电话.com/qzone/v6/reg/index.html&pt_qr_help_link=https://z.qzone.com/download.html&pt_no_auth=0简单抓包能够发现二维码登录的接口很可能是那个(ptqrlogin看着就像是二维码登录):
看下恳求那个链接需要哪些参数吧:
测试一下,能够发现大部门参数是固定的,即:
u1:https://qzs.电话.com/qzone/v5/loginsucc.html?para=izone ptredirect: 0 h: 1 t: 1 g: 1 from_ui: 1 ptlang: 2052 js_ver: 19112817 js_type: 1 pt_uistyle: 40 aid: 549000912 daid: 5 ptdrvs: AnyQUpMB2syC5zV6V4JDelrCvoAMh-HP6Xy5jvKJzHBIplMBK37jV1o3JjBWmY7j*U1eD8quewY_ has_onekey: 1所以我们只需要晓得以下参数就行啦:
action login_sig ptqrtoken很显然,action的构造体例应该是如许的:
0-0-+时间戳至于login_sig参数,容易发现能够通过恳求以下链接:
然后在返回的cookies里得到login_sig参数。
而恳求:
https://xui.ptlogin2.电话.com/cgi-bin/xlogin?需要照顾的参数为:
通过测试能够发现上面那些参数都是固定的。最初就剩下ptqrtoken那个参数啦,全局搜刮一下,能够发现ptqrtoken那个参数在某个js文件里写了计算体例:
此中,hash33的js代码为:
function hash33(t) { for (var e = 0, i = 0, n = t.length; i < n; ++i) e += (e << 5) + t.charCodeAt(i); return 2147483647 & e }转为python代码就是:
def decryptQrsig(qrsig): e = 0 for c in qrsig: e += (e << 5) + ord(c) return 2147483647 & e那么,如今的问题就是qrsig那个参数若何获得呢?和login_sig参数类似,容易发现恳求以下那个链接:
在返回的cookies里能够得到qrsig那个参数的值:
而恳求:
https://ssl.ptlogin2.电话.com/ptqrshow需要照顾的参数如下图所示:
除了t其他参数都是稳定的,觉得t像个随机数(因为测试了下,发现t就算不断连结稳定也不妨),既然影响不大,就懒得继续阐发t到底是个啥了,就当是个随机数呗(归正位数也都是16位)。
OK,到此为行,我们大要已经领会了整个模仿登录的流程了,那就起头边写代码边进一步明白该流程呗~起首天然是获得login_sig参数:
params = { proxy_url: https://qzs.电话.com/qzone/v6/portal/proxy.html, daid: 5, hide_title_bar: 1, low_login: 0, qlogin_auto_login: 1, no_verifyimg: 1, link_target: blank, appid: 549000912, style: 22, target: self, s_url: https://qzs.电话.com/qzone/v5/loginsucc.html?para=izone, pt_qr_app: 手机QQ空间, pt_qr_link: https://z.qzone.com/download.html, self_regurl: https://qzs.电话.com/qzone/v6/reg/index.html, pt_qr_help_link: https://z.qzone.com/download.html, pt_no_auth: 0 } res = self.session.get(self.xlogin_url, headers=self.headers, verify=False, params=params) all_cookies.update(requests.utils.dict_from_cookiejar(res.cookies)) pt_login_sig = all_cookies[pt_login_sig]然后获得ptqrtoken参数:
params = { appid: 549000912, e: 2, l: M, s: 3, d: 72, v: 4, t: str(random.random()), daid: 5, pt_3rd_aid: 0 } res = self.session.get(self.qrshow_url, headers=self.headers, verify=False, params=params) all_cookies.update(requests.utils.dict_from_cookiejar(res.cookies)) ptqrtoken = self.__decryptQrsig(all_cookies[qrsig])同时,在恳求上述链接的过程中,也就是:
https://ssl.ptlogin2.电话.com/ptqrshow我们还能够获得二维码图片(即res.content其实就是二维码的图片数据),并将其显示出来:
saveImage(res.content, qrcode.jpg) showImage(qrcode.jpg)接着我们通过不竭恳求一起头发现的二维码登录链接,即:
https://ssl.ptlogin2.电话.com/ptqrlogin来检测二维码当前的形态:
while True: params = { u1: https://qzs.电话.com/qzone/v5/loginsucc.html?para=izone, ptqrtoken: ptqrtoken, ptredirect: 0, h: 1, t: 1, g: 1, from_ui: 1, ptlang: 2052, action: 0-0- + str(int(time.time())), js_ver: 19112817, js_type: 1, login_sig: pt_login_sig, pt_uistyle: 40, aid: 549000912, daid: 5, ptdrvs: AnyQUpMB2syC5zV6V4JDelrCvoAMh-HP6Xy5jvKJzHBIplMBK37jV1o3JjBWmY7j*U1eD8quewY_, has_onekey: 1 } res = self.session.get(self.qrlogin_url, headers=self.headers, verify=False, params=params) if 登录胜利 in res.text: break elif 二维码已经失效 in res.text: raise RuntimeError(Fail to login, qrcode has expired...) time.sleep(2)若登录胜利,则用该恳求返回的链接来更新session的cookies从而获得最末的QQ空间登录会话对象:
all_cookies.update(requests.utils.dict_from_cookiejar(res.cookies)) 电话_number = re.findall(r&uin=(.+?)&service, res.text)[0] print([INFO]: Account -> %s, login successfully... % 电话_number) url_refresh = res.text[res.text.find(http): res.text.find(pt_3rd_aid=0)] + pt_3rd_aid=0 self.session.cookies.update(all_cookies) res = self.session.get(url_refresh, allow_redirects=False, verify=False) all_cookies.update(requests.utils.dict_from_cookiejar(res.cookies)) self.session.cookies.update(all_cookies)OK,大功乐成,完好源代码详见最前面的Github链接(小伙伴们记得随手给的星呀~)