作者:粉爱_粉爱陈小翔 | 来源:互联网 | 2023-05-17 13:32
HttpClient模拟登陆HTTP协议本来是无状态的,但为了保持会话的状态,使用Cookie保存Session信息,当向服务器发送请求时会附加一些会话信息,从而能区分不同会话
HttpClient模拟登陆
HTTP协议本来是无状态的,但为了保持会话的状态,使用COOKIE保存Session信息,当向服务器发送请求时会附加一些会话信息,从而能区分不同会话的状态。用户登陆过程,其实简单而言,就是首先验证用户名与密码,然后服务器生成会话信息保存到本地,最后用户凭借会话信息能够访问类似用户信息等需登陆的网页。
HttpClient4.5通过COOKIEStore保存用户的会话信息,还提供HttpClientContext保存用户连接的信息。下面是一个使用HttpClient模拟知乎登陆的简单案例。
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.client.COOKIEStore;
import org.apache.http.client.config.COOKIESpecs;
import org.apache.http.client.config.RequestConfig;
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.client.protocol.HttpClientContext;
import org.apache.http.COOKIE.COOKIE;
import org.apache.http.impl.client.BasicCOOKIEStore;
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 ZhiHuTest {
public static void main(String[] args) throws java.text.ParseException {
String name = "username";
String password = "password"
// 全局请求设置
RequestConfig globalCOnfig= RequestConfig.custom().setCOOKIESpec(COOKIESpecs.STANDARD).build();
// 创建COOKIE store的本地实例
COOKIEStore COOKIEStore = new BasicCOOKIEStore();
// 创建HttpClient上下文
HttpClientContext cOntext= HttpClientContext.create();
context.setCOOKIEStore(COOKIEStore);
// 创建一个HttpClient
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig)
.setDefaultCOOKIEStore(COOKIEStore).build();
CloseableHttpResponse res = null;
// 创建本地的HTTP内容
try {
try {
// 创建一个get请求用来获取必要的COOKIE,如_xsrf信息
HttpGet get = new HttpGet("http://www.zhihu.com/");
res = httpClient.execute(get);
// 获取常用COOKIE,包括_xsrf信息,放在发送请求之后
System.out.println("访问知乎首页后的获取的常规COOKIE:===============");
for (COOKIE c : COOKIEStore.getCOOKIEs()) {
System.out.println(c.getName() + ": " + c.getValue());
}
res.close();
// 构造post数据
List valuePairs = new LinkedList();
valuePairs.add(new BasicNameValuePair("email", name));
valuePairs.add(new BasicNameValuePair("password", password));
valuePairs.add(new BasicNameValuePair("remember_me", "true"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(valuePairs, Consts.UTF_8);
entity.setContentType("application/x-www-form-urlencoded");
// 创建一个post请求
HttpPost post = new HttpPost("https://www.zhihu.com/login/email");
// 注入post数据
post.setEntity(entity);
res = httpClient.execute(post);
// 打印响应信息,查看是否登陆是否成功
System.out.println("打印响应信息===========");
HttpClientUtils.printResponse(res);
res.close();
//放在post请求之后,获取的是响应头的Set-COOKIE
System.out.println("登陆成功后,新的COOKIE:===============");
for (COOKIE c : context.getCOOKIEStore().getCOOKIEs()) {
System.out.println(c.getName() + ": " + c.getValue());
}
// 构造一个新的get请求,用来测试登录是否成功
HttpGet newGet = new HttpGet("http://www.zhihu.com/question/following");
res = httpClient.execute(newGet, context);
String cOntent= EntityUtils.toString(res.getEntity());
System.out.println("登陆成功后访问的页面===============");
System.out.println(content);
res.close();
} finally {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}