邀请QQ好友-QQ联系人导入(上)
2009-09-06 00:00:00 来源:WEB开发网通过分析QQ邮箱登录页,发现除了QQ号码和密码之外,还有几个隐藏字段。
sid 常量
firstlogin 常量
starttime
redirecturl 常量
f 常量
p
delegate_url 常量
s 常量
ts
from 常量
uin
aliastype
pp
verifycode
大部分都不清楚什么用途,且都是固定的。
有用的就是 starttime(js生成的当前时间戳)、p(QQ号码和密码混合加密后生成的字符串)、ts(某种算法生成的时间戳,来自服务器)、uin(QQ号码)、aliastype(邮箱域
,通常是 @qq.com)、pp(密码掩码)、verifycode(验证码)
还有几个Cookie:
verifysession(获取验证码时服务器种下的)
pvid、flv、r_cookie(看起来像是跟踪用的)
OK,我们把这些参数及Cookie发送给服务器,就可以登录了。
再做一些加工,一个导入QQ联系人的组件就诞生了,不过这些代码却脆弱无比,只要qq邮箱一更新,那怕少一个空格,我这几个小时的代码就变成垃圾了。所以,如果想用到正
式的项目上,你就要时刻准备更新你的程序~~
ie7 firefox 下测试通过,google浏览器下总说验证码错误。
不多说了,上代码
-----------------QQContactsService.java------------------------------------------------
Java代码
package qq;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public class QQContactsService {
private static QQContactsService qcs = new QQContactsService();
public static QQContactsService getInstance(){
return qcs;
}
public static final RuntimeException QQ_EEROR = new RuntimeException( "qq server error");
public static final RuntimeException QQ_WRONG_PWD = new RuntimeException("qq wrong password");
public static final RuntimeException QQ_WRONG_VERIFY = new RuntimeException("qq wrong verify");
public static final RuntimeException QQ_MANY_LOGIN_TIMES = new RuntimeException("qq too many login times");
public RSAInfo getRSAInfo() {
String loginPage = "http://mail.qq.com/cgi-bin/loginpage";
HttpClient httpClient = newHttpClient();
GetMethod getLoginPage = new GetMethod(loginPage);
try {
int code = httpClient.executeMethod(getLoginPage);
if (code != 200) throw QQ_EEROR;
String body = getLoginPage.getResponseBodyAsString();
String publicKey = QQUtil.paser(body,QQUtil.publicKeyPattern);
String ts = QQUtil.paser(body,QQUtil.tsPattern);
String domain = QQUtil.paser(body,QQUtil.domainPattern);
if (publicKey == null || ts == null || domain == null) throw QQ_EEROR;
return new RSAInfo(publicKey, ts, domain);
} catch (IOException e) {
e.printStackTrace();
throw QQ_EEROR;
}
}
public VerifyCode getVerifyCode() {
HttpClient httpClient = newHttpClient();
GetMethod getVerifyPage = new GetMethod(getVerifyUrl());
try {
int code = httpClient.executeMethod(getVerifyPage);
if (code != 200) throw QQ_EEROR;
System.out.println("code:"+code);
byte[] data = getVerifyPage.getResponseBody();
Cookie[] cookies = httpClient.getState().getCookies();
Cookie verifySession = pickUpVerifySessionCookie(cookies);
System.out.println("verifySession:"+verifySession+",data:"+data);
if (data == null || verifySession == null) throw QQ_EEROR;
return new VerifyCode(verifySession, data);
} catch (IOException e) {
e.printStackTrace();
throw QQ_EEROR;
}
}
public List<QQContact> getQQContacts(AuthInfo authInfo) {
login(authInfo);
String contactsHtml = getQQContactsPage(authInfo);
return QQUtil.parserQQContects(contactsHtml);
}
private String getQQContactsPage(AuthInfo authInfo) {
//http://m154.mail.qq.com/cgi-bin/addr_listall?sid=iaVXkE2ACz61dmYs&category=qq
String domain = authInfo.getParam(AuthInfo.DOMAIN);
String sid = authInfo.getParam("sid");
String contactUrl = domain+"/cgi-bin/addr_listall?sid="+sid+"&category=qq";
GetMethod getAllContect = new GetMethod(contactUrl);
getAllContect.setRequestHeader("Cookie", authInfo.getParam(AuthInfo.COOKIE));
getAllContect.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; InfoPath.2; CIBA)");
HttpClient httpClient = newHttpClient();
try {
httpClient.executeMethod(getAllContect);
String body = new String(getAllContect.getResponseBody(),"gbk");
return body;
} catch (IOException e) {
e.printStackTrace();
throw QQ_EEROR;
}
}
private void login(AuthInfo authInfo){
fillPvidAndRCookie(authInfo);
String domain = authInfo.getParam(AuthInfo.DOMAIN);
PostMethod postMethod = new PostMethod(domain+"/cgi-bin/login?sid=0,2,zh_CN");
postMethod.setRequestBody(toNameValuePer(authInfo));
postMethod.setRequestHeader("Cookie", authInfo.getParam(AuthInfo.COOKIE));
postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
postMethod.setRequestHeader("Referer", "http://mail.qq.com/cgi-bin/loginpage");
postMethod.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; InfoPath.2; CIBA)");
HttpClient httpClient = newHttpClient();
try {
int status = httpClient.executeMethod(postMethod);
if(status != 200 ) throw QQ_EEROR;
String body = postMethod.getResponseBodyAsString();
System.out.println("body:"+body);
String sid = QQUtil.paser(body, QQUtil.sidPattern);
if(sid == null){
String errType = QQUtil.paser(body, QQUtil.errTypePattern);
if("1".equals(errType)) throw QQ_WRONG_PWD;
if("2".equals(errType)) throw QQ_WRONG_VERIFY;
if("17".equals(errType)) throw QQ_MANY_LOGIN_TIMES;
throw QQ_EEROR;
}
System.out.println("sid:"+sid);
Cookie[] cookies = httpClient.getState().getCookies();
addCookie(authInfo,cookies);
authInfo.putParam("sid", sid);
System.out.println("set sid:"+authInfo.getParam("sid"));
}catch (IOException e) {
e.printStackTrace();
throw QQ_EEROR;
}
}
private NameValuePair[] toNameValuePer(AuthInfo authInfo) {
List<NameValuePair> nvp = new ArrayList<NameValuePair>();
Map<String,String> params = authInfo.getParam();
for (Map.Entry<String, String> entry : params.entrySet()) {
if(!entry.getKey().equals(AuthInfo.COOKIE) && !entry.getKey().equals(AuthInfo.DOMAIN)){
nvp.add(new NameValuePair(entry.getKey(),entry.getValue()));
}
}
return nvp.toArray(new NameValuePair[nvp.size()]);
}
private HttpClient newHttpClient() {
HttpClient c = new HttpClient();
c.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
return c;
}
private String getVerifyUrl() {
return "http://ptlogin2.qq.com/getimage?aid=23000101&" + Math.random();
}
private Cookie pickUpVerifySessionCookie(Cookie[] cookies) {
for (Cookie c : cookies) {
System.out.println("cookie:"+c.getName());
if ("verifysession".equalsIgnoreCase(c.getName())) {
return c;
}
}
return null;
}
private void fillPvidAndRCookie(AuthInfo authInfo) {
String cookie = authInfo.getParam(AuthInfo.COOKIE);
cookie+=newPvid();
cookie+=newRCookie();
authInfo.putParam(AuthInfo.COOKIE, cookie);
}
private String newPvid() {
long pvidtmp = (Math.round(Math.random() * 2147483647) * 199) % 10000000000L;
return "pvid="+pvidtmp+";";
}
private String newRCookie() {
long r_cookie = Math.round(Math.random() * 1000000000000L);
return "r_cookie="+r_cookie+";";
}
private void addCookie(AuthInfo authInfo, Cookie[] cookies){
String cookie = authInfo.getParam(AuthInfo.COOKIE);
for(Cookie c : cookies){
cookie += c.toString()+";";
}
System.out.println("addCookie:"+cookie);
authInfo.putParam(AuthInfo.COOKIE, cookie);
}
public static void main(String[] args) {
QQContactsService service = QQContactsService.getInstance();
RSAInfo rsa = service.getRSAInfo();
System.out.println("rsa:"+rsa.getDomain()+","+rsa.getPublicKey()+","+rsa.getTs());
service.getVerifyCode();
}
}
更多精彩
赞助商链接