一、HttpClient简介

HttpClient是一个客户端的HTTP通信实现库,它不是一个浏览器。关于HTTP协议,可以搜索相关的资料。它设计的目的是发送与接收HTTP报文。它不会执行嵌入在页面中JavaScript代码,所以当需要抓取通过AJAX技术获取实际内容的页面时需要使用WebClient等其他开源库。HttpClient最新版已经到第5版,但已经稳定的应该是4.5.2版本,官方网址:http://hc.apache.org/

二、HttpClient简单使用

HttpClient的主要用途是接收HTTP响应的内容,下面介绍HttpClient的简单使用,抓取博客园的首页。至于HttpClient4.5的常用API可以参考这篇文章:http://liangbizhi.github.io/httpclient-4-3-x-chapter-1/

package com.httpclient.demo;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; public class SimpleHttpClient {
// 使用HttpClient获取博客园首页
public static void main(String[] args) throws ClientProtocolException, IOException {
String targetUrl = "http://www.cnblogs.com/"; // 1.建立HttpClient对象
CloseableHttpClient client = HttpClients.createDefault(); // 2.建立Get请求
HttpGet get = new HttpGet(targetUrl); // 3.发送Get请求
CloseableHttpResponse res = client.execute(get); // 4.处理请求结果
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = res.getEntity();
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
String mimeType = contentType.getMimeType();
// 获取字节数组
byte[] content = EntityUtils.toByteArray(entity);
if (charset == null) {
// 默认编码转成字符串
String temp = new String(content);
String regEx = "(?=<meta).*?(?<=charset=[\\'|\\\"]?)([[a-z]|[A-Z]|[0-9]|-]*)";
Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(temp);
if (m.find() && m.groupCount() == 1) {
charset = Charset.forName(m.group(1));
} else {
charset = Charset.forName("ISO-8859-1");
}
}
System.out.println(new String(content, charset));
} } }

  

三、HttpClient模拟登陆

HTTP协议本来是无状态的,但为了保持会话的状态,使用Cookie保存Session信息,当向服务器发送请求时会附加一些会话信息,从而能区分不同会话的状态。用户登陆过程,其实简单而言,就是首先验证用户名与密码,然后服务器生成会话信息保存到本地,最后用户凭借会话信息能够访问类似用户信息等需登陆的网页。

HttpClient4.5通过CookieStore保存用户的会话信息,还提供HttpClientContext保存用户连接的信息。下面是一个使用HttpClient模拟知乎登陆的简单案例。

package com.httpclient.demo;

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, context);
// 获取常用Cookie,包括_xsrf信息
System.out.println("访问知乎首页后的获取的常规Cookie:===============");
for (Cookie c : cookieStore.getCookies()) {
System.out.println(c.getName() + ": " + c.getValue());
}
res.close(); // 构造post数据
List<NameValuePair> valuePairs = new LinkedList<NameValuePair>();
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, context); // 打印响应信息,查看是否登陆是否成功
System.out.println("打印响应信息===========");
HttpClientUtils.printResponse(res);
res.close(); 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();
}
}
}

最新文章

  1. 【探索】利用 canvas 实现数据压缩
  2. 在使用vs2012中的MVC4出的错误!类型“System.Data.Entity.DbContext”在未被引用的程序集中定义
  3. Backbone☞View中的events...click事件失效
  4. PHP版本VC6与VC9、Thread Safe与None-Thread Safe等的区别
  5. jdk自带发布webservice服务
  6. [原创]oracle 顺序号生成函数。仿Sequence
  7. This manual page is part of Xcode Tools version 5.0
  8. java 实现排序
  9. IOS Block 反向传值
  10. 如何使用getopt()函数解析参数
  11. leetcode implement strStr python
  12. linux c语言定时器
  13. Fast R-CNN中的边框回归
  14. nodejs操作 mongoose(mongodb)和Sequelize(mysql)查询数据后添加新属性未生效
  15. Redis 缓存应用实战
  16. vue中遇到的一个点击展开或收起并且改变背景颜色的问题。
  17. Vim列模式(块选择)输入
  18. LeetCode 28 Implement strStr() (实现找子串函数)
  19. MVC日期和其它字符串格式化
  20. 虚拟化–操作系统级 LXC Linux Containers内核轻量级虚拟化技术

热门文章

  1. DDOS hulk,rudy
  2. Python面试数据库
  3. 删除未加入svn版本控制的文件(包括文件夹)
  4. Mybatis插入数据后返回主键id
  5. LRU算法 缓存淘汰策略
  6. Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
  7. [py]django前台处理后端返回的各类数据
  8. openstack 部署笔记--dashboard
  9. ID和Name
  10. 修改class文件