2014/06/28修改

添加了验证码操作

2014/06/28修改

之前的写得实在太烂了, 所以重写了代码

流程:

1. 访问一次框架的源码(地址), 获取login_sig, appid, pt_version, mibao, pt_lang等参数;


2. 访问获取验证码的地址, 获取验证码(如果需要输入验证码, 则需要再访问其返回的获取验证码的地址, 通常不用验证码的话, 第二个参数就是验证码);


3. 根据QQ号, QQ密码, 验证码的值计算得出p的值(第一次登录需要用到, 计算方法在PSWEncrypt模块中);


4. 构建相关的Form, 并对地址(https://ssl.ptlogin2.qq.com/login)发送请求(必须使用Get方法, Post会出错),  登录成功后会返回一些参数, 例如二次登录需要访问的地址等, 其中ptwebqq在cookie中, 需要另外获取。。;


5. 访问一次第一次登录时返回的地址, 构建相关的Form(参数大多在之前已经得到了, 其中clientid参数在数字10000000-99999999中随便选一个就行了), 并向地址(http://d.web2.qq.com/channel/login2)发送请求, 登录成功后会返回相关的参数, 如uin, status, vfwebqq, psessionid等, 保存下来, 后面其他操作会用到的。


6.至此, webqq登录已经完成。

相关代码:

WebQQLogin.py

#coding=utf-8import re;
import json;
import http;
import urllib;
import random;
import http.cookiejar;
import urllib.request;
from urllib.parse import urlencode;
from PSWEncrypt import PSWEncrypt;
from Queryable import *;URL_LOGIN = "https://ssl.ptlogin2.qq.com/login?";
URL_LOGIN2 = "http://d.web2.qq.com/channel/login2";#打开Chrome访问w.qq.com后右键查看框架源码就能看到这个了, 这个里面包含了登录时要用到的大部分信息
URL_LOAD_INFO = "https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20131024001";
URL_VERYCODE = "https://ssl.ptlogin2.qq.com/check?";
URL_VERYCODE_IMG = "https://ssl.captcha.qq.com/getimage?";webQQHeader = {"Host":"ui.ptlogin2.qq.com","Referer":"http://w.qq.com/","User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.1916.153 Safari/537.36",
};
#后面大多数模块都要用到这个header.....
webQQHeader2 = {"Referer":"http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2", "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
}class WebQQLogin(Queryable):def __init__(self):#先保存一个clientid(8位), 第二次登录的时候要将这个id上传Queryable.__init__(self, {"clientid":str(random.randint(10000000, 99999999))});self._cookie = http.cookiejar.LWPCookieJar();self._opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self._cookie));#多次正则, 感觉效率应该会很低, 但又没有更好的抓取办法def _readInfo(self, url):request = urllib.request.Request(URL_LOAD_INFO, headers = webQQHeader);ret = self._opener.open(request).read().decode("utf-8");login_sig = re.compile("g_login_sig=encodeURIComponent\(\"([^\"]+)\"\)").findall(ret)[0];appid = re.compile("g_appid =encodeURIComponent\(\"(\d+)\"\)").findall(ret)[0];pt_version = re.compile("g_pt_version=encodeURIComponent\(\"(\d+)\"\)").findall(ret)[0];mibao = re.compile("mibao_css=encodeURIComponent\(\"(\w+)\"\)").findall(ret)[0];pt_lang = re.compile("g_lang=\"([^\"]+)\"").findall(ret)[0];#open("1.txt", "wb").write(ret.encode("utf-8"));hiddenList = re.compile('<input\s+type="hidden"\s+name="([^\"]*)"\s+value="([^\"]*)"[^/]+/>').findall(ret);for item in hiddenList:self.setQuery(item[0], item[1]);self.setQueryEx({"login_sig":login_sig, "appid":appid, "js_ver":pt_version, "mibao":mibao, "pt_lang":pt_lang});def _requestVerifyCode(self, param):headerData = {"daid":self.queryInfo("daid"),"target":"self","style":"16","mibao_css":self.queryInfo("mibao"),"appid":self.queryInfo("appid"),"enable_qlogin":"0","no_verifyimg":"1","s_url":"http://w.qq.com/proxy.html","f_url":"loginerroralert","strong_login":"1","login_state":"10","t":"20131024001",};header = {"Host":"Host:ssl.captcha.qq.com","Referer":"https://ui.ptlogin2.qq.com/cgi-bin/login?" + urlencode(headerData), "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36", };data = {"aid":self.queryInfo("appid"),"r":"0.1642276826314628","uin":self.queryInfo("uin"),};request = urllib.request.Request(URL_VERYCODE_IMG + urlencode(data), headers = header);open("verifyCode.jpg", "wb").write(self._opener.open(request).read());verifyCode = input("输入验证码:");return verifyCode;#虽然这个是获取验证码部分, 但一直都没碰到过验证码, 所以。。def _getVerycode(self, id):form = {"login_sig":self.queryInfo("login_sig"), "r":"0.3272944095078856", "js_type":"0", "appid":self.queryInfo("appid"), "js_ver":self.queryInfo("js_ver"), "u1":"http://w.qq.com/proxy.html", "uin":id};request = urllib.request.Request(URL_VERYCODE + urlencode(form));ret = self._opener.open(request).read().decode("utf-8");list = re.compile("ptui_checkVC\('(\d+)','([^\']*)','([^\']+)', '([^\']*)'\);").findall(ret)[0];if(list[0] == "0"):return list[1];else:return self._requestVerifyCode(list[1]);print(list);#debugreturn None;#第一次登录def _firstLogin(self, id, psw):verifycode = self._getVerycode(id);#大部分都用到了之前框架里面抓取到的东西, 避免硬编码(虽然还是有很多无法避免地用到了硬编码)form = {"u":id,"p":PSWEncrypt.encrypt(id, psw, verifycode),"verifycode":verifycode,"webqq_type":self.queryInfo("webqq_type"),"remember_uin":self.queryInfo("remember_uin"),"login2qq":self.queryInfo("login2qq"),"aid":self.queryInfo("appid"),"u1":"{0}?login2qq={1}&webqq_type={2}".format(self.queryInfo("u1"), self.queryInfo("login2qq"), self.queryInfo("webqq_type")),"h":self.queryInfo("h"),"ptredirect":self.queryInfo("ptredirect"),"ptlang":self.queryInfo("pt_lang"),"daid":self.queryInfo("daid"),"from_ui":self.queryInfo("from_ui"),"pttype":self.queryInfo("pttype"),"dumy":self.queryInfo("dumy"),"fp":self.queryInfo("fp"),"action":"0-23-34008","mibao_css":self.queryInfo("mibao"),"t":"1","g":"1","js_type":"0","js_ver":self.queryInfo("js_ver"),"login_sig":self.queryInfo("login_sig"),};#在这里用post方法的话。。会出错request = urllib.request.Request(URL_LOGIN + urlencode(form), headers = webQQHeader);ret = self._opener.open(request).read().decode("utf-8");#第一次登录完成, 保存返回的相关参数tuple = re.compile("ptuiCB\('([^\']*)',\s*'([^\']*)',\s*'([^\']*)',\s*'([^\']*)',\s*'([^\']*)',\s*'([^\']*)'\);").findall(ret)[0];if(tuple[0] == "0" and tuple[1] == "0"):self.setQuery("nick", tuple[-1]);self.setQuery("ptwebqq", re.compile("ptwebqq=([^\s]+)").findall(str(self._cookie))[0]);return tuple[2]; #这里会返回一个地址, 第二次登录的时候要先访问一次这个地址else:print(tuple);#debugreturn None;#第二次登录def _secLogin(self, url):#先访问一次第一次登录返回的那个地址self._opener.open(url);data = {"r":'{"ptwebqq":"' + self.queryInfo("ptwebqq") + '","clientid":' + self.queryInfo("clientid") + ',"psessionid":"","status":"online"}'};request = urllib.request.Request(URL_LOGIN2, headers = webQQHeader2);ret = json.loads(self._opener.open(request, urlencode(data).encode("utf-8")).read().decode("utf-8"));#retcode为0则第二次登录成功, 保存返回的相关参数if(ret["retcode"] == 0):result = ret["result"];self.setQuery("status", result["status"]);self.setQuery("vfwebqq", result["vfwebqq"]);self.setQuery("psessionid", result["psessionid"]);return True;else:print(ret); #debugreturn False;def login(self, id, psw):self.setQuery("uin", id);self._readInfo(URL_LOAD_INFO);secLoginAddr = self._firstLogin(id, psw);if(secLoginAddr == None):return None;if(not self._secLogin(secLoginAddr)):return None;self.setQuery("opener", self._opener);self.setQuery("header", webQQHeader2);#登录成功后将已经保存的所有参数信息返回return self.getDict();def main():qq = WebQQLogin();print(qq.login("397828451", "xxxx"));if(__name__ == "__main__"):main();


Queryable.py

#coding=utf-8class Queryable:def __init__(self, dict):self.__dict = dict;def queryInfo(self, key):if(self.find(key)):return self.__dict[key];return None;def setQuery(self, key, value):self.__dict[key] = value;def setQueryEx(self, dict):self.__dict.update(dict);def find(self, key):if(key in self.__dict):return True;return False;def getDict(self):return self.__dict;

PSWEncrypt.py  在  http://blog.csdn.net/qq506657335/article/details/20801181

webQQ协议——模拟登录相关推荐

  1. ipad协议模拟登录

    PC微信协议.web微信协议.ipad微信协议.所有平台的微信协议里,只有ipad微信协议功能最多,稳定,还可以同时登陆手机版,也就是说,在授权给ipad版本登录去实现商业能力时,您仍然可以在手机端正 ...

  2. HTTP 笔记与总结(5)socket 编程:使用 HTTP 协议模拟登录并发帖

    在 VeryCD 上注册两个帐号,发送和接收站内信,观察 POST 请求时发送的参数(h****2 发送给 d***2).(最好用 FireFox 的 FireBug 工具,发送站内信之前选中 &qu ...

  3. 深澜认证协议分析,python模拟登录

    深澜校园网模拟登录 1.分析api 连接到校园网,登录网站自动弹出来 http://172.16.8.6/srun_portal_pc?ac_id=1&theme=basic2 先输入错的密码 ...

  4. 网络协议模拟之QQ微博分享接口应用

    QQ微博在营销领域越来越受青睐了,这里面集成了很多非常有用的接口,像是邮件分享.空间分享.QQ分享.微信分享等.这相对于传统的直接模拟协议,登录邮箱等方式进行邮件发送甚至更有效.所有这些都没什么技术难 ...

  5. python爬虫模拟登录人人网

    模拟登录:爬取基于某些用户的用户信息. 需求1:对人人网进行模拟登录. 点击登录按钮之后会发起一个post请求 post请求中会携带登录之前录入的相关的登录信息(用户名,密码,验证码-) 验证码:每次 ...

  6. PHP cURL应用实现模拟登录与采集使用方法详解

    对于做过数据采集的人来说,cURL一定不会陌生.虽然在PHP中有file_get_contents函数可以获取远程链接的数据,但是它的可控制性太差了,对于各种复杂情况的采集情景,file_get_co ...

  7. python爬虫(四)cookie模拟登录和反反爬案例

    处理不被信任证书的网站 SSL证书:数字证书的一种,配置在服务器上面的,类似于驾驶证.护照和营业执照的电子副本.因为配置在服务器上,也称为SSL服务器证书. SSL证书的特点:遵循了SSL协议,由收信 ...

  8. 用python实现模拟登录人人网

    我决定从头说起.懂的人可以快速略过前面理论看最后几张图. web基础知识 从OSI参考模型(从低到高:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层)来说,我们的互联网属于应用层.从TCP ...

  9. 2021春项目需求记录 python实现模拟登录+爬取NASA Modis 上的产品数据

    python实现模拟登录+爬取Nasa Modis 上的产品数据 概述 需求分析 基本思路 代码 概述 3月的中旬时候参与了学校的一个大创项目,作为本科生,本人只是摸鱼打杂,负责了其中的一个功能模块: ...

  10. 【Android+OkHttp3+Jsoup】 模拟登录教务系统 抓取课表和成绩

    原文链接:https://blog.csdn.net/u013347241/article/details/52711018 今天这篇文章为大家带来的是模拟登录教务系统并抓取课表和成绩的详细实现过程. ...

最新文章

  1. Oracle Gateway使用分享
  2. 基于koajs的web项目构建-心得篇
  3. python简单代码input-Python简单程序的练习
  4. java json utf-8_Java 编码 和JSON
  5. java map大小_Java中HashMap的size()方法: HashMap.size() - Break易站
  6. 包头市民族中学2021高考成绩查询,2021庆阳高考成绩查询系统入口
  7. setuptools Declaring Dependencies
  8. 两种include方式及filter中的dispatcher解析
  9. office另存为pdf的加载项_你可能需要用到的office转换技巧
  10. SQL server 2012 数据库还原操作
  11. method swizzling你应该注意的点
  12. php 代码的分离和调用及注意事项(版本、变量及cookie与session的区别,PHP包含文件函数include、include_once、require、require_once区别和总结)
  13. Android GIS开发系列-- 入门季(15) 网络图层加载
  14. ajax请求csv文件,使用Ajax读取csv /文本文件
  15. python负数的表示方法_负整数的Python表示
  16. 雷电3接口能干嘛_Sonnet发布雷电3接口双卡读卡机RED MINIMAG Pro
  17. 蓝桥杯2020年第十届C/C++省赛A组第4题-迷宫(bfs)
  18. Aria2远程下载方案部署(CentOS7+Aria+AriaNG+Nginx)
  19. 用青龙面板跑闲趣赚(趣闲赚)脚本(收益超级稳定)
  20. PDF生成技巧:怎么把其他格式转换成PDF文件?

热门文章

  1. Cximage 库使用,直接读取图像数据到内存。
  2. 解决win10上“RDP Wrapper里的Not supported“问题
  3. 小米笔记本重装系统BOOT启动菜单识别不了硬盘无法启动进入系统
  4. servlet使用jsp内置对象
  5. oracle密码过期了,oracle密码过期的彻底解决方案
  6. Postman汉化补丁
  7. confluence编辑文件和文字_知识管理Confluence:常用基本操作
  8. 推荐克莱夫·汤普森《天才程序员》
  9. IIC,SPI,I2S
  10. [560]python简单验证文本的Zipf分布