×

PyQQbot Python实现的QQ机器人

消耗积分:2 | 格式:zip | 大小:0.30 MB | 2022-05-27

h1654155275.0032

分享资料个

授权协议 MIT
开发语言 Python
操作系统 跨平台
软件类型 开源软件

软件简介

一、介绍
QQBot 是一个用 python 实现的、基于腾讯 SmartQQ 协议的简单 QQ 机器人,可运行在 Linux 和 Windows 平台下,所有代码均集成在一个 [qqbot.py][code] 文件中,代码量仅 400 多行(不包括注释)。程序采用单线程的方式运行,且尽可能的减少了网络和登录错误(特别是所谓的 103 error )发生的概率。
[code]: https://raw.githubusercontent.com/pandolia/qqbot/master/qqbot.py

本项目 github 地址: https://github.com/pandolia/qqbot/

你可以用 QQBot 来实现:
* 监控、收集 QQ 消息
* 自动消息推送
* 聊天机器人
* 通过 QQ 远程控制电脑、智能家电

二、安装方法
在 Python 2.7 下使用,用 pip 安装,安装命令:

$ pip install qqbot

也可以直接下载 [qqbot.py][code] 运行,但需先安装 [requests](https://pypi.python.org/pypi/requests) 库。

三、使用方法
##### 1. 启动 QQBot
在命令行输入: **qqbot** ,或直接运行 [qqbot.py][code] : **python qqbot.py** 。启动过程中会自动弹出二维码图片(Linux下需安装有 gvfs ,否则需要手动打开图片),需要用手机 QQ 客户端扫码并授权登录。启动成功后,会将本次登录信息保存到本地文件中,下次启动时,可以输入: **qqbot qq号码**,或:**python qqbot.py qq号码** ,先尝试从本地文件中恢复登录信息(不需要手动扫码),只有恢复不成功或登录信息已过期时才会需要手动扫码登录。
##### 2. 操作 QQBot
QQ 机器人启动后,用另外一个 QQ 向本 QQ 发送消息即可操作 QQBot 。目前提供以下命令:
    1) 帮助:
        -help
    2) 列出 好友/群/讨论组:
        -list buddy/group/discuss
    3) 向 好友/群/讨论组 发送消息:
        -send buddy/group/discuss uin message
        其中 uin 是临时 qq 号,利用 -list 命令查看好友等的临时 qq 号。   
    4) 停止 QQBot :
        -stop


四、实现你自己的 QQ 机器人
实现自己的 QQ 机器人非常简单,只需要继承 [qqbot.py][code] 中提供的 **QQBot** 类并重新实现此类中的消息响应方法 **onPullComplete** 方法。示例代码:

    from qqbot import QQBot    
    class MyQQBot(QQBot):
        def onPollComplete(self, msgType, from_uin, buddy_uin, message):
            if message == '-hello':
                self.send(msgType, from_uin, '你好,我是QQ机器人')
            elif message == '-stop':
                self.stopped = True
                self.send(msgType, from_uin, 'QQ机器人已关闭')
    
    myqqbot = MyQQBot()
    myqqbot.Login()
    myqqbot.PollForever()

以上代码运行后,用另外一个 QQ 向本 QQ 发送消息 **“-hello”**,则会自动回复 **“你好,我是 QQ 机器人”**,发送消息 **“-stop”** 则会关闭 QQ 机器人。

五、 QQBot 类中的主要方法、属性
#### 1. 构造方法、登录方法、主要属性

    >>> bot = QQBot()
    >>> bot.Login()
    ...

构造方法生成一个 QQBot 实例,其实没做任何工作。全部的登录、获取 好友/群/讨论组 列表的工作在 **Login** 方法中完成。Login 方法会检查命令行参数 sys.argv 中是否提供了 qq 号码。若没有提供 qq 号码,则需要手动扫码登录。登录后会将登录信息保存在本地。若提供了 qq 号码,则会先尝试从本地恢复会话信息(不需要手动扫码),只有恢复不成功或登录信息已过期时才会需要手动扫码登录。

QQBot 登录完成后,可以进行消息收发了,且 好友/群/讨论组 的列表保存在 **buddy, buddyStr, group, groupStr, discuss, discussStr** 属性当中。

    >>> bot.buddy
    ((1880557506, 'Jack'), (2776164208, 'Mike'), ..., (2536444957, 'Kebi'))
    >>> print bot.buddyStr

    好友列表:
        0, Jack (2348993434)
        1, Mike (348093248)
        ...
#### 2. 消息收发

    >>> bot.poll()
    ('buddy', 207353438, 207353438, 'hello')
    >>> bot.poll()
    ('', 0, 0, '')
    >>> bot.send('buddy', 45789321, 'hello')

向buddy45789321发送消息成功
**poll** 方法向 QQ 服务器查询消息,如果有未读消息则会立即返回,返回值为一个四元 tuple :
    (msgType, from_uin, buddy_uin, message)
其中 **msgType** 可以为 **'buddy'** 、 **'group'** 或 **'discuss'**,分别表示这是一个 **好友消息** 、**群消息** 或 **讨论组消息** ; **from_uin** 和 **buddy_uin** 代表消息发送者的 **uin** ,可以通过 uin 向发送者回复消息,如果这是一个好友消息,则 from_uin 和 buddy_uin 相同,均为好友的 uin ,如果是群消息或讨论组消息,则 from_uin 为该群或讨论组的 uin , buddy_uin 为消息发送人的 uin ; **message** 为消息内容,是一个 **utf8** 编码的 string 。
如果没有未读消息,则 **poll** 方法会一直等待两分钟,若期间没有其他人发消息过来,则返回一个只含空值的四元 tuple :
    ('', 0, 0, '')
**send** 方法的三个参数为 **msgType** 、 **to_uin** 和 **message** ,分别代表 **消息类型** 、**接收者的 uin** 以及 **消息内容** ,消息内容必须是一个 **utf8** 编码的 string 。
如果发送消息的频率过快, qq 号码可能会被锁定甚至封号。因此每发送一条消息,会强制 sleep 3 秒钟,每发送 10 条消息,会强制 sleep 30 秒钟。同一条消息重复发送多次也可能被锁号或封号,因此每条消息发送之前都会在开头附加一个随机数字。
这里需要注意的是,当 poll 方法因等待消息而阻塞时,不要试图在另一个线程中调用 send 方法发送消息,也不要试图用多线程的方式同时调用 send 方法,否则可能引起一些无法预料的错误。
#### 3. 无限消息轮询

    >>> bot.PullForever()

**PullForever** 方法会不停的调用 poll 方法,并将 poll 方法的返回值传递给 **onPullComplete** 方法,直到 stopped 属性变为 True 。如下:

    def PollForever(self):
        self.stopped = False
        while not self.stopped:
            pullResult = self.poll()
            self.onPollComplete(*pullResult)

onPollComplete 方法是 QQ 机器人的灵魂。你可以自由发挥,重写此方法,实现更智能的机器人。

六、参考资料
QQBot 参考了以下开源项目:

- [ScienJus/qqbot](https://github.com/ScienJus/qqbothttps://github.com/pandolia/qqbot/) (ruby)
- [floatinghotpot/qqbot](https://github.com/floatinghotpot/qqbot) (node.js)

在此感谢以上两位作者的无私分享,特别是感谢 ScienJus 对 SmartQQ 协议所做出的深入细致的分析。

### 七、反馈

有任何问题或建议可以发邮件给我,邮箱:

 

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//m.obk20.com/www/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'PyQQbot Python实现的QQ机器人',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"https://www.elecfans.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);