最近几天写了一个模拟登陆webqq并抓取群成员信息的程序
整个程序大致分为两部分,第一部分是登录webqq,第二部分是以登录成功的身份像服务器请求所需的信息。
下面先来说下第一部分。
登录webqq总共需要两步登录
第一步登录:
1.首先要用get方式访问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=0&login_state=10&t=20140612002获取login_sig
其中最后那个t后面的参数可以根据个人具体信息填写,其他参数目前都是固定死的
这个参数的获取方法是利用getmethod的getResponseBodyAsString()方法获得服务器返回的文本,再用正则表达式对文本进行匹配,找到login_sig的值。文本中有关sig值的内容如下:
通过观察我们可以用如下的正则表达式进行匹配 g_login_sig=encodeURIComponent\\(\"(.*?)\"
获取到login_sig之后,我们便可以进行步骤2,获取验证码。
2.获取验证码需要首先用get方式访问https://ssl.ptlogin2.qq.com/check?uin=********&appid=1003903&js_ver=10097&js_type=0&login_sig=JFcjryaVVlls4q7OiWamTvrLI6NE3B5ZcRIxUiulDGRbsEIAfu47h7djpJC4cVzy&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.48204019796249664
其中uin是你要登录的qq号码,login_sig则是步骤1中获取到的值。参数r后面是0.加上16位的随机数(自己随便手敲16个数就可以了)
每次访问后,服务器都会返回类似如下内容
这三个参数都有用,因此要用正则
rs = getMethod.getResponseBodyAsString();
p = Pattern.compile("\'(.*?)\'");
m = p.matcher(rs);
int i = 0;
while (m.find()) {
<span style="white-space:pre"> </span>content[i] = m.group(1);
i++;
}
将结果全部存到一个String类型数组中。
其中第一个参数表示此次登陆是否需要验证码,1代表需要,0代表不需要,网上有人说当第一个参数为0时,第二个参数便是验证码,这个我并没有试过。在我模拟登陆时,发现无论第一个参数是1还是0,浏览器都会向服务器请求个验证码,即使第一个参数是0,你用服务器发给你的验证码去登陆,也是会成功的。于是我就在程序中忽略了这个参数。(而且我感觉基本每次登陆都是要验证码的……)
下面来说第二个参数
说到第二个参数,就要注意一下用httpwatch抓到的浏览器与服务器之间的请求信息了,如图
每次进行登陆时,浏览器都要向服务器请求两次相同的地址,这是为什么?开始的时候没太在意,以为是第一次没请求到,又来了一次。后来发现每次用httpwatch抓包的时候,这个请求都是两次,那么这里就肯定是有原因的了。
经过测试刷新验证码这个功能,发现者两次请求确实是有区别的。
第一次请求结果如图
第二次请求结果如图
第一次获取验证码如图