def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) if self.cmdQrcode: try: showCmdQRCode(self.qrcodePath) except Exception as e: WARN('无法以文本模式显示二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if not (self.qrcodeServer or self.mailAgent or self.cmdQrcode): try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址: %s', self.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode)
def sendEmail(self): lastSubject = '' while True: if lastSubject != self.qrcodeMail['subject']: qrcode = self.qrcode.getVal() if qrcode is None: break qrcode = '' if self.qrcodeServer else qrcode try: with self.mailAgent.SMTP() as smtp: smtp.send(png_content=qrcode, **self.qrcodeMail) except Exception as e: WARN('无法将二维码发送至邮箱%s %s', self.mailAgent.account, e, exc_info=True) else: INFO('已将二维码发送至邮箱%s', self.mailAgent.account) if self.qrcodeServer: break else: lastSubject = self.qrcodeMail['subject'] else: time.sleep(65) qrcode = self.qrcode.getVal() if qrcode is None: break try: DEBUG('开始查询邮箱 %s 中的最近的邮件', self.mailAgent.account) with self.mailAgent.IMAP() as imap: lastSubject = imap.getSubject(-1) except Exception as e: WARN('查询邮箱 %s 中的邮件失败 %s', self.mailAgent.account, e) else: DEBUG('最近的邮件: %s', lastSubject)
def Run(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((HOST, self.port)) self.sock.listen(5) except socket.error as e: WARN('无法开启 QQBot term 服务器。%s', e) WARN(' qq 命令无法使用') else: time.sleep(0.1) INFO('已在 %s 端口开启 QQBot-Term 服务器,', self.port) INFO('请在其他控制台窗口使用 qq 命令来控制 QQBot ,' '示例: qq send buddy jack hello') while True: try: sock, addr = self.sock.accept() except socket.error: WARN('QQBot-Term 服务器出现 accept 错误') else: name = 'QTerm客户端"%s:%s"' % addr sock.settimeout(5.0) try: data = sock.recv(1024) except socket.error: sock.close() else: content = BYTES2STR(data) INFO('QTerm 命令:%s', content) yield TermMessage(name, sock, content)
def Run(self, onCommand=None): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((HOST, self.port)) self.sock.listen(5) except socket.error as e: WARN('无法开启 QQBot term 服务器。%s', e) WARN(' qq 命令无法使用') else: time.sleep(0.1) INFO('已在 %s 端口开启 QQBot-Term 服务器,', self.port) INFO('QQBot 已启动,请在其他控制台窗口使用 qq 命令来控制 QQBot ,' '示例: qq send buddy jack hello') while True: try: sock, addr = self.sock.accept() except socket.error: WARN('QQBot-Term 服务器出现 accept 错误') else: name = 'QTerm客户端"%s:%s"' % addr sock.settimeout(5.0) try: data = sock.recv(8192) except socket.error: sock.close() else: command = BYTES2STR(data) # INFO('QTerm 命令:%s', repr(command)) Put(onCommand, Client(name, sock), command)
def QLogin(qq=None, user=None): conf = QConf(qq, user) conf.Display() if conf.qq: INFO('开始自动登录...') picklePath = conf.PicklePath() session = QSession() contactdb = QContactDB(session) try: contactdb.Restore(picklePath) except Exception as e: WARN('自动登录失败,原因:%s', e) else: INFO('成功从文件 "%s" 中恢复登录信息' % picklePath) try: contactdb.session.TestLogin() except RequestError: WARN('自动登录失败,原因:上次保存的登录信息已过期') except Exception as e: WARN('自动登录失败,原因:%s', e) DEBUG('', exc_info=True) else: return contactdb.session.Copy(), contactdb, conf INFO('开始手动登录...') session = QSession() session.Login(conf) contactdb = QContactDB(session, conf.PicklePath()) contactdb.Dump() return session.Copy(), contactdb, conf
def task(bot): global firstcheck new_member = [] # g is list g = bot.List('group', groupid) if firstcheck is True: bot.Update(g[0]) firstcheck = False if g is None: WARN('向 QQ 服务器请求联系人列表和资料失败') elif not g: INFO('该联系人列表内没有和 cinfo 匹配的联系人') elif g: # group_* is object ml_old = copy.copy(bot.List(g[0])) # update group_member list if bot.Update(g[0]): ml_latest = copy.copy(bot.List(g[0])) if len(ml_latest) > len(ml_old): for mb in map(str, ml_latest): if mb not in map(str, ml_old): new_member.append(mb) for group in g: msg = '欢迎' if (len(ml_latest) - len(ml_old)) < len(new_member): msg += str(len(ml_latest) - len(ml_old)) + '位新聚聚加入本群' else: for vl in new_member: msg += '新' + str(vl) msg += '加入本群' bot.SendTo(group, msg) bot.SendTo(group, setting.welcome()) new_member = [] else: WARN('更新联系人列表和资料失败')
def QLogin(qq=None, user=None, conf=None): if not conf: conf = QConf(qq, user) conf.Display() if conf.qq: INFO('开始自动登录...') picklePath = conf.PicklePath() session = QSession() try: with open(picklePath, 'rb') as f: session.__dict__ = pickle.load(f) session.dbname = conf.absPath(session.dbbasename) except Exception as e: WARN('自动登录失败,原因:%s', e) else: INFO('成功从文件 "%s" 中恢复登录信息' % SYSTEMSTR2STR(picklePath)) try: session.TestLogin() except RequestError: WARN('自动登录失败,原因:上次保存的登录信息已过期') except Exception as e: WARN('自动登录失败,原因:%s', e) DEBUG('', exc_info=True) else: return session, QContactDB(session), conf if os.path.exists(session.dbname): try: os.remove(session.dbname) except OSError: pass except: WARN('', exc_info=True) INFO('开始手动登录...') session = QSession() session.Login(conf) picklePath = conf.PicklePath() try: with open(picklePath, 'wb') as f: pickle.dump((session.__dict__), f) except Exception as e: WARN('保存登录信息及联系人失败:%s %s', (e, SYSTEMSTR2STR(picklePath))) else: INFO('登录信息已保存至: %s' % SYSTEMSTR2STR(picklePath)) return session, QContactDB(session), conf
def membsOperation(self, group, membs, tag, func, exArg): if not membs: return [] try: ok = func(group.qq, [m.qq for m in membs], exArg) except RequestError: errInfo = '错误:' + tag + '失败(远程请求被拒绝)' result = [errInfo.format(m=str(m)) for m in membs] except Exception as e: WARN('', exc_info=True) errInfo = '错误:' + tag + '失败(' + str(e) + ')' result = [errInfo.format(m=str(m)) for m in membs] else: if ok: okInfo = '成功:' + tag result = [okInfo.format(m=str(m)) for m in membs] else: errInfo = '错误:' + tag + '失败(权限不够)' result = [errInfo.format(m=str(m)) for m in membs] for r in result: INFO(r) if r.startswith('成功') else ERROR(r) return result
def fetchBuddyTable(self): result = self.smartRequest( url = 'http://s.web2.qq.com/api/get_user_friends2', data = { 'r': JsonDumps({'vfwebqq':self.vfwebqq, 'hash':self.hash}) }, Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey = 'marknames', repeatOnDeny = 4 ) markDict = dict((str(d['uin']), str(d['markname'])) for d in result['marknames']) qqResult = self.smartRequest( url = 'http://qun.qq.com/cgi-bin/qun_mgr/get_friend_list', data = {'bkn': self.bkn}, Referer = 'http://qun.qq.com/member.html' ) qqDict = collections.defaultdict(list) for blist in list(qqResult.values()): for d in blist.get('mems', []): name = HTMLUnescape(d['name']) qqDict[name].append(str(d['uin'])) buddies, unresolved, resolvedQQ = [], [], set() for info in result['info']: uin = str(info['uin']) nick = str(info['nick']) mark = markDict.get(uin, '') name = mark or nick qqlist = qqDict.get(name, []) if len(qqlist) == 1: qq = qqlist[0] resolvedQQ.add(qq) else: qq = '#NULL' unresolved.append('好友“%s”(uin=%s)' % (name, uin)) # 各属性的顺序绝对不能变 buddies.append([qq, uin, nick, mark, name]) for blist in list(qqResult.values()): for d in blist.get('mems', []): name = HTMLUnescape(d['name']) qq = str(d['uin']) if qq not in resolvedQQ: buddies.append([qq, '-'+qq, '#NULL', '#NULL', name]) if unresolved: unresolved.sort() WARN('因存在重名或名称中含特殊字符,无法绑定以下好友的真实QQ号,请修改其备' '注名,保证备注名的唯一性且不带特殊字符:\n\t%s', '\n\t'.join(unresolved)) return buddies
def Plug(cls, moduleName): try: module = Import(moduleName) except (Exception, SystemExit) as e: cls.unplug(moduleName) cls.plugins.discard(moduleName) result = '错误:无法加载插件 %s ,%s: %s' % (moduleName, type(e), e) ERROR(result) else: cls.unplug(moduleName) names = [] for slotName in cls.slotsTable.keys(): if hasattr(module, slotName): cls.slotsTable[slotName].append(getattr(module, slotName)) names.append(slotName) if not names: INFO(module.__dict__.keys()) result = '警告:插件 %s 中不包含任何可注册的回调函数' % moduleName WARN(result) else: cls.plugins.add(moduleName) result = '成功:加载插件 %s%s' % (moduleName, names) INFO(result) return result
def monitor(self, monitorTables, session, bot): self.table('buddy') self.table('group') self.table('discuss') for tname in monitorTables[:]: if tname in ('buddy', 'group', 'discuss'): tl = [tname] elif tname.startswith('group-member-'): tl = self._table('group').List(tname[13:]) elif tname.startswith('discuss-member-'): tl = self._table('discuss').List(tname[15:]) else: tl = [] if not tl: WARN(('特别监视列表中的 "%s" 不存在,' '因此将其从特别监视列表中删除'), tname) monitorTables.remove(tname) else: PutTo('monitor-fetch', self.monitorFetch, session, tl, bot) if monitorTables: PutTo('monior-fetch', Put, self.monitor, monitorTables, session, bot)
def waitForAuth(self, conf): qrcodeManager = QrcodeManager(conf) try: qrcodeManager.Show(self.getQrcode()) x, y = 1, 1 while True: time.sleep(3) authStatus = self.getAuthStatus() if '二维码未失效' in authStatus: if x: INFO('等待二维码扫描及授权...') x = 0 elif '二维码认证中' in authStatus: if y: INFO('二维码已扫描,等待授权...') y = 0 elif '二维码已失效' in authStatus: WARN('二维码已失效, 重新获取二维码') qrcodeManager.Show(self.getQrcode()) x, y = 1, 1 elif '登录成功' in authStatus: INFO('已获授权') items = authStatus.split(',') self.nick = str(items[-1].split("'")[1]) self.qq = str(int(self.session.cookies['superuin'][1:])) self.urlPtwebqq = items[2].strip().strip("'") conf.qq = self.qq break else: CRITICAL('获取二维码扫描状态时出错, html="%s"', authStatus) sys.exit(1) finally: qrcodeManager.Destroy()
def Plug(cls, moduleName): cls.unplug(moduleName) try: module = Import(moduleName) except (Exception, SystemExit) as e: result = '错误:无法加载插件 %s ,%s: %s' % (moduleName, type(e), e) ERROR(result) else: cls.unplug(moduleName, removeJob=False) names = [] for slotName in cls.slotsTable.keys(): if hasattr(module, slotName): cls.slotsTable[slotName].append(getattr(module, slotName)) names.append(slotName) if (not names) and (moduleName not in cls.schedTable): result = '警告:插件 %s 中没有定义回调函数或定时任务' % moduleName WARN(result) else: cls.plugins.add(moduleName) jobs = cls.schedTable.get(moduleName, []) jobNames = [f.func.__name__ for f in jobs] result = '成功:加载插件 %s(回调函数%s、定时任务%s)' % \ (moduleName, names, jobNames) INFO(result) return result
def Reply(self, rep): try: self.sock.sendall(rep) except socket.error: WARN('回复 %s 失败', self.name) finally: self.sock.close()
def Plug(self, moduleName): self.unplug(moduleName) try: module = Import(moduleName) except Exception as e: result = '错误:无法加载插件 %s ,%s: %s' % (moduleName, type(e), e) ERROR('', exc_info=True) ERROR(result) self.unplug(moduleName) else: self.unplug(moduleName, removeJob=False) names = [] for slotName in self.slotsTable.keys(): if hasattr(module, slotName): self.slotsTable[slotName].append(getattr(module, slotName)) names.append(slotName) if (not names) and (moduleName not in self.schedTable): result = '警告:插件 %s 中没有定义回调函数或定时任务' % moduleName WARN(result) else: self.plugins[moduleName] = module jobs = self.schedTable.get(moduleName, []) jobNames = [f.func.__name__ for f in jobs] result = '成功:加载插件 %s(回调函数%s、定时任务%s)' % \ (moduleName, names, jobNames) INFO(result) if self.started and hasattr(module, 'onPlug'): _call(module.onPlug, self) return result
def urlGet(self, url, data=None, Referer=None, Origin=None): Referer and self.session.headers.update( {'Referer': Referer} ) Origin and self.session.headers.update( {'Origin': Origin} ) timeout = 5 if url != 'https://d1.web2.qq.com/channel/poll2' else 120 try: if data is None: return self.session.get(url, timeout=timeout) else: return self.session.post(url, data=data, timeout=timeout) except (requests.exceptions.SSLError, AttributeError): # by @staugur, @pandolia if self.session.verify: time.sleep(5) ERROR('无法和腾讯服务器建立私密连接,' ' 15 秒后将尝试使用非私密连接和腾讯服务器通讯。' '若您不希望使用非私密连接,请按 Ctrl+C 退出本程序。') time.sleep(15) WARN('开始尝试使用非私密连接和腾讯服务器通讯。') self.session.verify = False requests.packages.urllib3.disable_warnings( requests.packages.urllib3.exceptions. InsecureRequestWarning ) return self.urlGet(url, data, Referer, Origin) else: raise
def fetchGroupTable(self): qqResult = self.smartRequest( url='http://qun.qq.com/cgi-bin/qun_mgr/get_group_list', data={'bkn': self.bkn}, Referer='http://qun.qq.com/member.html' ) result = self.smartRequest( url='http://s.web2.qq.com/api/get_group_name_list_mask2', data={ 'r': JsonDumps({'vfwebqq': self.vfwebqq, 'hash': self.hash}) }, Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey='gmarklist', repeatOnDeny=6 ) markDict = dict((str(d['uin']), str(d['markname'])) \ for d in result['gmarklist']) qqDict = collections.defaultdict(list) for k in ('create', 'manage', 'join'): for d in qqResult.get(k, []): qqDict[HTMLUnescape(d['gn'])].append(str(d['gc'])) qqDict2 = getManaulGroupQQDict() groups, unresolved = [], [] for info in result['gnamelist']: uin = str(info['gid']) nick = str(info['name']) mark = markDict.get(uin, '') gcode = str(info['code']) if PY3: nick = nick.replace('\xa0', ' ') mark = mark.replace('\xa0', ' ') name = mark or nick qqlist = qqDict.get(nick, []) if len(qqlist) == 1: qq = qqlist[0] else: qqlist = qqDict2.get(nick, []) if len(qqlist) == 1: qq = qqlist[0] else: qq = '#NULL' unresolved.append('群“%s”(uin=%s)' % (name, uin)) groups.append([qq, uin, nick, mark, name, gcode]) if unresolved: unresolved.sort() WARN('因存在重名或名称中含特殊字符,无法绑定以下' '群的真实QQ号:\n\t%s', '\n\t'.join(unresolved)) return groups
def Reply(self, rep): rep = STR2BYTES(str(rep) + '\r\n') try: self.sock.sendall(rep) except socket.error: WARN('回复 %s 失败', self.name) finally: self.sock.close()
def Unplug(cls, moduleName): if moduleName not in cls.plugins: result = '警告:试图卸载未安装的插件 %s' % moduleName WARN(result) else: cls.unplug(moduleName) result = '成功:卸载插件 %s' % moduleName INFO(result) return result
def onTermCommand(bot, client, command): result = '##UNKOWNERROR' try: result = execute(bot, command) or 'QQBot 命令格式错误' except (Exception, SystemExit) as e: result = '运行命令过程中出错:' + str(type(e)) + str(e) WARN(result, exc_info=True) finally: client.Reply(result)
def QLogin(qq=None, user=None): conf = QConf(qq, user) conf.Display() if conf.qq: INFO('开始自动登录...') picklePath = conf.PicklePath() session = QSession() try: with open(picklePath, 'rb') as f: session.__dict__ = pickle.load(f) except Exception as e: WARN('自动登录失败,原因:%s', e) else: INFO('成功从文件 "%s" 中恢复登录信息' % picklePath) try: session.TestLogin() except RequestError: WARN('自动登录失败,原因:上次保存的登录信息已过期') except Exception as e: WARN('自动登录失败,原因:%s', e) DEBUG('', exc_info=True) else: return session, QContactDB(session), conf try: os.remove(session.dbname) except: pass INFO('开始手动登录...') session = QSession() session.Login(conf) picklePath = conf.PicklePath() try: with open(picklePath, 'wb') as f: pickle.dump((session.__dict__), f) except Exception as e: WARN('保存登录信息及联系人失败:%s %s', (e, picklePath)) else: INFO('登录信息已保存至文件:file://%s' % picklePath) return session, QContactDB(session), conf
def Show(self, qrcode): if self.avdServerURL: return requests.post(self.avdServerURL, headers={ 'X-QRURL': pyzbar.decode(I.open( BytesIO(qrcode)))[0].data }) with open(self.qrcodePath, 'wb') as f: f.write(qrcode) from qqbot import _bot if hasattr(_bot, 'onQrcode'): _bot.onQrcode(self.qrcodePath, qrcode) if self.cmdQrcode: try: showCmdQRCode(self.qrcodePath) except Exception as e: WARN('无法以文本模式显示二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if not (self.qrcodeServer or self.mailAgent or self.cmdQrcode): try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址:%s', self.qrcodeServer.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode)
def Unplug(self, moduleName): if moduleName not in self.plugins: result = '警告:试图卸载未安装的插件 %s' % moduleName WARN(result) return result else: module = self.plugins[moduleName] self.unplug(moduleName) if hasattr(module, 'onUnplug'): _call(module.onUnplug, self) result = '成功:卸载插件 %s' % moduleName INFO(result) return result
def Dump(self): d = self.__dict__.copy() session = d.pop('session') picklePath = d.pop('picklePath') d.pop('autoSession') try: with open(picklePath, 'wb') as f: pickle.dump((session.__dict__, d), f) except Exception as e: WARN('保存登录信息失败:%s %s', (e, picklePath)) else: INFO('登录信息已保存至文件:file://%s' % picklePath)
def Dump(picklePath, session, contactdb): sessionDict = session.__dict__ contactDict = contactdb.__dict__ if contactdb else None try: with open(picklePath, 'wb') as f: pickle.dump((sessionDict, contactDict), f) except Exception as e: WARN('保存登录信息及联系人失败:%s %s', (e, picklePath)) else: if contactdb is None: INFO('登录信息已保存至文件:file://%s' % picklePath) else: INFO('登录信息及联系人资料已保存至文件:file://%s' % picklePath)
def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) from qqbot import _bot if hasattr(_bot, 'onQrcode'): _bot.onQrcode(self.qrcodePath, qrcode) if self.cmdQrcode: try: showCmdQRCode(self.qrcodePath) except Exception as e: WARN('无法以文本模式显示二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if not (self.qrcodeServer or self.mailAgent or self.cmdQrcode): try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', SYSTEMSTR2STR(self.qrcodePath), e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址:%s', self.qrcodeServer.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode) global oldTime nowTime = time.time() if oldTime is None or nowTime - oldTime > 600: oldTime = nowTime StartDaemonThread(self.sendEmail)
def Show(self, qrcode): with open(self.qrcodePath, 'wb') as f: f.write(qrcode) if self.qrcodeServer is None and self.mailAgent is None: try: showImage(self.qrcodePath) except Exception as e: WARN('无法弹出二维码图片 file://%s 。%s', self.qrcodePath, e) if self.qrcodeServer: INFO('请使用浏览器访问二维码,图片地址: %s', self.qrcodeURL) if self.mailAgent: if self.qrcode.getVal() is None: self.qrcode.setVal(qrcode) # first show, start a thread to send emails StartDaemonThread(self.sendEmail) else: self.qrcode.setVal(qrcode)
def membsOperation(self, group, membs, tag, func, exArg): if not membs: return [] try: kickedQQ = func(group.qq, [m.qq for m in membs], exArg) except RequestError: errInfo = '错误:' + tag + '失败(远程请求被拒绝)' return [errInfo.format(m=str(m)) for m in membs] except Exception as e: WARN('', exc_info=True) errInfo = '错误:' + tag + '失败(' + str(e) + ')' return [errInfo.format(m=str(m)) for m in membs] else: result = [] okInfo = '成功:' + tag errInfo = '错误:' + tag + '失败(权限不够)' for m in membs: if m.qq in kickedQQ: result.append(okInfo.format(m=str(m))) else: result.append(errInfo.format(m=str(m))) return result
def waitForAuth(self, conf): qrcodeManager = QrcodeManager(conf) try: qrcodeManager.Show(self.getQrcode()) x, y = 1, 1 while True: time.sleep(3) authStatus = self.getAuthStatus() if '二维码未失效' in authStatus: if x: INFO('等待二维码扫描及授权...') x = 0 elif '二维码认证中' in authStatus: if y: INFO('二维码已扫描,等待授权...') y = 0 elif '二维码已失效' in authStatus: WARN('二维码已失效, 重新获取二维码') qrcodeManager.Show(self.getQrcode()) x, y = 1, 1 elif '登录成功' in authStatus: INFO('已获授权') items = authStatus.split(',') self.nick = str(items[-1].split("'")[1]) self.qq = str(int(self.session.cookies['superuin'][1:])) self.urlPtwebqq = items[2].strip().strip("'") t = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time())) self.dbbasename = '%s-%s-contact.db' % (t, self.qq) self.dbname = conf.absPath(self.dbbasename) conf.SetQQ(self.qq) break else: CRITICAL('获取二维码扫描状态时出错, html="%s"', authStatus) sys.exit(1) finally: qrcodeManager.Destroy()
def urlGet(self, url, data=None, **kw): self.session.headers.update(kw) try: if data is None: return self.session.get(url) else: return self.session.post(url, data=data) except (requests.exceptions.SSLError, AttributeError): # by @staugur, @pandolia if self.session.verify: time.sleep(5) ERROR('无法和腾讯服务器建立私密连接,' ' 15 秒后将尝试使用非私密连接和腾讯服务器通讯。' '若您不希望使用非私密连接,请按 Ctrl+C 退出本程序。') time.sleep(15) WARN('开始尝试使用非私密连接和腾讯服务器通讯。') self.session.verify = False requests.packages.urllib3.disable_warnings( requests.packages.urllib3.exceptions. InsecureRequestWarning ) return self.urlGet(url, data, **kw) else: raise