class QQ: REFERER = 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2' def __init__(self): self.default_config = DefaultConfigs() self.req = HttpClient() self.friend_list = {} self.client_id = '53999199' self.ptwebqq = '' self.psessionid = '' self.appid = 0 self.vfwebqq = '' self.qrcode_path = self.default_config.conf.get("global", "qrcode_path") # QRCode保存路径 self.username = '' self.account = 0 def login_by_qrcode(self): logging.info("Requesting the login pages...") initurl_html = self.req.Get(self.default_config.conf.get("global", "smartqq_url")) initurl = get_revalue(initurl_html, r'\.src = "(.+?)"', "Get Login Url Error.", 1) html = self.req.Get(initurl + '0') appid = get_revalue(html, r'g_appid=encodeURIComponent\("(\d+)"\)', 'Get AppId Error', 1) sign = get_revalue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)', 'Get Login Sign Error', 0) js_ver = get_revalue(html, r'g_pt_version=encodeURIComponent\("(\d+)"\)', 'Get g_pt_version Error', 1) mibao_css = get_revalue(html, r'g_mibao_css=encodeURIComponent\("(.+?)"\)', 'Get g_mibao_css Error', 1) start_time = date_to_millis(datetime.datetime.utcnow()) error_times = 0 ret = [] while True: error_times += 1 self.req.Download('https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=L&s=8&d=72&v=4'.format(appid), self.qrcode_path) logging.info("Please scan the downloaded QRCode") while True: time.sleep(1) html = self.req.Get( 'https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid={0}&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-{1}&mibao_css={2}&t=undefined&g=1&js_type=0&js_ver={3}&login_sig={4}'.format( appid, date_to_millis(datetime.datetime.utcnow()) - start_time, mibao_css, js_ver, sign), initurl) logging.debug("QRCode check html: " + str(html)) ret = html.split("'") if ret[1] in ('0', '65'): # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中 break if ret[1] == '0' or error_times > 10: break if ret[1] != '0': return logging.info("QRCode scaned, now logging in.") # 删除QRCode文件 if os.path.exists(self.qrcode_path): os.remove(self.qrcode_path) # 记录登陆账号的昵称 self.username = ret[11] html = self.req.Get(ret[5]) url = get_revalue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0) if url != '': html = self.req.Get(url.replace('&', '&')) url = get_revalue(html, r'location\.href="(.+?)"', 'Get Redirect Url Error', 1) self.req.Get(url) self.ptwebqq = self.req.getCookie('ptwebqq') logging.debug("ptwebqq: %s", self.ptwebqq) ret = {} html = self.req.Get( 'http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid=&t={2}'.format( self.ptwebqq, self.client_id, start_time), 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2') logging.debug("getvfwebqq: %s", str(html)) ret = json.loads(html) if ret['retcode'] != 0: logging.error("http://s.web2.qq.com/api/getvfwebqq: %s", html) return False, "get vfwebqq failed!" self.vfwebqq = ret['result']['vfwebqq'] html = self.req.Post( 'http://d1.web2.qq.com/channel/login2', {'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"","status":"online"}}'.format(self.ptwebqq, self.client_id)}, 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2') try: ret = json.loads(html) logging.debug(html) self.psessionid = ret['result']['psessionid'] except Exception as ex: logging.error("http://d1.web2.qq.com/channel/login2: %s, %s", ex, html) return False, "get psessionid failed!" self.account = ret['result'].get('uin') logging.info("QQ:{0} login successfully, Username:{1}".format(self.account, self.username)) return True, "success" def relogin(self, error_times=0): if error_times >= 10: return False try: html = self.req.Post('http://d.web2.qq.com/channel/login2', { 'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","key":"","status":"online"}}'.format( self.ptwebqq, self.client_id, self.psessionid) }, self.default_config.conf.get("global", "connect_referer")) ret = json.loads(html) logging.debug("relogin html: " + str(html)) self.vfwebqq = ret['result']['vfwebqq'] self.psessionid = ret['result']['psessionid'] return True except: logging.info("login fail, retryng..." + str(error_times)) return self.relogin(error_times + 1) def check_msg(self, error_times=0): # if error_times >= 5: # if not self.relogin(): # raise IOError("Account offline.") # else: # error_times = 0 # 调用后进入单次轮询,等待服务器发回状态。 # params = dict(ptwebqq=self.ptwebqq, clientid=self.client_id, psessionid=self.psessionid, key="") html = self.req.Post( 'http://d1.web2.qq.com/channel/poll2', {'r': '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'.format(self.psessionid, self.ptwebqq, self.client_id)}, 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2' ) logging.debug("check_msg html: " + str(html)) try: if html == "": return self.check_msg() ret = json.loads(html) ret_code = ret['retcode'] if ret_code in (102,): logging.info("received retcode: " + str(ret_code) + ": No message.") time.sleep(1) return if ret_code in (103,): logging.warning("received retcode: " + str(ret_code) + ": Check error.retrying.." + str(error_times)) time.sleep(1) return self.check_msg(error_times + 1) if ret_code in (121,): logging.warning("received retcode: " + str(ret_code)) return self.check_msg(5) elif ret_code == 0: msg_list = [] pm_list = [] sess_list = [] group_list = [] notify_list = [] for msg in ret['result']: ret_type = msg['poll_type'] if ret_type == 'message': pm_list.append(PmMsg(msg)) elif ret_type == 'group_message': group_list.append(GroupMsg(msg)) elif ret_type == 'sess_message': sess_list.append(SessMsg(msg)) elif ret_type == 'input_notify': notify_list.append(InputNotify(msg)) elif ret_code == 'kick_message': notify_list.append(KickMessage(msg)) else: logging.warning("unknown message type: " + str(ret_type) + "details: " + str(msg)) group_list.sort(key=lambda x: x.seq) msg_list += pm_list + sess_list + group_list + notify_list if not msg_list: return return msg_list elif ret_code == 100006: logging.warning("POST data error") return elif ret_code == 116: self.ptwebqq = ret['p'] logging.info("ptwebqq updated.") return else: logging.warning("unknown retcode " + str(ret_code)) return except ValueError, e: logging.warning("Check error occured: " + str(e)) time.sleep(1) return self.check_msg(error_times + 1) except BaseException, e: logging.warning("Unknown check error occured, retrying. Error: " + str(e)) time.sleep(1) return self.check_msg(error_times + 1)
elif info["code"] in [40002, 40005, 40006, 40007]: self.reply("我遇到了一点问题,请稍后@我") logging.warning("PM AI return error, code:" + str(info["code"])) else: rpy = str(info["text"]).replace('<主人>', '你').replace('<br>', "\n") self.reply(rpy) return True except Exception, e: print e return False #开始 #登陆 msgId = 0 html = Client.Get(url_login) # session = requests.Session() # headers = { # 'Accept':'application/javascript, */*;q=0.8', # 'Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36', # } # html = session.get(url_login, headers=headers).text m = re.findall(r'\.src = "(.+?)"', html) if m: html = Client.Get(m[0]) # html = session.get(m[0]).text APPID = re.findall(r'g_appid\s*=\s*encodeURIComponent\s*\("(\d+)"', html)[0] sign = re.findall(r'g_login_sig\s*=\s*encodeURIComponent\s*\("(.+?)"\)', html)[0] JsVer = re.findall(r'g_pt_version\s*=\s*encodeURIComponent\s*\("(\d+)"\)', html)[0] MiBaoCss = re.findall(r'g_mibao_css\s*=\s*encodeURIComponent\s*\("(.+?)"\)', html)[0]
def SendQQMsg(uin, msg): SendMsg('send_buddy_msg2', uin, msg, 'to') def SendGroupMsg(qid, msg): SendMsg('send_qun_msg2', qid, msg, 'group_uin') logging.basicConfig(filename='qq.log', level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='[%Y-%m-%d %H:%M:%S]') http = HttpClient() initUrl = "https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=5&mibao_css=m_webqq&appid={0}&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=".format(APPID) html = http.Get(initUrl, 'http://web2.qq.com/webqq.html') sign = re.search(r'var g_login_sig=encodeURIComponent\("(.+?)"\);', html) if sign is None: logging.error('get login sign error') else: sign = sign.group(1) logging.info('get sign : %s', sign) html = http.Get("https://ssl.ptlogin2.qq.com/check?pt_tea=1&uin={0}&appid={1}&js_ver=10116&js_type=0&login_sig={2}&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.5331138293443659".format(QQ, APPID, sign), initUrl) logging.debug(html)
import urllib2,cookielib import re from HttpClient import HttpClient def getReValue(self, html, rex, er, ex): v = re.search(rex, html) if v is None:#如果匹配失败 if ex:#如果条件成立,则抛异常 raise Exception, er return '' return v.group(1)#返回匹配到的内容 smartQQUrl=r'http://w.qq.com/login.html' httpclient=HttpClient() #获得二维码地址 initUrl=getReValue(httpclient.Get(smartQQUrl),r'\.src = "(.+?)"', 'Get Login Url Error.', 1) #获取二维码html refer=r'http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2' html=httpclient.Get(initUrl+'0',smartQQUrl) APPID=getReValue(html,r'g_appid=encodeURIComponent\("(\d+)"\)','Get AppId Error', 1) sign =getReValue(html, r'g_login_sig=encodeURIComponent\("(.*?)"\)', 'Get Login Sign Error', 1)