美文网首页
qqbot 请求“http://s.web2.qq.com/ap

qqbot 请求“http://s.web2.qq.com/ap

作者: an鑫_wolfxin2010 | 来源:发表于2018-12-05 09:53 被阅读0次

qqbot 是一个用 python 实现的、基于腾讯 SmartQQ 协议的 QQ 机器人框架,可运行在 Linux 、 Windows 和 Mac OSX 平台下。
本项目 github 地址: https://github.com/pandolia/qqbot

如何背单词永不遗忘?暴暴暴暴暴暴涨38000单词量的秘诀-->科学记忆法

你可以通过扩展 qqbot 来实现:

  • 监控、收集 QQ 消息
  • 自动消息推送
  • 聊天机器人
  • 通过 QQ 远程控制你的设备

但是近两天出现使用命令行启动qqbot时老是提示错误:
[ERROR] 第7次请求“http://s.web2.qq.com/api/get_group_name_list_mask2”时出现 请求被拒绝错误, html='{"retcode":50}'

qqbot运行错误提示信息

解决方法:

  1. 找到python安装目录下“Lib\site-packages\qqbot\qcontactdb\fetch.py”文件下的“http://s.web2.qq.com” 替换成 “https://s.web2.qq.com”即可
  2. 直接将以下的fetch.py的内容覆盖原文件的内容即可:
# fetch.py已修改成功并亲测可使用!!
# -*- coding: utf-8 -*-

import sys, os.path as op
p = op.dirname(op.dirname(op.dirname(op.abspath(__file__))))
if p not in sys.path:
    sys.path.insert(0, p)

from qqbot.qcontactdb.contactdb import rName, tType

from qqbot.qconf import QConf
from qqbot.utf8logger import WARN, ERROR, INFO
from qqbot.basicqsession import BasicQSession, RequestError
from qqbot.common import JsonDumps, HTMLUnescape, PY3, STR2BYTES, BYTES2STR

import collections, os

def fetchBuddyTable(self):

    result = self.smartRequest(
        url = 'https://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 = [], []

    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]
#        else:
#            qq = '#NULL'
#            unresolved.append('好友“%s”(uin=%s)' % (name, uin))
        qq = '#NULL'
        
        # 各属性的顺序绝对不能变
        buddies.append([qq, uin, nick, mark, name])
        
    
#    if unresolved:
#        unresolved.sort()
#        WARN('因存在重名或名称中含特殊字符,无法绑定以下好友的真实QQ号,请修改其备'
#             '注名,保证备注名的唯一性且不带特殊字符:\n\t%s', '\n\t'.join(unresolved))
    WARN('因腾讯关闭了 qun.qq.com 的接口,无法获取到好友的真实 QQ 号码!')
    
    return buddies

def getManaulGroupQQDict():
    
    mgQQDict = collections.defaultdict(list)
    
    from qqbot import QQBot; fn = QQBot._bot.conf.absPath('groupqq')

    if not os.path.exists(fn):
        return mgQQDict

    try:
        with open(fn, 'rb') as f:
            s = f.read()
    except Exception as e:
        ERROR('无法读取群 QQ 文件 %s , %s', fn, e)
        return mgQQDict
    
    try:
        s = BYTES2STR(s)
    except Exception as e:
        ERROR('群 QQ 文件 %s 编码错误, %s', fn, e)
        return mgQQDict    

    try:
        for line in s.split('\n'):
            if not line.startswith('#') and (',' in line):
                qq, nick = line.rstrip('\r').split(',', 1)
                mgQQDict[nick].append(qq)
    except Exception as e:
        ERROR('群 QQ 文件 %s 格式错误, %s', fn, e)
        return mgQQDict
    
    INFO('成功从文件 %s 中读取群的实际 QQ 号码', fn)

    return mgQQDict

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 = 'https://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))
        qq = '#NULL'

        groups.append([qq, uin, nick, mark, name, gcode])        
    
#    if unresolved:
#        unresolved.sort()
#        WARN('因存在重名或名称中含特殊字符,无法绑定以下'
#             '群的真实QQ号:\n\t%s', '\n\t'.join(unresolved))
    
    WARN('因腾讯关闭了 qun.qq.com 的接口,无法获取到群的真实 QQ 号码!')
    
    return groups

# by @waylonwang, pandolia
def fetchGroupMemberTable(self, group):
    
    result = self.smartRequest(
        url = ('https://s.web2.qq.com/api/get_group_info_ext2?gcode=%s'
               '&vfwebqq=%s&t={rand}') % (group.gcode, self.vfwebqq),
        Referer = ('https://s.web2.qq.com/proxy.html?v=20130916001'
                   '&callback=1&id=1'),
        expectedKey = 'minfo',
        repeatOnDeny = 5
    )

    cardDict = collections.defaultdict(list)
    nickDict = collections.defaultdict(list)    
    if group.qq != '#NULL':
        r = self.smartRequest(
            url='http://qinfo.clt.qq.com/cgi-bin/qun_info/get_group_members_new',
            Referer='http://qinfo.clt.qq.com/member.html',
            data={'gc': group.qq, 'u': self.uin , 'bkn': self.bkn}
        )        
        
        for m in r['mems']:
            qq = str(m['u'])
            nick = HTMLUnescape(m['n'])
            card = HTMLUnescape(r.get('cards', {}).get(qq, ''))
            mark = HTMLUnescape(r.get('remarks', {}).get(qq, ''))            
            name = card or nick
            
            join_time = r.get('join', {}).get(qq, 0)
            last_speak_time = r.get('times', {}).get(qq, 0)
            is_buddy = m['u'] in r.get('friends', [])
    
            if r['owner'] == m['u'] :
                role, role_id = '群主', 0
            elif m['u'] in r.get('adm', []):
                role, role_id = '管理员', 1
            else:
                role, role_id = '普通成员', 2
    
            level = r.get('lv', {}).get(qq, {}).get('l', 0)
            levelname = HTMLUnescape(r.get('levelname', {}).get('lvln' + str(level), ''))
            point = r.get('lv', {}).get(qq, {}).get('p', 0)
            
            memb = [qq, None, nick, mark, card, name, join_time, last_speak_time,
                    role, role_id, is_buddy, level, levelname, point]
            
            if card:
                cardDict[STR2BYTES(card)[:18]].append(memb)
    
            nickDict[nick].append(memb)
    
    membss, unresolved = [], []
    ucDict = dict((str(it['muin']), it['card']) for it in result.get('cards', {}))
    for m, inf in zip(result['ginfo']['members'], result['minfo']):
        uin, nick = str(m['muin']), str(inf['nick'])
        card = ucDict.get(uin, '')        
        if not PY3:
            card = card.replace('\xc2\xa0', ' ')
            nick = nick.replace('\xc2\xa0', ' ')
        else:
            card = card.replace('\xa0', ' ')
            nick = nick.replace('\xa0', ' ')
        name = card or nick
        
        membs = nickDict.get(nick, [])
        if len(membs) == 1:
            memb = membs[0]
        else:
            membs = cardDict.get(STR2BYTES(card)[:18], [])
            if len(membs) == 1:
                memb = membs[0]
            else:
                memb = None
        
        if memb is None:
            unresolved.append('成员“%s”(uin=%s)' % (name, uin))
            memb = ['#NULL', uin, nick, '#NULL', card, name, -1, -1,
                    '#NULL', -1, -1, -1, '#NULL', -1]
        else:
            memb[1] = uin
        
        membss.append(memb)

#    if unresolved:
#        unresolved.sort()
#        WARN('因存在重名或名称中含特殊字符,无法绑定 %s 中以下'
#             '成员的真实QQ号:\n\t%s', group, '\n\t'.join(unresolved))
    WARN('因腾讯关闭了 qun.qq.com 的接口,无法获取到群成员的真实 QQ 号码!')
    
    return membss

def fetchDiscussTable(self):
    result = self.smartRequest(
        url = ('https://s.web2.qq.com/api/get_discus_list?clientid=%s&'
               'psessionid=%s&vfwebqq=%s&t={rand}') % 
              (self.clientid, self.psessionid, self.vfwebqq),
        Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001'
                   '&callback=1&id=2'),
        expectedKey = 'dnamelist',
        repeatOnDeny = 5
    )['dnamelist']        
    discusses = []
    for info in result:
        discusses.append([str(info['did']), str(info['name'])])
    return discusses

def fetchDiscussMemberTable(self, discuss):
    result = self.smartRequest(
        url = ('http://d1.web2.qq.com/channel/get_discu_info?'
               'did=%s&psessionid=%s&vfwebqq=%s&clientid=%s&t={rand}') %
              (discuss.uin, self.psessionid, self.vfwebqq, self.clientid),
        Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001'
                   '&callback=1&id=2')
    )
    qqDict = dict((m['mem_uin'], m['ruin']) for m in result['info']['mem_list'])
    membs = []
    for m in result['mem_info']:
        membs.append([str(qqDict[m['uin']]), str(m['uin']), str(m['nick'])])
    return membs

def Fetch(self, tinfo):
    rname, ttype = rName(tinfo), tType(tinfo)
    INFO('正在获取 %s ...', rname)
    try:
        if ttype == 'buddy':
            table = fetchBuddyTable(self)
        elif ttype == 'group':
            table = fetchGroupTable(self)
        elif ttype == 'discuss':
            table = fetchDiscussTable(self)
        elif ttype == 'group-member':
            table = fetchGroupMemberTable(self, tinfo)
        else:
            table = fetchDiscussMemberTable(self, tinfo)
    except RequestError:
        table = None
    except:
        ERROR('', exc_info=True)
        table = None
    
    if table is None:
        ERROR('获取 %s 失败', rname)

    return table

if __name__ == '__main__':
    from qqbot.qconf import QConf
    from qqbot.basicqsession import BasicQSession
    
    self = BasicQSession()
    conf = QConf(['-q', '158297369'])
    conf.Display()
    self.Login(conf)

修改好fetch.py文件后,重新使用qqbot命令,运行大功告成....
修改好fetch.py文件后,重新使用qqbot命令,运行大功告成....
修改好fetch.py文件后,重新使用qqbot命令,运行大功告成....

启动qqbot命令,成功运行 qqbot群测试结果

如您确实无法进行修复,可以微信联系我wolfxin2010;自己能解决的就不要劳烦本人!thanks

相关文章

  • qqbot 请求“http://s.web2.qq.com/ap

    qqbot 是一个用 python 实现的、基于腾讯 SmartQQ 协议的 QQ 机器人框架,可运行在 Linu...

  • DAY1

    一 http基础 http请求方式 输入url,先去找DNS缓存(hosts),找ip地址发送http请求,先ap...

  • UE HTTP协议

    UE4客户端向HTTP服务器请求数据 :采用post方式提交 这里我们http协议的post请求提交方式使用:ap...

  • 5.请求和回应

    Drf中的请求和回应 文档: 地址:http://www.django-rest-framework.org/ap...

  • 认识和使用AJAX(二)

    1、请求格式 GET /xxx HTTP/1.1HOST:jack.com:8002Content-Type:ap...

  • 〖QQ自动回复机器人〗qqbot

    qqbot 只有两步,但只能查看信息,搜索信息 pip install qqbot qqbot 扫码 Smartq...

  • iOS网络方面问题汇总

    1、使用HTTP请求 iOS9引入了新特性App Transport Security (ATS),新特性要求Ap...

  • ESP8266通讯协议应用比较

    AP模式TCPWeb Server+HTTPHTTP1. HTTP的请求/应答方式的会话都是客户端发起的,缺乏服务...

  • 替代qqbot,使用酷q机器人实现qq机器人

    替代qqbot,使用酷q机器人实现qq机器人 写在前面 由于qqbot已停止维护,之前基于qqbot写的机器人不能...

  • 【HTTP】HTTP请求

    1、HTTP协议通信流程: 2、HTTP请求包含内容 一个HTTP请求报文由请求行(request line)、请...

网友评论

      本文标题:qqbot 请求“http://s.web2.qq.com/ap

      本文链接:https://www.haomeiwen.com/subject/bqpbcqtx.html