Apache Httpclient4.5学习笔记,


很早之前写过一个java爬虫,用来抓某网站妹子图片的,用到了httpclient包,但是没有认真理解方法,只是为了实现功能而拼凑了一个东西出来,当然也还为了好玩。

现在不一样了,已经决定了不考研,而又处于大三这个开始有找工作的压力的情况下,自然要开始学习磨炼自己的技术。再加上学习安卓网络编程正好用到了httpclient包,于是就下载了官方手册仔细的学了一学,现在在这里写下来我对第一部分(Post与get)相关的理解。

首先贴出下载链接:http://hc.apache.org/downloads.cgi

然后是官方官方教程:http://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/index.html

下面开始说说常用的方法。

GET:基本知识就不说了,网上一搜一大堆。这里讲讲怎么用发送get请求,获取网页的request。

1.用Httpclient的静态方法获取一个CloseableHttpClient的 对象(CloseableHttpClient httpclient = HttpClients.createDefault();)

2.获取一个HttpGet对象,并传入想要get的url(HttpGet httpGet = new HttpGet(url);)

3.通过httpClient.execute(httpGet)返回一个CloseableHttpResponse的服务器返回的response

4.将调用response的getEntity()方法,返回一个HttpEntity对象entity

5.调用entity的getContent方法返回一个输入流

6.常规的把输入流处理为String就可以利用正则表达式获取自己想要的信息了。

其中,如果要给get方法带上参数,则需要构建uri,比如提交一个百度搜索界面,带上搜索关键词“地锅鸡”,则需要提交网址http://www.baidu.com/s?wd=地锅鸡    的形式,不知道的同学可以用chrome的抓包功能,然后进行分析(如果有必要以后也写个笔记记录一下抓包的过程)。

构建URI如:URI uri = new URIBuilder().setScheme("http").setHost("www.baidu.com").setPath("/s").setParameter("wd", keyWord).build();

然后将URI放入HttpGet的构建即可。

Post方法,稍微麻烦一点。我因为写安卓做了一个种子搜索器,所以用到了KittyBt网站以及它的搜索功能。即提交搜索关键词,解析返回的网址,用正则表达式获取所需要的信息就可以了。

基本过程如下:

1.创建Httpclient对象

2.创建HttpPost对象,带上网址参数

3.设置提交的header(为了防止网站把程序提交的request过滤掉),使用addHeader()方法

4.设置需要post的内容List<NameValuePair> formparas,调用add()方法,并用BasicNameValuePair构建参数

5. Httpclient的execute执行httppost,如上面的方法获取一个response,再用entity获得输入流进行解析。

public class HttpUtils {

	static CloseableHttpClient httpClient = HttpClients.createDefault();
	static CloseableHttpResponse response1;

	/**
	 * @param 目标url
	 * @return 网页正文string
	 */
	public static String contentByGet(String url) throws Exception {
		String response = "";// 用于存放网页返回的html内容
		InputStream in = null;// 用于获得entity的输入流
		HttpGet httpGet = new HttpGet(url);
		response1 = httpClient.execute(httpGet);
		try {
			HttpEntity entity = response1.getEntity();
			if (entity != null) {
				in = entity.getContent();
				try {
					response = InputStreamToString.inputToStr(in);
				} finally {
					in.close();
				}
			}
		} finally {
			response1.close();
		}
		return response;
	}

	/**
	 * @param 待搜索的关键词
	 * @return 网页正文string
	 */
	public static String getBaiDu(String keyWord) throws Exception {
		String response = "";
		InputStream in = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		URI uri = new URIBuilder().setScheme("http").setHost("www.baidu.com").setPath("/s").setParameter("wd", keyWord)
				.build();// 构建搜索网址:http://www.baidu.com/s?wd=地锅鸡
		HttpGet httpGet = new HttpGet(uri);
		CloseableHttpResponse response1 = httpClient.execute(httpGet);
		try {
			HttpEntity entity = response1.getEntity();
			if (entity != null) {
				in = entity.getContent();
				try {
					response = InputStreamToString.inputToStr(in);
				} finally {
					in.close();
				}
			}
		} finally {
			response1.close();
		}
		return response;
	}

	/**
	 * @param 待搜索的关键词
	 * @return 搜索结果的html链接
	 */
	public static String postKittyBt(String keuword) throws Exception {
		String response = "";
		String targetURL = "";
		InputStream in = null;

		// 构建post提交的参数
		List<NameValuePair> formparas = new ArrayList<NameValuePair>();
		formparas.add(new BasicNameValuePair("keyword", keuword));
		formparas.add(new BasicNameValuePair("hidden", "true"));
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparas, Consts.UTF_8);

		HttpPost post = new HttpPost("http://btkitty.bid/");
		// 设置请求头header
		post.setEntity(entity);
		post.addHeader("Cache-Control", "max-age=0");
		post.addHeader("Content-Type", "application/x-www-form-urlencoded");
		post.addHeader("User-Agent",
				"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
		post.addHeader("Accept-Encoding", "gzip, deflate");
		post.addHeader("Accept-Language", "zh-CN,zh;q=0.8");
		post.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		response1 = httpClient.execute(post);
		try {
			HttpEntity entity2 = response1.getEntity();
			if (entity2 != null) {
				in = entity2.getContent();
				try {
					// 获取目标网址的response的header,获取Location参数的值,即为目标网址
					Header[] headers = response1.getAllHeaders();
					System.out.println("----测试location:" + headers.toString());
					for (int i = 0; i < headers.length; i++) {
						System.out.println(headers[i].getName() + ":" + headers[i].getValue());
						if (headers[i].getName().equalsIgnoreCase("Location")) {
							targetURL = headers[i].getValue();
						}
					}
				} finally {
					in.close();
				}
			}

		} finally {
			response1.close();
		}
		return targetURL;
	}

}

之所以post要解析response的header,是因为KittyBt这个网站在发送搜索关键词的请求后,返回的并不是目标html,而是返回一个空内容的网页,只有在header里附带了Location的属性里有目标网址链接。

下面是输入流转换为string文本的方法

public class InputStreamToString {
	/**
	 * @param in
	 * @return 输入流的内容string
	 */
	public static String inputToStr(InputStream in) {
		BufferedReader str = null;
		StringBuffer buffer = null;
		InputStreamReader reader = null;
		try {
			reader = new InputStreamReader(in, "UTF-8");
			str = new BufferedReader(reader);
			buffer = new StringBuffer();
			String line = "";
			while ((line = str.readLine()) != null) {
				buffer.append(line);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (str != null) {
					str.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return buffer.toString();
	}
}

做个广告,之前那个java爬妹子图片的程序在:https://github.com/ztgreenleaves/ReptileLearning

有没有大佬能介绍个软件开发的实习啊!大三了 好急啊。2017.3.13

相关内容

    暂无相关文章