QQ机器人实现原理之Java篇

1.登录:

前言:QQweb端想要登录,首先有两个很重的参考的文件:

第一个是map.js这个文件,这个文件是进入到QQweb页面,F5刷新刷出来的,记录着几个重要信息的生成方式:

1.登录后,获取好友列表需要传的hash值算法,该算法值如下:其中uin的参数为你的QQ号,ptvfwebqq为空字符

var hash2 = function(uin,ptvfwebqq){
            uin += "";
            var ptb = [];
            for (var i=0;i                 var ptbIndex = i%4;
                ptb[ptbIndex] ^= ptvfwebqq.charCodeAt(i);
            }
            var salt = ["EC", "OK"];
            var uinByte = [];
            uinByte[0] = (((uin >> 24) & 0xFF) ^ salt[0].charCodeAt(0));
            uinByte[1] = (((uin >> 16) & 0xFF) ^ salt[0].charCodeAt(1));
            uinByte[2] = (((uin >> 8) & 0xFF) ^ salt[1].charCodeAt(0));
            uinByte[3] = ((uin & 0xFF) ^ salt[1].charCodeAt(1));
            var result = [];
            for (var i=0;i<8;i++){
                if (i%2 == 0)
                    result[i] = ptb[i>>1];
                else
                    result[i] = uinByte[i>>1];
            }
            return byte2hex(result);

        };


        var byte2hex = function(bytes){//bytes array
            var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
            var buf = "";

            for (var i=0;i                 buf += (hex[(bytes[i]>>4) & 0xF]);
                buf += (hex[bytes[i] & 0xF]);
            }
            return buf;
        }

第二个是是接口https://tajs.qq.com/stats,这个请求同样会返回一个算法js,该js用于初始化生成两个重要的cookie,即pgv_pvi、pgv_si这两个cookie,其生成公式如下:

a.si = function() {
            var a = p("pgv_si");
            a || (a = r("s"),
            q("pgv_si", a));
            return a
        }();

 a.pvi = function() {
            var b = p("pgv_pvi");
            b || (a.ty = 0,
            b = r(),
            q("pgv_pvi", b, "Sun, 18 Jan 2038 00:00:00 GMT;"));
            return b
        }();

其调用的方法为该方法中的:

f方法一:判断这两个cookie是否存在,如果不存在则为null

function p(c) {
        return (c = document.cookie.match(new RegExp("(?:^|;\\s)" + c + "=(.*?)(?:;\\s|$)"))) ? c[1] : ""
    }

方法二:如果上面的返回为null,则调用下列方法来生成cookie的值:

function r(c) {
        return (c || "") + Math.round(2147483647 * (Math.random() || .5)) * +new Date % 1E10
    }

方法三:调用 下列方法进行cookie生成

function q(c, a, b) {
        var d = window.location.host
          , e = {
            "com.cn": 1,
            "net.cn": 1,
            "gov.cn": 1,
            "com.hk": 1,
            "co.nz": 1,
            "org.cn": 1,
            "edu.cn": 1
        }
          , f = d.split(".");
        2 < f.length && (d = (e[f.slice(-2).join(".")] ? f.slice(-3) : f.slice(-2)).join("."));
        document.cookie = c + "=" + a + ";path=/;domain=" + d + (b ? ";expires=" + b : "")
    }

正式开始:

1.第一个带着上面生成cookie,进行请求,生成二维码

网址:https://ssl.ptlogin2.qq.com/ptqrshow

参数:该网址所有的参数,除了t之外都是固定值,t的值为17至18位小数的随机值

作用:为了生成二维码

2.第二个网址如下

网址:https://xui.ptlogin2.qq.com/ptui_ver.js,

参数:该网址的所有的参数,除了v为17至18位小数的随机值,其它的都是固定值

作用:是为了获取ptqrtoken、login_sig两个参数,这两个参数是为了判断QQ二维码是否被扫描的所需要的参数

ptqrtoken的值为该接口返回的名为qrsig的cookie的值,并调用https://tajs.qq.com/stats返回的js中的如下方法获得:

hash33: function(t) {
            for (var e = 0, i = 0, n = t.length; i < n; ++i)
                e += (e << 5) + t.charCodeAt(i);
            return 2147483647 & e
        }

login_sig的值为该接口返回的名为pt_login_sig的cookie的值

3.第三个请求网址如下:

网址:https://ssl.ptlogin2.qq.com/ptqrlogin

参数:该参数出了ptqrtoken、login_sig,为上面接口获取的值,其它的都是固定值;

附注:该接口请求需带有referer的头

作用:判断二维码是否已经被扫描,如果被扫描且登录会返回一个登录网址

4.第四个请求网址如下:

网址:上个请求返回的登录网址

作用:该接口需要获取其所有的cookie,并用做下次请求

5.请求的网站如下:

网址:http://s.web2.qq.com/api/getvfwebqq?ptwebqq=&clientid=53999199&psessionid=&t="+new Date().getTime()

参数:该参数中ptwebqq的参数为空,clientid的id为固定值,psessionid为空,t为时间戳

附注:该接口,需要带refer头。该接口返回的cookie会有几个不规范的cookie,这里面涉及cookie的策略问题,可通过重写策略,进行cookie获取,同时还有几个重复的cookie名的cookie,其值为空,可通过人工进行删除。

作用:为了获取参数vfWebQQ,以便以后使用

6.请求的网址如下:

网址:http://d1.web2.qq.com/channel/login2

参数:参数形式r={"ptwebqq":"","clientid":53999199,"psessionid":"","status":"online"},需要注意的是需要对{"ptwebqq":"","clientid":53999199,"psessionid":"","status":"online"}参数进行编码,编码为ISO-8859-1

附注:该网址需要带两个头,Referer和Content-Type头,Content-Type=application/x-www-form-urlencoded

作用:为了获取参数psessionid,以便后面的获取群成员列表、好友列表等数据使用

7.请求的网址如下:

网址:http://s.web2.qq.com/api/get_user_friends2

参数:r={"vfwebqq":XXXXX,"hash":XXXXX},vfwebqq和hash的值均为上述接口已经获取的值,同样的需要对{"vfwebqq":XXXXX,"hash":XXXXX}进行ISO-8859-1的编码

附注:该网址需要带两个头,Referer和Content-Type头,Content-Type=application/x-www-form-urlencoded

作用:为了获取还有列表

8.剩余的参数什么的,自己去抓就可以了,写累了就到这。另温馨提示:后面refer头指向的网址有变化,可别懵逼的都是用同一个refer头,不然浪费时间

9添加一个重要的说明,QQ爬取消息时,必须要请求的接口,最近联系人接口(get_recent_list2)、在线人数接口(get_online_buddies2),如果不获取这些,你会发现你的QQ会话消息是不阻塞请求的。

 

 

你可能感兴趣的:(QQ机器人,QQWeb爬虫,SmartQQAPI接口)