HttpClient模拟登陆例子

第一步:
创建httpclient对象,它的地位相当于一个浏览器
第二步:
创建一个httpget或者httppost请求对象,这是一个请求,可以由httpclient发送出去
第三步:
调用httpclient.excute(httpget)方法来执行
第四步:
读取服务器返回的response
第五步:
释放链接

chrome浏览器抓取请求信息:在地址栏输入 chrome://net-internals/#requests 即可进入。
遇到服务器拒绝请求403的情况:
 需要在请求中添加模拟的浏览器版本信息:httppost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.77 Safari/537.1");

调用HttpClient中的PostMethod与GetMethod类似,除了设置PostMethod的实例与GetMethod有些不同之外,剩下的步骤都差不多。在下面的例子中,省去了与GetMethod相同的步骤,只说明与上面不同的地方,并以登录清华大学BBS为例子进行说明。
构造PostMethod之前的步骤都相同,与GetMethod一样,构造PostMethod也需要一个URI参数,在本例中,登录的地址是http://www.newsmth.net/bbslogin2.php。在创建了PostMethod的实例之后,需要给method实例填充表单的值,在BBS的登录表单中需要有两个域,第一个是用户名(域名叫id),第二个是密码(域名叫passwd)。表单中的域用类NameValuePair来表示,该类的构造函数第一个参数是域名,第二参数是该域的值;将表单所有的值设置到PostMethod中用方法setRequestBody。另外由于BBS登录成功后会转向另外一个页面,但是HttpClient对于要求接受后继服务的请求,比如POST和PUT,不支持自动转发,因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的"自动转向"部分。代码如下:
String url = "http://www.newsmth.net/bbslogin2.php";
PostMethod postMethod = new PostMethod(url);
// 填入各个表单域的值
NameValuePair[] data = { new NameValuePair("id", "youUserName"),
new NameValuePair("passwd", "yourPwd") };
// 将表单的值放入postMethod中
postMethod.setRequestBody(data);
// 执行postMethod
int statusCode = httpClient.executeMethod(postMethod);
// HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
// 301或者302
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || 
statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
    // 从头中取出转向的地址
    Header locationHeader = postMethod.getResponseHeader("location");
    String location = null;
    if (locationHeader != null) {
     location = locationHeader.getValue();
     System.out.println("The page was redirected to:" + location);
    } else {
     System.err.println("Location field value is null.");
    }
    return;
}




HttpClient支持自动转向处理,但是象POST和PUT方式这种要求接受后继服务的请求方式,暂时不支持自动转向,因此如果碰到POST方式提交后返回的是301或者302的话需要自己处理。就像刚才在POSTMethod中举的例子:如果想进入登录BBS后的页面,必须重新发起登录的请求,请求的地址可以在头字段location中得到。不过需要注意的是,有时候location返回的可能是相对路径,因此需要对location返回的值做一些处理才可以发起向新地址的请求。
另外除了在头中包含的信息可能使页面发生重定向外,在页面中也有可能会发生页面的重定向。引起页面自动转发的标签是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">。如果你想在程序中也处理这种情况的话得自己分析页面来实现转向。需要注意的是,在上面那个标签中url的值也可以是一个相对地址,如果是这样的话,需要对它做一些处理后才可以转发。




这里获取到了登录后的cookie,一般网站都是通过cookie验证来检查是否登录。
如果获取得到,我们就相当于登录成功了。


1.HttpClient支持SSL连接,代码请另百度
2.//httpclient.getConnectionManager().shutdown();被屏蔽掉和HttpClient httpclient=new DefaultHttpClient();定义为全局变量的原因就是这样才能保证第一次post登录之后,第二次访问页面不会提示未登录,通俗的讲只要HttpClient的实例没有重新赋值,它会自动保存cookie,下次访问将自动附带上。


我们知道服务器会保存session会话,但是客户端是通过cookie来对应session会话的,所以在发送post的时候,我们需要将之前httpclient自动保存的cookie发送到服务器端。


http://www.renren.com/PLogin.do



import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class loginRenRen {
//	可以登陆人人
	public static void main(String args[]){
		String reUrl = getLoginReDirecitonUrl();
		getLoginedPage(reUrl);
		try {
			httpClient.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	static CloseableHttpClient httpClient = HttpClients.createDefault();
	
	public static String  getLoginReDirecitonUrl(){
		String loginurl = "http://www.renren.com/PLogin.do";
		String account  = "你的账号";
		String password = "你的密码";
		
		
		HttpPost httpPost = new HttpPost(loginurl);
		
		httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) " +
        		"Chrome/21.0.1180.77 Safari/537.1");
		
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		
		nvps.add(new BasicNameValuePair("email", account));
		nvps.add(new BasicNameValuePair("password",password));
		nvps.add(new BasicNameValuePair("domain", "renren.com"));  
        nvps.add(new BasicNameValuePair("captcha_type", "web_login"));  
        nvps.add(new BasicNameValuePair("origURL", "http://www.renren.com/home"));  
        String reDerictionUrl="";
        httpPost.setEntity(new UrlEncodedFormEntity(nvps,Consts.UTF_8));
        CloseableHttpResponse response = null;
        try {
        	response = httpClient.execute(httpPost);
//        	测试返回结果的报文内容,得知分为两部分:header和entity
//        	header包含了定向请求以及接受的各种编码等参数设定,entity是返回的HTML的内容
//        	Header[] headers = response.getAllHeaders();
//        	HttpEntity resEntity = response.getEntity();
//        	for(Header h:headers){
//        		System.out.println(h.getName()+h.getValue());
//        	}
//        	String entityContent = EntityUtils.toString(resEntity);
//        	EntityUtils.consume(resEntity);
//        	System.out.println(entityContent);
        	Header locationHeader = response.getFirstHeader("location");//location大小写没有区分
//        	System.out.println(locationHeader.getValue());//打印出来的就是跳转地址
        	reDerictionUrl = locationHeader.getValue();
        	return reDerictionUrl;
		} catch (ClientProtocolException e) {
			System.out.println("登陆失败");
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("登陆失败");
			return null;
		}finally{
			httpPost.abort();
			try {
				response.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void getLoginedPage(String reDirecitonUrl){
		String page = sendGet(reDirecitonUrl);
		System.out.println(page);
		
	}
	
	
	public static String sendGet(String url) {  
	        CloseableHttpResponse response = null;  
	        String content = null;  
	        try {  
	            HttpGet get = new HttpGet(url);  
	            response = httpClient.execute(get);  
	            HttpEntity entity = response.getEntity();  
	            content = EntityUtils.toString(entity);  
	            EntityUtils.consume(entity);  
	            return content;  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	            if (response != null) {  
	                try {  
	                    response.close();  
	                } catch (IOException e1) {  
	                    e1.printStackTrace();  
	                }  
	            }  
	        }  
	        return content;  
	    }  

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值