class Login(object): def __init__(self): self.login_get_cookies_url = "https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20131024001" self.get_ptqrshow = "https://ssl.ptlogin2.qq.com/ptqrshow?appid=501004106&e=0&l=M&s=5&d=72&v=4&t=0.9142399367333609" self.check = "https://ssl.ptlogin2.qq.com/ptqrlogin?ptqrtoken={ptqrtoken}&webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-32750&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10197&login_sig=&pt_randsalt=0" self.code = open('code.png', 'w') self.jm = "http://jiema.wwei.cn/fileupload/index/op/jiema.html" self.logger = Logger('Login') self.getvfwebqq = "http://s.web2.qq.com/api/getvfwebqq?ptwebqq={ptwebqq}&clientid=53999199&psessionid=&t=1488053293431" self.login2 = "http://d1.web2.qq.com/channel/login2" self.online = "http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq={vfwebqq}&clientid=53999199&psessionid={psessionid}&t=1488268527333" def run(self): #开启一个session会话用来获取基础cookies以及获取二维码及其cookies base = requests.session() #访问获取基础cookies的地址 result = base.get(self.login_get_cookies_url) base_cookies = result.cookies #基础cookies #获取二维码图片并获取二维码cookies result = base.get(self.get_ptqrshow) ptqr_cookies = result.cookies #二维码cookies #将二维码图片上传解码后进行二维码生成并打印到终端 self.code.write(result.content) self.code.close() cookies = dict(base_cookies.items() + ptqr_cookies.items()) #进行ptqrtoken计算 qrsig = cookies['qrsig'] e = 0 n = len(qrsig) for i in range(0, n): e = e + (e << 5) + ord(qrsig[i]) ptqrtoken = 2147483647 & e #计算完成 #上传二维码图片解码,然后打印二维码到控制台 try: rtext = requests.post(self.jm, files={'file': open('code.png', 'rb')}) except Exception as e: self.logger.debug('upload qcord error') if rtext.status_code == 200: try: jtext = json.loads(rtext.text) except ValueError as e: self.logger.error('二维码解析返回不正常') return {'result': '-1', 'reason': '二维码解析返回不正常'} self.logger.info('请扫描屏幕中的二维码') url = jtext['jiema'] #将二维码打印到控制台 qrcode_terminal.draw(url) #循环验证二维码状态 l = 0 k = 0 j = 0 while True: result = requests.get( "https://ssl.ptlogin2.qq.com/ptqrlogin?ptqrtoken=" + str(ptqrtoken) + "&webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-32750&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10197&login_sig=&pt_randsalt=0", cookies=cookies) if '二维码未失效' in result.text: if l == 0: self.logger.info('二维码未失效,等待扫码验证中') l = l + 1 if '已失效' in result.text: if k == 0: self.logger.info('二维码已经失效') k = k + 1 return {'result': '-1', 'reason': '二维码已经失效'} if '认证中' in result.text: if j == 0: self.logger.info('二维码已被扫描,正在认证中') j = j + 1 if '登录成功' in result.text: checksig_url = result.text.split("','")[2] user_cookies = result.cookies break time.sleep(1) #获取cookie中ptwebqq ptwebqq = user_cookies['ptwebqq'] result = requests.get(checksig_url, cookies=user_cookies, allow_redirects=False) user2_cookies = result.cookies #合并两个cookies user3_cookies = dict(user_cookies.items() + user2_cookies.items()) #获取vfwebqq headers = { "Referer": "http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1" } vfwebqq = requests.get(self.getvfwebqq.replace( '{ptwebqq}', ptwebqq), cookies=user3_cookies, headers=headers).text vfwebqq = json.loads(vfwebqq)['result']['vfwebqq'] #二次登陆,真正的登录 data = { 'r': '{"ptwebqq":"' + ptwebqq + '","clientid":53999199,"psessionid":"","status":"online"}' } headers = { 'Host': 'd1.web2.qq.com', 'Referer': 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2', 'Origin': 'http://d1.web2.qq.com' } result = requests.post(self.login2, data=data, cookies=user3_cookies, headers=headers) jresult = json.loads(result.text) if jresult['retcode'] == 0: self.logger.info('登录成功') uin = jresult["result"]["uin"] headers = { 'Host': 'd1.web2.qq.com', 'Referer': 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2' '' } requests.get(self.online.replace('{vfwebqq}', vfwebqq).replace( '{psessionid}', jresult['result']['psessionid']), cookies=user3_cookies, headers=headers) return { 'result': '0', 'reason': '登录成功', 'cookies': user3_cookies, 'psessionid': jresult['result']['psessionid'], 'vfwebqq': vfwebqq, 'uin': uin } else: self.logger.info('登录失败') return {'result': '-2', 'reason': '登录失败'} else: self.logger.error('解码发生错误,系统即将退出') return {'result': '-1', 'reason': '解码发生错误,系统即将退出'}
class Friends(object): def __init__(self, cookies, uin, vfwebqq): self.logger = Logger('Friends') self.db = sqlite3.connect(DB_CONFIG['SQLITE']) self.target = 'http://s.web2.qq.com/api/get_user_friends2' self.cookies = json.loads(cookies) self.header = { 'origin': 'https://d1.web2.qq.com', 'referer': 'https://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1' } self.hash = self.friendsHash(uin, self.cookies['ptwebqq']) self.data = { 'r': '{"vfwebqq":"' + vfwebqq + '","hash":"' + self.hash + '"}' } self.logger.info('清理过期数据') query = "delete from categories" self.db.execute(query) query = "delete from friends" self.db.execute(query) self.db.commit() self.getFriend() def getFriend(self): result = requests.post(self.target, headers=self.header, cookies=self.cookies, data=self.data) jresult = json.loads(result.text) if jresult['retcode'] == 0: self.logger.info('正在获取好友分组中') categories = jresult['result']['categories'] query = "insert into categories(groupId,name)values( ? , ? )" for i in categories: values = (i['index'], i['name']) try: self.db.execute(query, values) except Exception as e: self.logger.error(e) self.db.commit() self.logger.info('获取好友分组成功') self.logger.info('开始获取好友列表') friends = jresult['result']['friends'] query = "insert into friends(uin,groupid)values(? , ?)" for x in friends: values = (x['uin'], x['categories']) try: self.db.execute(query, values) except Exception as e: self.logger.error(e) self.logger.debug('0') self.db.commit() self.logger.info('获取好友列表成功,正在处理好友数据') marknames = jresult['result']['marknames'] query = "update friends set markname = ? where uin = ?" for j in marknames: uin = j['uin'] markname = j['markname'] values = (markname, uin) try: self.db.execute(query, values) except Exception as e: self.logger.error(e) self.logger.debug('1') self.db.commit() info = jresult['result']['info'] query = "update friends set nickname = ? where uin = ?" for k in info: uin = k['uin'] nickname = k['nick'] values = (nickname, uin) try: self.db.execute(query, values) except Exception as e: self.logger.error(e) self.logger.debug('2') self.db.commit() self.logger.info('数据处理完毕') def friendsHash(self, uin, ptwebqq): N = [0, 0, 0, 0] for t in range(len(ptwebqq)): N[t % 4] ^= ord(ptwebqq[t]) U = ["EC", "OK"] V = [0, 0, 0, 0] V[0] = int(uin) >> 24 & 255 ^ ord(U[0][0]) V[1] = int(uin) >> 16 & 255 ^ ord(U[0][1]) V[2] = int(uin) >> 8 & 255 ^ ord(U[1][0]) V[3] = int(uin) & 255 ^ ord(U[1][1]) U = [0, 0, 0, 0, 0, 0, 0, 0] for T in range(8): if T % 2 == 0: U[T] = N[T >> 1] else: U[T] = V[T >> 1] N = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ] V = "" for T in range(len(U)): V += N[U[T] >> 4 & 15] V += N[U[T] & 15] return V