public class Http_client { private static final Log logger = LogFactory.getLog(Http_client.class); static String SINA_PK = "EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D24" + "5A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD39" + "93CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE" + "1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443"; static DefaultHttpClient client = new DefaultHttpClient(); String html = null; public DefaultHttpClient login(String userName, String pwd) throws HttpException, IOException { client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000); client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000); String su = encodeAccount(userName);//账户重新编码 String initPageURL = "http://login.sina.com.cn/sso/prelogin.php?entry=sso&" + "callback=sinaSSOController.preloginCallBack&su=" + su + "&rsakt=mod&client=ssologin.js(v1.4.5)" + "&_=" + getServerTime(); HttpGet get = newGet(initPageURL);//第1次访问 HttpResponse responceGet = client.execute(get); int resStatu = responceGet.getStatusLine().getStatusCode(); if (resStatu == HttpStatus.SC_OK) { HttpEntity entity = responceGet.getEntity(); if (entity != null) { html = EntityUtils.toString(entity, "utf-8"); } } String jsonBody = StringUtils.substringBetween(html, "(", ")"); String nonce = ""; long servertime = 0L; String rsakv = ""; nonce = StringUtils.substringBetween(jsonBody, "nonce\":\"", "\""); //System.out.println(nonce); rsakv = StringUtils.substringBetween(jsonBody, "rsakv\":\"", "\""); //System.out.println(rsakv); servertime = Long.parseLong(StringUtils.substringBetween(jsonBody, "servertime\":", ",")); //System.out.println(servertime); get.abort(); String loginURL = "http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.5)"; HttpPost post = new HttpPost(loginURL);//第2次访问 String pwdString = servertime + "\t" + nonce + "\n" + pwd; String sp = ""; try { sp = new BigIntegerRSA().rsaCrypt(SINA_PK, "10001", pwdString);//密码重新编码 } catch (InvalidKeyException e) { logger.error("AES加密密钥大于128!", e); } catch (IllegalBlockSizeException e) { logger.error(e); } catch (BadPaddingException e) { logger.error(e); } catch (NoSuchAlgorithmException e) { logger.error(e); } catch (InvalidKeySpecException e) { logger.error(e); } catch (NoSuchPaddingException e) { logger.error(e); } List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("entry", "weibo")); nvps.add(new BasicNameValuePair("gateway", "1")); nvps.add(new BasicNameValuePair("from", "")); nvps.add(new BasicNameValuePair("savestate", "7")); nvps.add(new BasicNameValuePair("useticket", "1")); nvps.add(new BasicNameValuePair("ssosimplelogin", "1")); nvps.add(new BasicNameValuePair("useticket", "1")); nvps.add(new BasicNameValuePair("vsnf", "1")); nvps.add(new BasicNameValuePair("vsnval", "")); nvps.add(new BasicNameValuePair("su", su)); nvps.add(new BasicNameValuePair("service", "miniblog")); nvps.add(new BasicNameValuePair("servertime", servertime + "")); nvps.add(new BasicNameValuePair("nonce", nonce)); nvps.add(new BasicNameValuePair("pwencode", "rsa2")); nvps.add(new BasicNameValuePair("rsakv", rsakv)); nvps.add(new BasicNameValuePair("sp", sp)); nvps.add(new BasicNameValuePair("encoding", "UTF-8")); nvps.add(new BasicNameValuePair("prelt", "115")); nvps.add(new BasicNameValuePair( "url", "http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack")); nvps.add(new BasicNameValuePair("returntype", "META")); post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); HttpResponse responcePost = client.execute(post); //CookieStore cookiestore=client.getCookieStore(); //client.setCookieStore(cookiestore); int postStatu = responcePost.getStatusLine().getStatusCode(); if (postStatu == HttpStatus.SC_OK) { System.out.println("OK"); HttpEntity entity = responcePost.getEntity(); if (entity != null) { html = EntityUtils.toString(entity, "utf-8"); //System.out.println(html); } } String url_3rd = html.substring(html.indexOf("replace") + 9, html.indexOf("');")); //System.out.println(url_3rd); HttpGet get_3rd = new HttpGet(url_3rd);//第3次访问 HttpResponse responce_3rd = client.execute(get_3rd); int status_3rd = responce_3rd.getStatusLine().getStatusCode(); if (status_3rd == HttpStatus.SC_OK) { HttpEntity entity = responce_3rd.getEntity(); if (entity != null) { html = EntityUtils.toString(entity, "utf-8"); //System.out.println(html); } } post.abort(); return client;//一直持有这个client就能一直获得登录状态了 } private String encodeAccount(String account) { return (new sun.misc.BASE64Encoder()).encode(URLEncoder.encode(account) .getBytes()); } public String getServerTime() { long servertime = new Date().getTime() / 1000; return String.valueOf(servertime); } protected HttpGet newGet(String url) { HttpGet getMethod = new HttpGet(url); getMethod .setHeader( "Accept", "image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"); getMethod.setHeader("Accept-Language", "zh-CN"); getMethod.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); getMethod.setHeader("Accept-Encoding", "deflate"); getMethod .setHeader( "User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; CIBA; MAXTHON 2.0)"); getMethod.setHeader("Connection", "Keep-Alive"); getMethod.setHeader("Cache-Control", "no-cache"); return getMethod; } }
public class BigIntegerRSA { //密码编码方法 public String rsaCrypt(String modeHex, String exponentHex, String messageg) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException { KeyFactory factory = KeyFactory.getInstance("RSA"); BigInteger m = new BigInteger(modeHex, 16); /* public exponent */ BigInteger e = new BigInteger(exponentHex, 16); /* modulus */ RSAPublicKeySpec spec = new RSAPublicKeySpec(m, e); RSAPublicKey pub = (RSAPublicKey) factory.generatePublic(spec); Cipher enc = Cipher.getInstance("RSA"); enc.init(Cipher.ENCRYPT_MODE, pub); byte[] encryptedContentKey = enc.doFinal(messageg.getBytes("GB2312")); return new String(Hex.encodeHex(encryptedContentKey)); } }
先贴上代码,其中部分复用了其他人的代码。
获得登录状态,使用同一个httpclient(这里使用了defaulthttpclient)需要相继访问3个url:
第一次get获得post所需要的东西。
第二次post传给账户密码等参数(很多参数),其中账户密码要经过编码。
第三次get访问post返回的数据中的一个地址。
因为httpclient自动管理cookie的性质,访问完3个网址后就获得了所有的cookie,我们使用这个client就能尽情访问我们所使用的账号才能访问的网址了(如微博,微博实时搜索,通行证等等)。
截至发稿为止,亲测可用。