使用Java中的URL 和 HttpURLConnection 就可以实现模拟网页登陆!
分析登陆的协议,可以使用HttpWatcher,蛮好用的!?
目前就两种网页请求方式?
Get和Post?
我们可以自己先写好这两个方法,以便之后调用?
这个就是Get请求方式了,参数就是URL地址?
- public?static?String?get(String?url)?{??
- ??
- ????System.out.println("get>>>"?+?url);??
- ????URL?serverUrl;??
- ????HttpURLConnection?conn;??
- ????StringBuffer?res?=?new?StringBuffer();??
- ????try?{??
- ????????serverUrl?=?new?URL(url);??
- ????????conn?=?(HttpURLConnection)?serverUrl.openConnection();??
- ????????conn.setRequestMethod("GET");//?"POST"?,"GET"??
- ????????conn.addRequestProperty("Cookie",?cookie);??
- ????????conn.addRequestProperty("Accept-Charset",?"UTF-8;");//?GB2312,??
- ????????conn.addRequestProperty("User-Agent",??
- ????????????????"Mozilla/5.0?(Windows;?U;?Windows?NT?5.1;?zh-CN;?rv:1.9.2.8)?Firefox/3.6.8");??
- ????????conn.connect();??
- ??
- ????????if?(conn.getHeaderFields().get("Set-Cookie")?!=?null)?{??
- ????????????for?(String?s?:?conn.getHeaderFields().get("Set-Cookie"))?{??
- ????????????????cookie?+=?s;??
- ????????????}??
- ????????}??
- ????????InputStream?ins?=?conn.getInputStream();??
- ??
- ????????String?charset?=?"UTF-8";??
- ????????InputStreamReader?inr?=?new?InputStreamReader(ins,?charset);??
- ????????BufferedReader?bfr?=?new?BufferedReader(inr);??
- ??
- ????????String?line?=?"";??
- ??
- ????????do?{??
- ????????????res.append(line);??
- ????????????line?=?bfr.readLine();??
- ????????????//?System.out.println(line);??
- ????????}?while?(line?!=?null);??
- ??
- ????????System.out.println("Value>>"?+?res);??
- ??
- ????}?catch?(MalformedURLException?e)?{??
- ????????//?TODO?Auto-generated?catch?block??
- ????????e.printStackTrace();??
- ????}?catch?(IOException?e)?{??
- ??
- ????}??
- ????return?res.toString();??
- }??
1.登陆前,我们需要判断此次登陆是否需要手动输入验证码。?
地址(GET):http://ptlogin2.qq.com/check?uin=********(QQ号码)&appid=1003903(固定)&r=0.2664082343145449(随机18位? 简单的说?? 0.后面+随机16位数)?
返回值有两种?
第一种:?
ptui_checkVC('1','8a6143167c8ca486696cf01c3ea088d658b913d64b11289b')?
这种情况下,我们需要获得验证码图片并手动输入验证码。?
此时我们可以将图片保存下来,然后使用SWING显示并输入,就可以得到验证码了。?
第二种:?
“ptui_checkVC('0','!OMD');?
这种情况下,!OMD就是我们需要的验证码了。?
2.第一次登陆?
得到验证码之后就可以进行第一次登陆,为什么是第一次?你试验下就知道了,当你此次登陆成功后,发现登陆的QQ并没有提示掉线或者别处登陆的,这是因为我们还需要后续的第二次登陆。?
http://ptlogin2.qq.com/login?u=*******(QQ号)&p=793E7DF74F8D87021F79A69F0DBF8287(md5(md5(密码)+验证码))&verifycode=!OMD(验证码)&webqq_type=10&remember_uin=1&login2qq=1&aid=1003903&u1=http%3A%2F%2Fweb.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert&mibao_css=m_webqq
呵呵~verifycode我们第一步就得到了。QQ号我们也知道。就是参数p啦~?
就是使用密码和验证码经过加密得到的啦。?
想研究加密过程的同学可以百度下,很多的!?
此段加密算法是在一个js脚本里,我们可以下下来这个脚本,然后直接调用。?
- public?static?String?mdP(String?p,?String?code){????
- ????????Object?t?=?null?;??
- ????????try?{????
- ????????????ScriptEngineManager?m?=?new?ScriptEngineManager();????
- ????????????ScriptEngine?se?=?m.getEngineByName("javascript");????
- ????????????se.eval(new?FileReader(new?File("comm.js")));????
- ????????????t?=?se.eval("md5(md5_3(\""+p+"\")+\""+code.toUpperCase()+"\");");????
- ????????????return?t.toString();????
- ????????}catch?(Exception?e)?{????
- ????????????e.printStackTrace();????
- ????????}?????
- ????????return?t.toString();????
- ????}???
第一登陆后,TX会返回Cookie,我们需要保持,在之后的第二次登陆中使用。?
3.第二次登陆?
需要使用Post方法:http://d.web2.qq.com/channel/login2?
POST数据:?
r=%7B%22status%22%3A%22online%22%2C%22ptwebqq%22%3A%22” + ptwebqq + “%22%2C%22passwd_sig%22%3A%22%22%2C%22clientid%22%3A%22” + clientid + “%22%2C%22psessionid%22%3Anull%7D&clientid=” + clientid + “&psessionid=null?
ptwebqq 就是我们在第一次登陆后获得的Cookie里的值,clientid是随机的的值,可以直接使用抓取到的值。?
登陆成功后,会返回数据?
{"retcode":0,"result":{"uin":********(QQ号码),"cip":3071582136,"index":1078,"port":53985,"status":"hidden","vfwebqq":"5ab2ce0743496ffa257aa4119f35e44324171aa08d3e14a4c506b7e392ca80b73e34551cef71a248","psessionid":"8368046764001e636f6e6e7365727665725f7765627171403137322e32372e3138312e3835000062450000079e03620524ef666d0000000a406e4e53734a517a33556d000000285ab2ce0743496ffa257aa4119f35e44324171aa08d3e14a4c506b7e392ca80b73e34551cef71a248"}}
vfwebqq和psessionid在之后和获取好友,群信息,以及发送消息都要使用。?
目前做到发送消息,不过老是返回{"retcode":122,"errmsg":"wrong web client3"}?
Post数据也没有问题,不知道到底是为啥~?
目前写的类也有点乱,打算使用HttpClient重新写~?
附上源代码,谁要是解决了发消息的问题?
给我说声啊~
?