c httpclient抓取网页(mons.httpclient与org.apache.http.client的区别 )
优采云 发布时间: 2021-10-23 15:10c httpclient抓取网页(mons.httpclient与org.apache.http.client的区别
)
与传统JDK自带的URLConnection相比,HttpClient增加了易用性和灵活性。不仅方便了客户端发送Http请求,也方便了开发者测试接口(基于Http协议),提高了开发效率,也方便了提高代码的健壮性。因此,掌握HttpClient是非常重要的必修内容。掌握了HttpClient之后,相信你会对Http协议有更深入的了解。
mons.httpclient.HttpClient 和 org.apache.http.client.HttpClient 的区别
Commons HttpClient 项目现已结束,不再开发。它已被 ApacheHttpComponents 项目的 HttpClient 和 HttpCore 模块取代,提供更好的性能和更大的灵活性。
一、简介
HttpClient 是 Apache Jakarta Common 下的一个子项目,用于提供支持 HTTP 协议的高效、最新、功能丰富的客户端编程工具包,它支持 HTTP 协议的最新版本和推荐。HttpClient 已经在很多项目中使用。例如,Apache Jakarta 上的另外两个著名的开源项目 Cactus 和 HTMLUnit,都使用 HttpClient。
所以这里简单介绍一下如何获取网页的源代码:
Maven 依赖:
org.apache.httpcomponents
httpclient
4.5.2
这里最大的问题是编码问题。如果编码不合适,就会出现中文乱码。
获取代码的方式一般有两种,一种是从响应头中获取,另一种是从网页源代码的meta中获取。
这两种方法应该结合使用。一般的过程是先从响应头中获取。如果响应头不可用,请从 Web 源代码元中获取。如果没有,请设置默认编码。
我的代码如下:
<p>package httpclient.download;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* httpclient来下载网页源码。
*
* @author 徐金仁
*
*关于网页下载最大的问题是编码的问题
*
*/
public class Download {
public String getHtmlSource(String url){
String htmlSource = null;
String finallyCharset = null;
//使用httpclient下载
//创建一个httpclient的引擎
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建一个httpGet对象,用于发送get请求,如果要发post请求,就创建一个post对象
HttpGet get = new HttpGet(url);
try {
//发送get请求,获取一个响应
CloseableHttpResponse response= httpClient.execute(get);
//获取这次响应的实体,接下来所有的操作都是基于此实体完成,
HttpEntity entity = response.getEntity();
//方法还是两个,先从header里面来查看,如果没有,再从meta里面查看
//这个方法主要是从header里面来获取,如果没有,会返回一个null
finallyCharset = EntityUtils.getContentCharSet(entity);
System.out.println("编码如下:");
System.out.println("charset1 = " + finallyCharset);
byte[] byteArray = null;
if(finallyCharset == null){
//如果header里面没有,则要从meta里面来获取,为了节约网络资源,网页只读取一次,
/*
* 那么,就有几个关系 :url->字符流->子节流->字符串
* 这里可以用子节数组来作为中间的过渡,从字节数组这里获取到编码,再通过正确的编码变为字符串
*/
byteArray = convertInputStreamToByteArray(entity.getContent());
if(byteArray == null){
throw new Exception("字节数组为空");
}
//接下来要从字节数组中获取到meta里面的chatset
finallyCharset = getCharsetFromMeta(byteArray);
System.out.println("charset2 = " + finallyCharset);
if(finallyCharset == null){
//如果没有找到
finallyCharset = "UTF-8"; //则等于默认的
System.out.println("charset3 = " + finallyCharset);
}
//如果找到了就更好
}
System.out.println("charset = " + finallyCharset);
htmlSource = new String(byteArray, finallyCharset);
}catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return htmlSource;
}
/**
* 将一个输入流转化为一个字节数组
* @param content
* @param defaultCharset
* @return
* @throws IOException
*/
public byte[] convertInputStreamToByteArray(InputStream content) throws IOException {
//输入流转化为一个字节数组
byte[] by = new byte[4096];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int l = -1;
while((l = content.read(by)) > 0){
bos.write(by, 0, l);
}
byte[] s = bos.toByteArray();
return s;
}
/**
* 从字节数组中获取到meta里面的charset的值
* @param byteArray
* @return
* @throws IOException
*/
public String getCharsetFromMeta(byte[] byteArray) throws IOException {
//将字节数组转化为bufferedReader,从中一行行的读取来,再判断
String htmlSource = new String(byteArray);
StringReader in = new StringReader(htmlSource);
BufferedReader reader = new BufferedReader(in);
String line = null;
while((line = reader.readLine()) != null){
line = line.toLowerCase();
if(line.contains("