webqq模拟登录参考资料

This is Google's cache of http://loginprogram.googlecode.com/svn-history/r26/qqlogin/src/com/xnet/qqlogin/webqq/WebQQClient.java. It is a snapshot of the page as it appeared on 7 Jan 2013 01:46:18 GMT. The current page could have changed in the meantime. Learn more
Tip: To quickly find your search term on this page, press Ctrl+F or ⌘-F (Mac) and use the find bar.


Text-only version
 
package com.xnet.qqlogin.webqq;


import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;


import javax.swing.JLabel;


import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;


import com.xnet.browser.http.HttpService;
import com.xnet.common.StringUtil;
import com.xnet.qqlogin.common.GlobalURL;
import com.xnet.qqlogin.common.QQUtils;
import com.xnet.qqlogin.common.VerifyCode;


/**
 * <p>Description: </p>
 * @author Huoyan
 * @version 1.0
 * <p>Copyright 2011</p>
 */


public class WebQQClient extends HttpService {


	private final Log log = LogFactory.getLog(this.getClass());
	
	private String qq = null;
	private String pwd = null;
	
	private boolean loginState = false;  //登录状态
	private long clientid = 18662986;
	private String psessionid = "";
	
	private String ptwebqq;
	private String vfwebqq = null;
	private String skey = null;
	
	public WebQQClient(String qq, String pwd){
		this.qq = qq;
		this.pwd = pwd;
		this.clientid = QQUtils.createClientID();
		//设置请求头中参数refer
		setRefer(GlobalURL.REFER);
	}
	
	/**
	 * webQQ接口登录
	 */
	public void login(String verifyCode){
		
		try {
			if(qq == null || pwd == null){
				log.error("使用qq: " + qq + "登录时,用户名或密码为空,登录失败");
			}else{/*
				//登录步骤1,获取登陆表单信息,检查当前QQ是否需要验证码登录
				String checkIdUrl = GlobalURL.CHECK_ID_URL + qq;
				//发送请求
				String res = getReturnStr(checkIdUrl);
				
				//使用正则匹配获取验证码编号
				// ptui_checkVC('0','!ZLE');返回这个就不需要获取验证码了。验证码就是!ZLE
				// ptui_checkVC('1','95ab7db15e5ab17f50f25d33598259e83ccc098c4af2f8a4');这个长字符串就需要使用了
				String checkType = StringUtil.findPattern("\\,\\'([!\\w]+)\\'", res);
				log.info(checkType);
				String check = ""; //客户端输入的验证码
				//判断是否需要验证码登录
				if (!checkType.startsWith("!")) {
					//需要输入验证码登录
					byte[] ibs = readCheckImage(GlobalURL.CHECK_IMAGE_URL + "&uin=" + qq + "&vc_type=" + checkType);
					//将图片设置在组件JLable上
					ImageIcon ii = new ImageIcon(ibs);
					//lbl.setIcon(ii);
				}else{
					//无需验证码登录
					check = checkType;
				}*/
				StringBuffer loginUrl = new StringBuffer(GlobalURL.LOGIN_URL);
				//登录步骤2,发送登录信息
				loginUrl.append("u=").append(qq)
					.append("&p=").append(QQUtils.makeMD5Str(pwd, verifyCode))
					.append("&verifycode=").append(verifyCode)
					.append("&webqq_type=10").append("&remember_uin=1")
					.append("&login2qq=1").append("&aid=1003903")
					.append("&u1=http%3A%2F%2Fweb.qq.com%2Floginproxy.html%3Flogin2qq%3D1%26webqq_type%3D10")
					.append("&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=4-11-25648");
				//发送请求-登录
				log.info(loginUrl.toString());
				String res = getReturnStr(loginUrl.toString());
				log.info(res);
				//返回结果
				// ptuiCB('0','0','http://web2.qq.com/loginproxy.html?strong=true','0','登录成功!');
				// ptuiCB('3','0','','0','您输入的帐号或者密码不正确,请重新输入。');
				// ptuiCB('4','0','','0','您输入的验证码有误,请重试。');
				// ptuiCB('7','0','','0','很遗憾,网络连接出现异常,请您稍后再试。(688916544)');
				if (StringUtil.exist("登录成功!", res)) {
					log.info(">>正在登录..");
				} else {
					log.info("一登录失败");
					//System.out.println(res.indexOf("3",8)); //待完善
					return;
				}
				
				// 从cookie中提取ptwebqq,skey
				ptwebqq = getCookie("ptwebqq");
				skey = getCookie("skey");
				
				//登录步骤3, 再次登陆,只有这次登陆,才算真正登陆qq,这个时候,如果你qq已经登陆,会把你的qq踢下线,而且此次登陆才算上线。
				String channelLoginUrl = "http://d.web2.qq.com/channel/login2";
				String content = "{\"status\":\"online\",\"ptwebqq\":\"" + ptwebqq
						+ "\",\"passwd_sig\":\"\",\"clientid\":\"" + clientid 
						+ "\",\"psessionid\":null}&clientid=" + clientid + "&psessionid=";
				content = "r=" + URLEncoder.encode(content);// urlencode转码,拼装post数据
				//发送请求
				res = postReturnStr(channelLoginUrl, content);
				
				// 这次登陆基本上不会发生什么问题
				// 下面提取很重要的2个数据psessionid ,vwebqq,通用采用正则表达式,虽然结果是个json
				vfwebqq = StringUtil.findPattern("\"vfwebqq\":\"(\\w+)\"", res);
				psessionid = StringUtil.findPattern("\"psessionid\":\"(\\w+)\"", res);
				
				log.info(">>登录成功\n vfwebqq="+vfwebqq + ", psessionid="+psessionid);
				loginState = true; //当前登录状态
				// 到此,登陆就算完成了,后面可以调用发送qq信息等接口了
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			shutdown();
		}
	}
	
	/**
	 * 获取验证码图片字节
	 * @param uri
	 */
	private byte[] readCheckImage(String uri){
		HttpResponse res = get(uri);
		byte[] b = null;
		try {
			InputStream in = res.getEntity().getContent();
			b = IOUtils.toByteArray(in);
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return b;
	}
	
	public static void main(String[] args) {
		//需要验证码QQ2508786110,2351221103, 2536565342
		//不需要2232924183
		WebQQClient c = new WebQQClient("2232924183", "asdf1234");
		String vc = new VerifyCode(c.getClient()).getVerifyCode("2232924183", new JLabel());
		c.login(vc);
	}
}


poll的返回值,也是一个JSON结构,如:{"retcode":103,"errmsg":""} {"retcode":121,"t":"0"} {"retcode":100006,"errmsg":""}
返回103、121,代表连接不成功,需要重新登录;
返回102,代表连接正常,此时服务器暂无信息;
返回0,代表服务器有信息传递过来:包括群信、群成员给你的发信,QQ好友给你的发信。
另外,此程序必须考虑另一种情况:如果网络断线,curl_easy_perform()将返回CURLE_COULDNT_RESOLVE_HOST,返回值buffer为了避免无效赋值:必须赋值为空字符串。
发生错误或有信息到来之时,poll马上返回相应的JSON,占用的时间很短;
但没有信息过来的时候,poll占用的时间一般比较长,不确定,时快时慢。

2)如果等poll获得返回值之后,再去响应用户其他的动作,会感觉有点卡。于是我们另开一个线程,循环不断的poll,而不影响主程序的正常响应,这就是所谓的异步通信;如获得有效信息,即可通过SendMessage消息机制传回主窗口。

线程程序:



http://svn.code.sf.net/p/pythonguiqq/code-0/trunk/api/Api_socket.py

http://svn.code.sf.net/p/pythonguiqq/code-0/trunk/api/md5.py

https://code.google.com/p/loginprogram/source/checkout

你可能感兴趣的:(webqq模拟登录参考资料)