httpclient使用

/**
  * 项目名:Crawler
  * 文件名:NewsInfoLoad.java
  * 作者:zhouyh
  * 时间:2014-9-4 上午08:47:06
  * 描述:TODO(用一句话描述该文件做什么) 
  */
package com.newsTest.infoload;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
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.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.newsTest.constant.NewsConstant;

/**
 * 类名: NewsInfoLoad
 * 包名: com.newsTest.infoload
 * 作者: zhouyh
 * 时间: 2014-9-4 上午08:47:06
 * 描述: 新闻下载类
 */
public class NewsInfoLoad {
	//创建httpclient实例
	private CloseableHttpClient httpClient = null;
	/**
	 * 
	 * 私有的构造函数
	 * 作者:zhouyh
	 */
	private NewsInfoLoad(){
		initHttpClient();
	}
	
	/**
	 * 
	 * 方法名:initHttpClient
	 * 作者:zhouyh
	 * 创建时间:2014-9-4 上午08:53:19
	 * 描述:创建httpClient连接池,并初始化httpclient
	 */
	private void initHttpClient(){
		//创建httpclient连接池
		PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
		httpClientConnectionManager.setMaxTotal(NewsConstant.MAX_TOTAL);	//设置连接池线程最大数量
		httpClientConnectionManager.setDefaultMaxPerRoute(NewsConstant.MAX_ROUTE_TOTAL);	//设置单个路由最大的连接线程数量
		//创建http request的配置信息
		RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(NewsConstant.REQUEST_TIMEOUT)
										.setSocketTimeout(NewsConstant.REQUEST_SOCKET_TIME).build();
		//设置重定向策略
		LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
		//初始化httpclient客户端
		httpClient = HttpClients.custom().setConnectionManager(httpClientConnectionManager)
						.setDefaultRequestConfig(requestConfig).setUserAgent(NewsConstant.USER_AGENT).setRedirectStrategy(redirectStrategy).build();
	}
	
	/********单例模式声明开始********************/
	//类初始化时,自行实例化,饿汉式单例模式
	private static final NewsInfoLoad newsInfoLoad = new NewsInfoLoad();
	/**
	 * 
	 * 方法名:getNewsInfoLoadInstance
	 * 作者:zhouyh
	 * 创建时间:2014-9-4 上午08:52:19
	 * 描述:单例的静态方法
	 * @return
	 */
	public static NewsInfoLoad getNewsInfoLoadInstance(){
		return newsInfoLoad;
	}
	
	/************************单例模式声明结束********/
	
	/**
	 * 
	 * 方法名:loadSrc
	 * 作者:zhouyh
	 * 创建时间:2014-9-4 上午09:04:40
	 * 描述:根据给定的url下载信息
	 * @param url
	 * @return
	 */
	public String loadSrc(String url){
		String src = "";
		if(null==url || "".equals(url)) {
			return src;	//如果url为空或者null,则返回src空值
		}
		//创建httpclient请求方式
		HttpGet httpGet = new HttpGet(url);
		CloseableHttpResponse response = null;
		
		try {
			//执行请求
			response = httpClient.execute(httpGet);
			//获得响应的消息实体
			HttpEntity entity = response.getEntity();
			//获取响应状态码
			int statusCode = response.getStatusLine().getStatusCode();
			//根据响应状态码进行处理
			switch (statusCode) {
			case NewsConstant.RESPONSE_200:
				//请求返回成功
				/**
				 * inputstream转换成byte数组,然后将这个byte数组转成字符串(随便哪种编码方式)
				 * 然后解析字符串中的编码方式。再利用这种编码方式将之前的byte数组转成正确的网页字符串
				 */
				InputStream inputStream = entity.getContent();
	            byte[] contentBytes = IOUtils.toByteArray(inputStream);
	            src = new String(contentBytes, "gb2312");
	            //获得响应字符集编码
	            ContentType contentType = ContentType.getOrDefault(entity);
	            String charSet = null;
	            try {
	            	Charset charset = contentType.getCharset();
	            	if(charset != null){
	            		 charSet = charset.toString();
	            	}
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}	          
	            //如果没有获取到字符编码则从meta标签中获取
	            if(charSet==null || charSet.equals("")){
	            	//判断页面的编码方式
		            Document document = Jsoup.parse(src);
		            
		            Elements elements = document.select("meta");  
		            for(Element metaElement : elements){  
		                if(metaElement!=null && StringUtils.isNotBlank(metaElement.attr("http-equiv")) && metaElement.attr("http-equiv").toLowerCase().equals("content-type")){  
		                    String content = metaElement.attr("content");  
		                    charSet = getCharSet(content); 		                    
		                    break;  
		                }  
		            }  
	            }
	            //用获取的编码对contentBytes进行重新编码
	            if(!charSet.equalsIgnoreCase("gb2312")){
	            	src = new String(contentBytes, charSet);
	            }	            
	            //去除特殊标签
                src = replaceStr(src);
	            				
				break;

			default:
				break;
			}
			
			//关闭httpEntity流
			EntityUtils.consume(entity);
			
		} catch (ClientProtocolException e) {
			// TODO 这里写异常处理的代码
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 这里写异常处理的代码
			e.printStackTrace();
		} finally{
			if(null != response){
				try {
					//关闭response
					response.close();
				} catch (IOException e) {
					// TODO 这里写异常处理的代码
					e.printStackTrace();
				}
			}
		}
		
		return src;
	}
	
	
	
	/**
	 * 
	 * 方法名:getCharSet
	 * 作者:zhouyh
	 * 创建时间:2014-9-4 上午09:57:58
	 * 描述:根据正则获取正文编码方式
	 * @param content
	 * @return
	 */
	private String getCharSet(String content){  
        String regex = ".*charset=([^;]*).*";  
        Pattern pattern = Pattern.compile(regex);  
        Matcher matcher = pattern.matcher(content);  
        if(matcher.find())  
            return matcher.group(1);  
        else  
            return null;  
    }
	
	
	/**
	 * 
	 * 方法名:replaceStr
	 * 作者:zhouyh
	 * 创建时间:2014-9-4 上午09:03:53
	 * 描述:去除源码中的特殊字符
	 * @param src
	 * @return
	 */
	public String replaceStr(String src){
		if (src == null || "".equals(src)) return null;
		src = src.replaceAll("<!--", "");
		src = src.replaceAll("-->", "");
		src = src.replaceAll("<", "<");
		src = src.replaceAll(">", ">");
		src = src.replaceAll(""", "\"");
		src = src.replaceAll(" ", " ");
		src = src.replaceAll("&", "&");
		return src;
	}
	
	/**
	 * 方法名:main
	 * 作者:zhouyh
	 * 创建时间:2014-9-4 上午08:47:06
	 * 描述:TODO(这里用一句话描述这个方法的作用)
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String url = "http://blog.sina.com.cn/s/blog_5dade77b0101lpu7.html";
		
		NewsInfoLoad newsLoad = NewsInfoLoad.getNewsInfoLoadInstance();
		
		System.out.println(newsLoad.loadSrc(url));
	}
	
}


转载于:https://my.oschina.net/u/2270476/blog/363938

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值