By chance, I saw a QQ number in a group always reply automatically based on the message you sent. At that time, I felt amazing. I knew that I could simulate login to the website, but I did not expect that I could simulate login to QQ, first of all, I thought of how to simulate logon to the PC-end QQ. I started to study it and found it hard to understand the packets sent by QQ.
So I switched to the web version QQ, because all the requests can be captured on the Web page to better implement the simulation function!
The first step is to open the web version of qq, open the browser developer mode here to monitor all requests!
When the logon interface is opened
A GET request is captured.
Https://ssl.ptlogin2.qq.com/check? Uin = 10588690 & appid = 1003903 & js_ver = 10080 & js_type = 0 & login_sig = YW1ZUUsIU * weight & r = 0.5928007187321782
Uin is your QQ number.
The returned value is ptui_checkVC ("1", '20174bdjmeh2hea77ptuohhqmtxbrqop3', '\ x00 \ x00 \ x00 \ x00 \ x00 \ xa1 \ x92 \ x12 ');
Among them, 1 indicates that the verification code is required. There is also a return value ptui_checkVC ('0 ','! Ljv', '\ x00 \ x00 \ x00 \ x00 \ x00 \ xa1 \ x92 \ x12') indicates that the verification code is not required.
def CheckVerify(self,uin): check="https://ssl.ptlogin2.qq.com/check?uin={uin}&appid=1003903&js_ver=10080&js_type=0&login_sig=YPD0P*wu2n8vW1OS2f7VfzvPf3Ku5vnkP4nzImF0GybR02fsKZdjGYB7f9R7nQRn&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.8179273759014904" check=check.replace('{uin}',uin) pattern=re.compile("ptui_checkVC\('(.*)','(.*)','(.*)'\);") result=self.Get(check) checked= pattern.search(result).groups() print 'Step1: CheckVerify' return checked
How to obtain the verification code
def GetVerify(self): #url = 'https://ssl.captcha.qq.com/getimage?&uin='+str(self.QQ)+'&aid=1002101&0.45644426648505' + str(random.randint(10,99)) verify="https://ssl.captcha.qq.com/getimage?aid=1003903&r=0.6472875226754695&uin={QQ}&cap_cd=aSD-ZVcNEcozlZUurhNYhp-MBHf4hjbJ" verify=verify.replace('{QQ}',self.QQ) path= r"c:/verify/1.jpg" #data = urllib.urlretrieve(url,path) data = urllib2.urlopen(verify) localPic =open(r"c:/verify/1.jpg",'wb') localPic.write(data.read()) localPic.close() data.close()
Enter the user name, password, and verification code, and then send a GET request.
Https://ssl.ptlogin2.qq.com/login? %%3flogin2qq % 3D1% 26webqq_type % 3D10 & h = 1 & ptredirect = 0 & ptlang = 2052 & daid = 164 & from_ui = 1 & pttype = 1 & dumy = & fp = loginerroralert & action = 6-14-296574 & mibao_css = m_webqq & t = 1 & g = 1 & js_type = 0 & js_ver = 10080 & login_sig = YW1ZUUsIU * cursor & pt_uistyle = 5
Here, u represents account p, indicating that the password is encrypted by certain algorithms. verify is the verification code.
The encryption algorithm is as follows:
Def PasswordSecret (self, password, v1, v2, md5 = True): if md5 = True: password = self. PCMd5 (password ). upper () length = len (password) temp = ''for I in range (0, length, 2): temp + = R' \ x' + password [I: I + 2] return self. PCMd5 (self. PCMd5 (self. hex2asc (temp) + self. hex2asc (v2 )). upper () + v1 ). upper () # md5 encryption function def PCMd5 (self, s): h = hashlib. md5 () h. update (s) return h. hexdigest () # hexadecimal conversion character def hex2asc (self, s): _ str = "". join (s. split (R' \ x') length = len (_ str) data = ''for I in range (0, length, 2 ): data + = chr (int (_ str [I: I + 2], 16) return data
Then some login code
Def Login (self, uin, pwd): # obtain the cheked = self. checkVerify (uin) # encrypted password # pwd = self. passwordSecret (pwd, cheked [1], cheked [2]) # pwd = self. passwordSecret (pwd, r 'aast ', R' \ x00 \ x00 \ x00 \ x00 \ x00 \ xa1 \ x92 \ x12') loginurl = "https://ssl.ptlogin2.qq.com/login? %%3flogin2qq % 3D1% 26webqq_type % 3D10 & h = 1 & ptredirect = 0 & ptlang = 2052 & daid = 164 & from_ui = 1 & pttype = 1 & dumy = & fp = loginerroralert & action = 4-30-135914 & mibao_css = m_webqq & t = 1 & g = 1 & js_type = 0 & js_ver = 10080 & login_sig = YPD0P * cursor & pt_uistyl E = 5 "loginurl = loginurl. replace ('{uin}', uin) # loginurl = loginurl. replace ('{pwd}', pwd) # loginurl = loginurl. replace ('{verify}', cheked [1]) # result = Get (loginurl) if (cheked [0] = "1"): # download the verification code self. getVerify () image = Image. open (r "c:/verify/1.jpg") image. show () code = raw_input ("verifycode :"). strip () loginurl = loginurl. replace ('{verify}', code. upper () pwd = self. passwordSecret (pwd, r'' + code. upper (), cheked [2]) # pwd = Self. passwordSecret (pwd, cheked [1], cheked [2]) else: loginurl = loginurl. replace ('{verify}', cheked [1]) pwd = self. passwordSecret (pwd, cheked [1], cheked [2]) loginurl = loginurl. replace ('{pwd}', pwd) result = self. get (loginurl, 'ssl .ptlogin2.qq.com ', 'https: // ui.ptlogin2.qq.com/cgi-bin/login? Logs & f_url = loginerroralert & strong_login = 1 & login_state = 10 & t = 20140514001 ', None) print 'step2: login' pattern = re. compile ("ptuiCB \('(. *)','(. *)','(. *)','(. *)','(. *) ', \ s '(. *) '\); ") ret = pattern. search (result ). groups () # obtain the necessary cookies. Otherwise, the second login will fail. self. get (ret [2]) print 'step3: GetCookie 'for c in self. cj: if c. name = "ptwebqq": self. ptwebqq = c. value return result
After successful login, the server will return a string of json data
PtuiCB ('0', '0', 'HTTP: // ptlogin4.web2.qq.com/check_sig? Pttype = 1 & uin = 10588690 & service = login & nodirect = 0 & ptsig = * pushed % 3Flogin2qq % 3D1% 26webqq_type % 3D10 & f_url = & ptlang = 2052 & ptredirect = 100 & aid = 1003903 & daid = 164 & j_later = 0 & low_login_hour = 0 & regmaster = 0 & pt_login_type = 1 & pt_aid = 0 & pt_aaid = 0 & pt_light = 0 ', '0', 'logon successful! ', 'Bambo ');
If the first value is 0, the logon is successful, but the logon is not successful.
The url in the returned value is used to obtain a key cookie, that is, ptwebqq.
Then perform the second login. This is the real login.
Http://d.web2.qq.com/channel/login2
The request is as follows:
- Accept :*/*
- Accept-Encoding: gzip, deflate, sdch
- Accept-Language: zh-CN, zh; q = 0.8
- Connection: keep-alive
- Content-Length: 244
- Content-Type: application/x-www-form-urlencoded
- Cookie: o_cookie = 455910092; RK = Connecticut; ts_last = web2.qq.com/; ts_refer = www.baidu.com/; ts_uid = 4588821804; pgv_pvid = 914251705; pgv_info = ssid = s3525422600 & pgvReferrer =; verifysession = h02LeYrtarkWBZeSu_czkiczeNSNlDm7V1mCm-A5qatkwnHaNfgb2z46zH4X7OfyhFT7wH6LfschPvSLhDGXFA4eA **; Protocol = 10588690; ptisp = cnc; ptcz = platform; ptwebqq = platform; pt2gguin = o0010588690; uin = o0010588690; skey = @ terminal; p_uin = o0010588690; p_skey = cZ5 x kS-NOcXlD2Q0AEpJnmExwC2yA0g7jbTygpVFiA8 _; pt4_token = 1SyuJ39Eq6oKEwEhGIizeg __
- Host: d.web2.qq.com
- Origin: http://d.web2.qq.com
- Referer: http://d.web2.qq.com/proxy.html? V= 20110331002 & callback = 1 & id = 2
- User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36
- Form Dataview sourceview URL encoded
- R: {"status": "online", "ptwebqq": "success", "passwd_sig": "", "clientid": "7963288", "psessionid": null}
- Client ID: 7963288
- Psessionid: null
The ptwebqq is the one we just obtained from the cookie.
This part of the code is
def Login2(self): try: url="http://d.web2.qq.com/channel/login2" postdata="r=%7B%22status%22%3A%22online%22%2C%22ptwebqq%22%3A%22{$ptwebqq}%22%2C%22passwd_sig%22%3A%22%22%2C%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3Anull%7D&clientid={$clientid}&psessionid=null" postdata=postdata.replace("{$ptwebqq}",self.ptwebqq) postdata=postdata.replace("{$clientid}",str(self.clientid)) print 'Step4: Login2' result=self.Post(url,postdata,QQRobot.HOST[0],QQRobot.REFERER[0],QQRobot.ORIGIN[0]) retjson=json.loads(result) retjson=retjson["result"] return retjson except Exception,e: print "Login2 error "+str(e)
Update again tomorrow ......