python实现QQ机器人(自动登录,获取群消息,发送群消息)

版权声明: https://blog.csdn.net/zhujunxxxxx/article/details/29412297

一次偶然的机会我看见了一个群里的一个QQ号总是根据你所发的消息自动回复,当时很感觉到神奇,我知道可以模拟登录网站,没想到竟然也能模拟登录QQ,首先自己想到的就是如何实现模拟登录PC端的QQ, 开始研究了下,发现QQ所发送的包都很难理解。

于是就转到了网页版的QQ,因为在网页里可以捕获所有的请求从而更好的实现模拟功能!

首先第一步就是打开网页版的qq,打开浏览器的开发者模式 这里可以监控所有的请求!

打开登录界面的的时候

会捕捉到一个GET请求

https://ssl.ptlogin2.qq.com/check?uin=10588690&appid=1003903&js_ver=10080&js_type=0&login_sig=YW1ZUUsIU*7FepsR1blgEgcSVWeHCrNVVquTT1LZ0paOxZ-6xHtypEqNGoo-VELQ&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.5928007187321782

其中uin是你的QQ号

返回值是 ptui_checkVC('1','AAr4bdjMeh2hEa77PTuoHhqMTxbRqOp3','\x00\x00\x00\x00\x00\xa1\x92\x12');

其中1表示需要验证码 还有一种返回值 ptui_checkVC('0','!LJV','\x00\x00\x00\x00\x00\xa1\x92\x12') 这种表示是不需要的验证码的

def CheckVerify(self,uin):check="https://ssl.ptlogin2.qq.com/check?uin={uin}&appid=1003903&js_ver=10080&js_type=0&login_sig=YPD0P*wu2n8vW1OS2f7VfzvPf3Ku5vnkP4nzImF0GybR02fsKZdjGYB7f9R7nQRn&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.8179273759014904"check=check.replace('{uin}',uin)pattern=re.compile("ptui_checkVC\('(.*)','(.*)','(.*)'\);")result=self.Get(check)checked= pattern.search(result).groups()print 'Step1: CheckVerify'return checked

获取验证码的方法

def GetVerify(self):#url = 'https://ssl.captcha.qq.com/getimage?&uin='+str(self.QQ)+'&aid=1002101&0.45644426648505' + str(random.randint(10,99))verify="https://ssl.captcha.qq.com/getimage?aid=1003903&r=0.6472875226754695&uin={QQ}&cap_cd=aSD-ZVcNEcozlZUurhNYhp-MBHf4hjbJ"verify=verify.replace('{QQ}',self.QQ)path= r"c:/verify/1.jpg"#data = urllib.urlretrieve(url,path)data = urllib2.urlopen(verify)localPic =open(r"c:/verify/1.jpg",'wb')localPic.write(data.read())localPic.close()data.close()

输入用户名和密码 还有验证码后发送一个GET请求

https://ssl.ptlogin2.qq.com/login?u=10588690&p=AB80CD3B6429D9660878E93058DD78BD&verifycode=TEYX&webqq_type=10&remember_uin=1&login2qq=1&aid=1003903&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&h=1&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=6-14-296574&mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10080&login_sig=YW1ZUUsIU*7FepsR1blgEgcSVWeHCrNVVquTT1LZ0paOxZ-6xHtypEqNGoo-VELQ&pt_uistyle=5

这里面u代表账号  p代表密码 密码是经过一定算法加密的 verify是验证码

加密算法如下

def PasswordSecret(self,password,v1,v2,md5=True):if md5==True:password=self.PCMd5(password).upper()length=len(password)temp=''for i in range(0,length,2):temp+=r'\x'+password[i:i+2]return self.PCMd5(self.PCMd5(self.hex2asc(temp)+self.hex2asc(v2)).upper()+v1).upper()#md5加密函数def PCMd5(self,s):h=hashlib.md5()h.update(s)return h.hexdigest()#16进制转字符def hex2asc(self,s):_str="".join(s.split(r'\x'))length=len(_str)data=''for i in range(0,length,2):data+=chr(int(_str[i:i+2],16))return data

然后是登录部分代码

def Login(self,uin,pwd):#获取参数cheked=self.CheckVerify(uin)#加密密码#pwd=self.PasswordSecret(pwd,cheked[1],cheked[2])#pwd=self.PasswordSecret(pwd,r'AAST',r'\x00\x00\x00\x00\x00\xa1\x92\x12')loginurl="https://ssl.ptlogin2.qq.com/login?u={uin}&p={pwd}&verifycode={verify}&webqq_type=10&remember_uin=1&login2qq=1&aid=1003903&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&h=1&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=4-30-135914&mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10080&login_sig=YPD0P*wu2n8vW1OS2f7VfzvPf3Ku5vnkP4nzImF0GybR02fsKZdjGYB7f9R7nQRn&pt_uistyle=5"loginurl=loginurl.replace('{uin}',uin)#loginurl=loginurl.replace('{pwd}',pwd)#loginurl=loginurl.replace('{verify}',cheked[1])#result=Get(loginurl)if(cheked[0]=="1"):#下载验证码self.GetVerify()image = Image.open(r"c:/verify/1.jpg")image.show()code=raw_input("verifycode:").strip()loginurl=loginurl.replace('{verify}',code.upper())pwd=self.PasswordSecret(pwd,r''+code.upper(),cheked[2])#pwd=self.PasswordSecret(pwd,cheked[1],cheked[2])else:loginurl=loginurl.replace('{verify}',cheked[1])pwd=self.PasswordSecret(pwd,cheked[1],cheked[2])loginurl=loginurl.replace('{pwd}',pwd)result=self.Get(loginurl,'ssl.ptlogin2.qq.com','https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903&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=20140514001',None)print 'Step2: Login'pattern=re.compile("ptuiCB\('(.*)','(.*)','(.*)','(.*)','(.*)',\s'(.*)'\);")ret= pattern.search(result).groups()#获取必要的cookie 否则第二次登陆会出错self.Get(ret[2])print 'Step3: GetCookie'for c in self.cj:if c.name=="ptwebqq":self.ptwebqq=c.valuereturn result

登录成功后服务器会返回一串json数据

ptuiCB('0','0','http://ptlogin4.web2.qq.com/check_sig?pttype=1&uin=10588690&service=login&nodirect=0&ptsig=*ZwU0pfTmYP93Fbdt6uSzbbODzlZ0EY9g25PDge5zZU_&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&f_url=&ptlang=2052&ptredirect=100&aid=1003903&daid=164&j_later=0&low_login_hour=0&regmaster=0&pt_login_type=1&pt_aid=0&pt_aaid=0&pt_light=0','0','登录成功!', '小竹');

第一个为0 就表示登录成功了 ,但是这并没有真正的登录成功

上面的返回值中的url是用来获取一个关键cookie的 那就是ptwebqq

然后进行第二次登录,这次才是真正的登录

http://d.web2.qq.com/channel/login2

请求如下

    1. Accept:*/*

    2. Accept-Encoding:gzip,deflate,sdch

    3. Accept-Language:zh-CN,zh;q=0.8

    4. Connection:keep-alive

    5. Content-Length:244

    6. Content-Type:application/x-www-form-urlencoded

    7. Cookie:o_cookie=455910092; RK=fMEaWEZ0Qc; ts_last=web2.qq.com/; ts_refer=www.baidu.com/; ts_uid=4588821804; pgv_pvid=914251705; pgv_info=ssid=s3525422600&pgvReferrer=; verifysession=h02LeYrtarkWBZeSu_czkiczeNSNlDm7V1mCm-A5qatkwnHaNfgb2z46zH4X7OfyhFT7wH6LfschPvSLhDGXFA4eA**; ptui_loginuin=10588690; ptisp=cnc; ptcz=dace9cf90e7064a16ee56c8153273eff9f2de1d2827ba31f6571412ac18c50c3; ptwebqq=b21232ed3519839063d1c2ead8a8588c385d168097efdf88bc56e1a78be7dfb4; pt2gguin=o0010588690; uin=o0010588690; skey=@gmEO6N2JD; p_uin=o0010588690; p_skey=cZ5*kS-NOcXlD2Q0AEpJnmExwC2yA0g7jbTygpVFiA8_; pt4_token=1SyuJ39Eq6oKEwEhGIizeg__

    8. Host:d.web2.qq.com

    9. Origin:http://d.web2.qq.com

    10. Referer:http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=2

    11. User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

  1. Form Dataview sourceview URL encoded

    1. r:{"status":"online","ptwebqq":"b21232ed3519839063d1c2ead8a8588c385d168097efdf88bc56e1a78be7dfb4","passwd_sig":"","clientid":"7963288","psessionid":null}

    2. clientid:7963288

    3. psessionid:null

其中的ptwebqq就是刚才我们从cookie中获取的

这部分代码是

def Login2(self):try:url="http://d.web2.qq.com/channel/login2"postdata="r=%7B%22status%22%3A%22online%22%2C%22ptwebqq%22%3A%22{$ptwebqq}%22%2C%22passwd_sig%22%3A%22%22%2C%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3Anull%7D&clientid={$clientid}&psessionid=null"postdata=postdata.replace("{$ptwebqq}",self.ptwebqq)postdata=postdata.replace("{$clientid}",str(self.clientid))print 'Step4: Login2'result=self.Post(url,postdata,QQRobot.HOST[0],QQRobot.REFERER[0],QQRobot.ORIGIN[0])retjson=json.loads(result)retjson=retjson["result"]return retjsonexcept Exception,e:print "Login2 error "+str(e)

第二次登陆成功后会返回一个

'''{"retcode":0,
    "result":{
              "uin":10588690,
              "cip":1707901841,
              "index":1075,
              "port":59571,
              "status":"online",
              "vfwebqq":"c043f1f6ce5c3b76a4603ab60082668bef2dde0b987808f728e2071eb7c164eeb30fcd85c31018d2",
              "psessionid":"8368046764001d636f6e6e7365727665725f77656271714031302e3133392e372e31363000006cb000001ae1036200a192126d0000000a40356c593742635175316d00000028c043f1f6ce5c3b76a4603ab60082668bef2dde0b987808f728e2071eb7c164eeb30fcd85c31018d2",
              "user_state":0,
              "f":0
              }
    }'''

这样的数据结构  其中0表示登陆成功

需要把这写数据保存下来 后面进行操作需要

登陆成功后我们就可以拉去群列表了

#获取群列表信息def GetGroupNameList(self,vfwebqq):try:url="http://s.web2.qq.com/api/get_group_name_list_mask2"postdata="r=%7B%22vfwebqq%22%3A%22{$vfwebqq}%22%7D"postdata=postdata.replace("{$vfwebqq}",vfwebqq)ret=self.Post(url,postdata,QQRobot.HOST[1],QQRobot.REFERER[1],QQRobot.ORIGIN[1])print 'Step5: GetGroupList'retjson=json.loads(ret)retjson=retjson["result"]self.grouplist=retjsonfor group in self.grouplist['gnamelist']:print group["code"],group["name"]except Exception,e:print "GetGroupNameList error"+str(e)
#获取群成员信息def GetGroupInfo(self,gcode,vfwebqq):try:url="http://s.web2.qq.com/api/get_group_info_ext2?gcode={$gcode}&cb=undefined&vfwebqq={$vfwebqq}&t=1402069438458"url=url.replace("{$vfwebqq}",vfwebqq)url=url.replace("{$gcode}",str(gcode))ret=self.Get(url,QQRobot.HOST[1],QQRobot.REFERER[1],None)print "Step6: GetGroupInfo"retjson=json.loads(ret)retjson=retjson["result"]self.groupuserlist=retjsonexcept Exception,e:print "GetGroupInfo error"+str(e)
#发送群消息def SendGroupMsg(self,groupid,msg,psessionid):try:#msg=u">:"+msg#msg=msg.strip()#urlmsg=quote(msg.encode('utf8'))#把普通字符串包裹起来stype="%5C%22{content}%5C%22"temp=""part=""for c in msg:if type(c) is types.ListType:part=quote(str(c).strip().encode('utf8'))+"%2C"#part=part.replace("%20","")part=part.replace("%27","%5C%22") #把 ' 换为 \"part=part.replace("u","") #把 u 换为 空temp+=partelse:temp+=stype.replace("{content}",quote(c.encode('utf8')))+"%2C"temp=temp[0:len(temp)-3]#urlmsg="%5C%228%5C%22"#"%5B%5C%22face%5C%22%2C13%5D"urlmsg=tempurl="http://d.web2.qq.com/channel/send_qun_msg2"msg_id = 77860003#postdata="r=%7B%22group_uin%22%3A{$group_uin}%2C%22content%22%3A%22%5B%5C%22{$msg}%5C%22%2C%5C%22%5C%22%2C%5B%5C%22font%5C%22%2C%7B%5C%22name%5C%22%3A%5C%22%E5%AE%8B%E4%BD%93%5C%22%2C%5C%22size%5C%22%3A%5C%2210%5C%22%2C%5C%22style%5C%22%3A%5B0%2C0%2C0%5D%2C%5C%22color%5C%22%3A%5C%22000000%5C%22%7D%5D%5D%22%2C%22msg_id%22%3A{$msg_id}%2C%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3A%22{$psessionid}%22%7D&clientid={$clientid}&psessionid={$psessionid}"#表情#postdata="r=%7B%22group_uin%22%3A{$group_uin}%2C%22content%22%3A%22%5B{$msg}%2C%5C%22%5C%5Cn%5C%22%2C%5B%5C%22font%5C%22%2C%7B%5C%22name%5C%22%3A%5C%22%E5%AE%8B%E4%BD%93%5C%22%2C%5C%22size%5C%22%3A%5C%2210%5C%22%2C%5C%22style%5C%22%3A%5B0%2C0%2C0%5D%2C%5C%22color%5C%22%3A%5C%22000000%5C%22%7D%5D%5D%22%2C%22msg_id%22%3A{$msg_id}%2C%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3A%22{$psessionid}%22%7D&clientid={$clientid}&psessionid={$psessionid}"#字符postdata="r=%7B%22group_uin%22%3A{$group_uin}%2C%22content%22%3A%22%5B{$msg}%2C%5C%22%5C%22%2C%5B%5C%22font%5C%22%2C%7B%5C%22name%5C%22%3A%5C%22%E5%AE%8B%E4%BD%93%5C%22%2C%5C%22size%5C%22%3A%5C%2210%5C%22%2C%5C%22style%5C%22%3A%5B0%2C0%2C0%5D%2C%5C%22color%5C%22%3A%5C%22000000%5C%22%7D%5D%5D%22%2C%22msg_id%22%3A{$msg_id}%2C%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3A%22{$psessionid}%22%7D&clientid={$clientid}&psessionid={$psessionid}"postdata=postdata.replace("{$group_uin}",str(groupid))postdata=postdata.replace("{$psessionid}",psessionid)postdata=postdata.replace("{$clientid}",str(self.clientid))postdata=postdata.replace("{$msg_id}",str(msg_id))postdata=postdata.replace("{$msg}",urlmsg)self.Post(url,postdata,QQRobot.HOST[0],QQRobot.REFERER[0],QQRobot.ORIGIN[0])except Exception,e:print "SendGroupMsg error"+str(e)#print "send msg: "+str(msg)

心跳就是每隔一定时间向服务器请求一次 证明自己还在!

#心跳包def HeartBreak(self,psessionid):url="http://d.web2.qq.com/channel/poll2"postdata="r=%7B%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3A%22{$psessionid}%22%2C%22key%22%3A0%2C%22ids%22%3A%5B%5D%7D&clientid={$clientid}&psessionid={$psessionid}"postdata=postdata.replace("{$clientid}",str(self.clientid))postdata=postdata.replace("{$psessionid}",psessionid)while True:#每隔2秒发送心跳包ret=self.Post(url,postdata,QQRobot.HOST[0],QQRobot.REFERER[0],QQRobot.ORIGIN[0])try:retjson=json.loads(ret)retjson=retjson["result"]retjson=retjson[0]#print "heartbreak"if(retjson["poll_type"]=="group_message"):msg=retjson["value"]self.ProcessMsg(msg)except Exception,e:#print "HeartBreak error "+str(e)passtime.sleep(2)

python实现QQ机器人(自动登录,获取群消息,发送群消息)相关推荐

  1. python实现qq机器人qqbot

    title: python实现qq机器人qqbot tags: python date: 2018-6-1 10:19:00 --- 以下内容为转载 一.介绍 qqbot 是一个用 python 实现 ...

  2. python实现微信机器人: 登录微信、消息接收、自动回复功能

    这篇文章主要介绍了python实现微信机器人: 登录微信.消息接收.自动回复功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 ...

  3. Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据流程分析【转】

    Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据&流程分析 QQ空间说说抓取难度比较大,花了一个星期才研究清楚! 代码请移步到GitHub GitHub地址:http ...

  4. python课设总结_Python技术分享课总结:用Python模拟知乎自动登录

    原标题:Python技术分享课总结:用Python模拟知乎自动登录 Python语言是由Guido van Rossum大牛在1989年发明,它是当今世界最受欢迎的计算机编程语言之一,也是一门&quo ...

  5. Python+Selenium实现新浪微博自动登录

    Python+Selenium实现新浪微博自动登录 环境说明:win10+eclipse+chrome 备注:需要下载chrome浏览器的驱动(地址: https://sites.google.com ...

  6. Python+selenium+chromedriver实现自动登录微博并发微博

    python环境这里就是默认安好的状态 首先要确保安装了selenium 在cmd/终端界面输入 pip install selenium 如果是pycharm的话那就是 Pycharm->Pr ...

  7. Python零基础之自动登录12306

    Python零基础之自动登录12306 文章目录 Python零基础之自动登录12306 需要注意的问题 直接上代码 分析过程在代码注释中已经写的较为清楚 功能实现是代码运行后打开生成的code2图片 ...

  8. Java+Selenium实现QQ邮箱自动登录、发邮件与退出

    初学selenium,用最近所学知识写了QQ邮箱自动登录.发送邮件.退出,算是对自己学习的知识的巩固吧.如果哪里有不足之处,就请各位告诉我,指导我一下,非常感谢. 登录页面 在网页登录QQ邮箱的时候, ...

  9. python 实现qq空间网页登录(本文主要是点图标进入空间)

    python 实现qq空间网页登录(本文主要是点图标进入空间) 工具: pycharm.selenium.time from selenium import webdriver from time i ...

  10. 基于python,控制微信自动登录并发送消息给指定联系人

    给出微信联系人.微信启动路径.消息内容,实现自动登录并并发送消息,如果需要定时发送可以开一个线程或者用while True实现.上代码,报错的话可能是缺少对应的库,自行百度安装即可. 下面代码 复制后 ...

最新文章

  1. JVM实用参数 GC日志
  2. php动态加载js,动态加载script文件的两种方法_javascript技巧
  3. nginx+mysql+php+cacti+rrdtool全方位架构急速版
  4. 实验四+116+陈洁
  5. 学java有什么技巧?
  6. 为了研究,可以在 Linux 内核中植入漏洞吗?
  7. Dev C++使用教程(使用Dev C++编写C语言程序)
  8. Axure 9母版引发事件
  9. windows无法格式化u盘_U盘被写保护无法格式化怎么办?优盘无法格式化的解决办法...
  10. 关于PWM脉冲宽度调制的点滴总结
  11. Scrapy——基本用法(命令行工具、Item、Spiders)
  12. Python系列之面向对象编程
  13. python读取图片各点灰度值_用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)...
  14. DSPE-PEG3-Mal,带有DSPE的基团小分子PEG试剂
  15. 大数据-玩转数据-Python几种数据采集
  16. 最喜欢突然说分手的星座,有TA吗?
  17. 双相情感障碍会变精分吗?精神科医生为您答疑
  18. Mapbox离线字体 glyphs
  19. 手撕python_GitHub - caishiqing/manual: 手撕机器学习
  20. 探究计算机的硬件组成 教案,初一信息技术探究计算机的硬件组成教案

热门文章

  1. 空手套白狼,硬阅java字节码class文件
  2. 软件工程的经典书籍有哪些?
  3. 使用stm32 SIM800A发送短信
  4. 河南联通中兴B860AV1.2_S905M-B_线刷刷机固件及教程
  5. 使用PHP官方镜像调用API进行文本翻译
  6. 《网络科学导论》——博弈模型笔记
  7. .Net 之时间轮算法(终极版)
  8. h3c交换机配置教程命令(新手配置交换机详细教程)
  9. 基于SpringBoot的酒店管理系统
  10. 智慧校园信息化建设方案