WebQQプロトコル——アナログログイン
“
2014/06/28修正
認証コード操作が追加されました
2014/06/28修正
前のは本当に下手だったので、コードを書き直しました.
”
プロセス:
1.一次フレームのソースコード(アドレス)にアクセスし、login_を取得するsig, appid, pt_version, mibao, pt_langなどのパラメータ;
2.取得検証コードのアドレスにアクセスし、検証コードを取得する(検証コードを入力する必要がある場合は、返される取得検証コードのアドレスに再アクセスする必要があり、通常検証コードを使用しない場合、2番目のパラメータは検証コードである).
3.QQ番号、QQパスワード、検証コードの値からpの値を計算する(最初のログインに使用する必要があり、計算方法はPSWEncryptモジュールにある).
4.関連するFormを構築し、アドレス(https://ssl.ptlogin2.qq.com/login)送信要求(Getメソッドを使用する必要があります.Postでエラーが発生します)は、ログインに成功すると、二次ログインでアクセスする必要があるアドレスなどのパラメータを返します.ptwebqqはクッキーで、別途取得する必要があります.
5.1回目のログイン時に返されるアドレスにアクセスし、関連するFormを構築し(パラメータの多くは以前に入手されており、clientidパラメータは1000000-99999999で任意に1つ選択すればよい)、アドレス(http://d.web2.qq.com/channel/login2)リクエストを送信し、ログインに成功するとuin、status、vfwebqq、psessionidなどの関連パラメータが返され、保存され、後で他の操作で使用されます.
6.これで、webqqログインが完了しました.
関連コード:
WebQQLogin.py
Queryable.py
PSWEncrypt.pyは
http://blog.csdn.net/qq506657335/article/details/20801181
2014/06/28修正
認証コード操作が追加されました
2014/06/28修正
前のは本当に下手だったので、コードを書き直しました.
”
プロセス:
1.一次フレームのソースコード(アドレス)にアクセスし、login_を取得するsig, appid, pt_version, mibao, pt_langなどのパラメータ;
2.取得検証コードのアドレスにアクセスし、検証コードを取得する(検証コードを入力する必要がある場合は、返される取得検証コードのアドレスに再アクセスする必要があり、通常検証コードを使用しない場合、2番目のパラメータは検証コードである).
3.QQ番号、QQパスワード、検証コードの値からpの値を計算する(最初のログインに使用する必要があり、計算方法はPSWEncryptモジュールにある).
4.関連するFormを構築し、アドレス(https://ssl.ptlogin2.qq.com/login)送信要求(Getメソッドを使用する必要があります.Postでエラーが発生します)は、ログインに成功すると、二次ログインでアクセスする必要があるアドレスなどのパラメータを返します.ptwebqqはクッキーで、別途取得する必要があります.
5.1回目のログイン時に返されるアドレスにアクセスし、関連するFormを構築し(パラメータの多くは以前に入手されており、clientidパラメータは1000000-99999999で任意に1つ選択すればよい)、アドレス(http://d.web2.qq.com/channel/login2)リクエストを送信し、ログインに成功するとuin、status、vfwebqq、psessionidなどの関連パラメータが返され、保存され、後で他の操作で使用されます.
6.これで、webqqログインが完了しました.
関連コード:
WebQQLogin.py
#coding=utf-8
import 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('').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);#debug
return 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);#debug
return 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); #debug
return 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-8
class 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