自学Python五 爬虫基础练习之SmartQQ协议
BAT站在中国互联网的顶端,引导着中国互联网的发展走向。。。既受到了多数程序员的关注,也在被我们所惦记着。。。
关于SmartQQ的协议来自HexBlog,根据他的博客我自己也一步一步的去分析,去尝试,自己不了解不知道的总是神秘的,如果你有这种好奇心,那么真相就只有一个。接下来我先把协议放出来,至于分析方法,以后有机会再谈谈。。。其实我也是个半吊子水平。。。谁知道下次改了协议还灵不灵呢!
登录之前,获取二维码:https://ssl.ptlogin2.qq.com/ptqrshow?appid=501004106&e=0&l=M&s=5&d=72&v=4&t=0.22925435146316886,refer为:https://ui.ptlogin2.qq.com/cgi-bin/login
循环获取二维码状态(是否失效,是否在手机上授权):https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&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-136435&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10139&login_sig=&pt_randsalt=0 refer为:https://ui.ptlogin2.qq.com/cgi-bin/login
获取cookie中ptwebqq:这次的url是手机扫描二维码之后得到的返回值。refer不变。
获取返回值vfwebqq:http://s.web2.qq.com/api/getvfwebqq?ptwebqq=" + ptwebqq + "&clientid=53999199&psessionid=&t=1446710396202。refer为http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1。
成功登录,得到uin,psessionid:http://d.web2.qq.com/channel/login2,refer为http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2,数据为:"r=%7B%22ptwebqq%22%3A%22"+ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22%22%2C%22status%22%3A%22online%22%7D",host地址为:"d1.web2.qq.com"
根据得到的信息获取好友列表:http://s.web2.qq.com/api/get_user_friends2,数据为:data="r=%7B%22vfwebqq%22%3A%22"+vfwebqq+"%22%2C%22hash%22%3A%22"+__hash+"%22%7D",refer为:http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2
让我们来看看程序:
下面我们用python来尝试一下(分为两个文件,其中继续沿用我们的HttpClient类,以及WebQQ类,代码如下):
#HttpClient.py
# -*- coding: utf-8 -*-
import cookielib, urllib, urllib2, socket class HttpClient:
__cookie = cookielib.CookieJar()
__req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie))
__req.addheaders = [
('Accept', 'application/javascript, */*;q=0.8'),
('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)')
]
urllib2.install_opener(__req) def Get(self, url, refer=None):
try:
req = urllib2.Request(url)
if not (refer is None):
req.add_header('Referer', refer)
return urllib2.urlopen(req, timeout=120).read()
except urllib2.HTTPError, e:
return e.read()
except socket.timeout, e:
return ''
except socket.error, e:
return '' def GetWithOutRead(self, url, refer=None):
try:
req = urllib2.Request(url)
if not (refer is None):
req.add_header('Referer', refer)
return urllib2.urlopen(req, timeout=120)
except urllib2.HTTPError, e:
return e.read()
except socket.timeout, e:
return ''
except socket.error, e:
return '' def Post(self, url, data, refer=None):
try:
#req = urllib2.Request(url, urllib.urlencode(data))
req = urllib2.Request(url,data)
if not (refer is None):
req.add_header('Referer', refer)
return urllib2.urlopen(req, timeout=120).read()
except urllib2.HTTPError, e:
return e.read()
except socket.timeout, e:
return ''
except socket.error, e:
return '' def Download(self, url, file):
output = open(file, 'wb')
output.write(urllib2.urlopen(url).read())
output.close() def getCookie(self, key):
for c in self.__cookie:
if c.name == key:
return c.value
return '' def setCookie(self, key, val, domain):
ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)
self.__cookie.set_cookie(ck)
#WebQQ.py
# -*- coding: utf-8 -*-
from Tkinter import *
from time import sleep
from HttpClient import HttpClient
import json,io
from multiprocessing import Process
import multiprocessing
from PIL import Image, ImageTk
class WebQQ(HttpClient):
def __init__(self):
self.__cookie = ""
self.__ptwebqq = ""
self.__vfwebqq = ""
self.__hash = ""
self.__uin = ""
self.__root = ""
self.__psessionid = ""
self.queue = multiprocessing.Queue() #获取二维码
def __ptqrshow(self):
img = self.Get(url="https://ssl.ptlogin2.qq.com/ptqrshow?appid=501004106&e=0&l=M&s=5&d=72&v=4&t=0.4139144900254905")
if(img!=None):
data_stream = io.BytesIO(img)
imgfile = Image.open(data_stream)
p = Process(target=self._run_proc, args=(imgfile,))
p.start()
print(u"二维码下载完毕,请尽快扫描...")
return True
else:
print(u"二维码下载失败")
return False #检测扫码状态,登录进度
def __ptqrlogin(self):
res = self.Get("https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1"+
"&login2qq=1&aid=501004106&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-136435"+
"&mibao_css=m_webqq&t=undefined&g=1&js_type=0&js_ver=10139&login_sig=&pt_randsalt=0",
"https://ui.ptlogin2.qq.com/cgi-bin/login")
if(res!=None):
result = res.find("登录成功")
if(result==-1):
sleep(1) return self.__ptqrlogin()
elif(result!=-1):
res = res.decode("UTF-8")
return self.__check_sig(res[res.find("http"):res.find(u"','0','登录成功!'")].encode())
else:
return False
else:
return False
#获得ptwebqq cookie
def __check_sig(self,url):
res = self.Get(url=url,refer="https://ui.ptlogin2.qq.com/cgi-bin/login")
if(res!=None):
self.__ptwebqq = self.getCookie("ptwebqq")
self.__getvfwebqq()
return self.__login2()
else:
return False
#获得vfwebqq cookie
def __getvfwebqq(self):
res = self.Get(url="http://s.web2.qq.com/api/getvfwebqq?ptwebqq="+self.__ptwebqq+
"&clientid=53999199&psessionid=&t=1446710396202",
refer="http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
if(res!=None):
jsn = json.loads(res)
self.__vfwebqq = jsn["result"]["vfwebqq"]
#登录 获取uin psessionid
def __login2(self):
data = "r=%7B%22ptwebqq%22%3A%22"+self.__ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22%22%2C%22status%22%3A%22online%22%7D" res = self.Post(url = "http://d1.web2.qq.com/channel/login2",
data = data.encode(encoding="utf8"),
refer = "http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2")
if(res==None):
return False
jsn = json.loads(res)
if(jsn["retcode"]==0):
self.__uin = jsn["result"]["uin"]
self.__psessionid = jsn["result"]["psessionid"]
self.__hash = self.__friendsHash(self.__uin,self.__ptwebqq)
self.__get_user_friends()
return True
else:
return False
#好友的hash 参考HexBlog
def __friendsHash(self,uin,pt):
N=[0 for x in range(4)]
V=[0 for x in range(4)]
U=[0 for x in range(8)]
# 字符串转换为字符数组
k=pt.encode(encoding="UTF8")
n=["","","","","","","","","","","A","B","C","D","E","F"]
for x in range(len(k)):
N[x%4]^=ord(k[x])
x=int(uin)
V[0] = x >> 24 & 255 ^ 69;
V[1] = x >> 16 & 255 ^ 67;
V[2] = x >> 8 & 255 ^ 79;
V[3] = x & 255 ^ 75;
for x in range(8):
U[x]=(x%2==0) and N[x>>1] or V[x>>1]
result=""
for x in U:
result+=n[x>>4&15]
result+=n[x&15]
return result
#获取好友列表
def __get_user_friends(self):
data="r=%7B%22vfwebqq%22%3A%22"+self.__vfwebqq+"%22%2C%22hash%22%3A%22"+self.__hash+"%22%7D"
res=self.Post(url="http://s.web2.qq.com/api/get_user_friends2",
data=data.encode(encoding="utf8"),
refer="http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1")
if(res!=None):
# 记录好友列表
jsn=json.loads(res)
if(jsn["retcode"]==0):
# 正确返回列表后
for x in jsn["result"]["marknames"]:
print (x["markname"])
#心跳包并接收消息,现在不能用了
#def __poll(self):
# data="r=%7B%22ptwebqq%22%3A%22"+self.__ptwebqq+"%22%2C%22clientid%22%3A53999199%2C%22psessionid%22%3A%22"+self.__psessionid +"%22%2C%22key%22%3A%22%22%7D"
# res=self.Post(url="http://d1.web2.qq.com/channel/poll2",
# data=data.encode(encoding="utf8"),
# refer="http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2")
# if(res!=None):
# print res def __check_queue(self):
try:
out = self.queue.get_nowait()
if out == 'stop':
self.__do_stop()
return
# Could check for other commands here, too
except :
pass
self.__root.after(100, self.__check_queue) def __stop(self):
self.queue.put('stop') def __do_stop(self):
self.__root.destroy() def _run_proc(self,imgfile):
self.__root = Tk()
result = ImageTk.PhotoImage(imgfile)
label = Label(self.__root, image=result)
label.pack()
self.__root.after(100, self.__check_queue)
self.__root.mainloop()
def run(self):
if(self.__ptqrshow()):
if(self.__ptqrlogin()):
print(u"登录成功")
self.__stop() if __name__ =="__main__":
qq=WebQQ()
qq.run()
自学Python五 爬虫基础练习之SmartQQ协议的更多相关文章
- 自学Python六 爬虫基础必不可少的正则
要想做爬虫,不可避免的要用到正则表达式,如果是简单的字符串处理,类似于split,substring等等就足够了,可是涉及到比较复杂的匹配,当然是正则的天下,不过正则好像好烦人的样子,那么如何做呢,熟 ...
- 自学Python四 爬虫基础知识储备
首先,推荐两个关于python爬虫不错的博客:Python爬虫入门教程专栏 和 Python爬虫学习系列教程 .写的都非常不错,我学习到了很多东西!在此,我就我看到的学到的进行总结一下! 爬虫就是 ...
- python从爬虫基础到爬取网络小说实例
一.爬虫基础 1.1 requests类 1.1.1 request的7个方法 requests.request() 实例化一个对象,拥有以下方法 requests.get(url, *args) r ...
- 自学Python七 爬虫实战一
此文承接上文,让我们写一个简简单单的爬虫,循序而渐进不是吗?此次进行的练习是爬取前5页什么值得买网站中的白菜价包邮信息.包括名称,价格,推荐人,时间. 我们所需要做的工作:1.确定URL并获得页面代码 ...
- Python扫描器-爬虫基础
0x1.基础框架原理 1.1.爬虫基础 爬虫程序主要原理就是模拟浏览器发送请求->下载网页代码->只提取有用的数据->存放于数据库或文件中 1.1.基础原理 1.发起HTTP请求 2 ...
- Python BeautifulSoup4 爬虫基础、多线程学习
针对 崔庆才老师 的 https://ssr1.scrape.center 的爬虫基础练习.Threading多线程库.Time库.json库.BeautifulSoup4 爬虫库.py基本语法
- 开发记录_自学Python写爬虫程序爬取csdn个人博客信息
每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已... 于是萌生了一个想法: 想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来. 打算通过网络各种搜集资料 ...
- Python归纳 | 爬虫基础知识
1. urllib模块库 Urllib是python内置的HTTP请求库,urllib标准库一共包含以下子包: urllib.error 由urllib.request引发的异常类 urllib.pa ...
- 自学Python十 爬虫实战三(美女福利续)
我又来送福利啦!!!不同于上篇文章,这次我们的爬虫采用了多线程,一直以来被所谓的分布式 多线程 爬虫 给唬的怕怕的.今天就来一发多线程爬虫吧,还能看妹子图,想想就觉得很激动!!! 依然是流程解释: ...
随机推荐
- iptables详解(5):iptables匹配条件总结之二(常用扩展模块)
所属分类:IPtables Linux基础 在本博客中,从理论到实践,系统的介绍了iptables,如果你想要从头开始了解iptables,可以查看iptables文章列表,直达链接如下 iptab ...
- 控制台输出(System.out.printf)的使用
一. 介绍 System.out.printf 与 C语言中的 printf 使用方法类似,可以向控制台(Console) 输出指定格式的内容.使用 System.out.printf 的方法比使 ...
- OI数学知识清单
OI常用的数学知识总结 本文持续更新…… 总结一下OI中的玄学知识 先列个单子,(from秦神 数论 模意义下的基本运算和欧拉定理 筛素数和判定素数欧几里得算法及其扩展[finish] 数论函数和莫比 ...
- 2.git进阶篇总结
阅读 Git 原理详解及实用指南 记录 进阶 1 - HEAD.master 与 branch: 介绍了 Git 中的一些「引用」:HEAD.master.branch.这里总结一下: HEAD 是指 ...
- JavaScript学习笔记之BOM对象
目录 1.Window 2.Window Screen 3.Window Location 4.Window History 5.Window Navigator 浏览器对象模型(Browser Ob ...
- js事件委托或事件代理
起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...
- js中阻止事件冒泡和浏览器默认行为
在使用javascript编程时会遇到一个问题,就是当你给html添加事件时,由于浏览器默认的为冒泡型事件触发机制,所以会触发你不想触发的事件.那么通过如下的函数可以解决这个问题.[兼容IE和FF] ...
- Jupyter Notebook 下安装 PHP 内核
我最近被强烈安利了 Jupyter Notebook 这个交互式笔记本.然后试用了它自带的 Python 内核后,这个应用整体给我的感觉很不错,就去搜索了下它所支持的其它内核 Jupyter Kern ...
- 2.5.3 简单的 echo 输出
echo的任务就是产生输出,可用来提示用户,或是用来产生数据供进一步处理. 原始的echo命令只会将参数打印到标准输出,参数之间以一个空格隔开,并以换行符号(newline)结尾. ...
- hdu 4971 多校10最大权闭合图
/* 很明显的最大权闭合图题 */ #include<stdio.h> #include<string.h> #include<queue> using names ...