java http 源码_httpclient下载网页源码---java基础爬虫

有关httpclient:

HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入。

org.apache.commons.httpclient.HttpClient与org.apache.http.client.HttpClient的区别

Commons的HttpClient项目现在是生命的尽头,不再被开发,  已被Apache HttpComponents项目HttpClient和HttpCore  模组取代,提供更好的性能和更大的灵活性。

一、简介

HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。

那么这里就简单写写如何获取网页源码:

maven依赖:

org.apache.httpcomponents

httpclient

4.5.2

这里最大的问题就是编码的问题,如果编码不是合适的话,就会出现中文乱码情况。

一般是通过两种方式来获取编码,一种是从响应头获取,一种是从网页源码的meta中获取。

7493b0bd0c20fe5aa69c2f16a3f96653.png

29350812b6a9f91a4cd8282508f695da.png

这两种方法要结合使用。一般步骤是先从响应头获取,如果响应头没有,就要到网页源码meta中获取,如果还没有,就要设置默认编码。

我的代码如下:

packagehttpclient.download;importjava.io.BufferedReader;importjava.io.ByteArrayOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.StringReader;importjava.util.regex.Matcher;importjava.util.regex.Pattern;importorg.apache.http.HttpEntity;importorg.apache.http.client.methods.CloseableHttpResponse;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.util.EntityUtils;/*** httpclient来下载网页源码。

*

*@author徐金仁

*

*关于网页下载最大的问题是编码的问题

**/

public classDownload {publicString getHtmlSource(String url){

String htmlSource= null;

String finallyCharset= null;//使用httpclient下载//创建一个httpclient的引擎

CloseableHttpClient httpClient =HttpClients.createDefault();//创建一个httpGet对象,用于发送get请求,如果要发post请求,就创建一个post对象

HttpGet get = newHttpGet(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= newString(byteArray, finallyCharset);

}catch(IOException e) {

e.printStackTrace();

}catch(Exception e) {

e.printStackTrace();

}returnhtmlSource;

}/*** 将一个输入流转化为一个字节数组

*@paramcontent

*@paramdefaultCharset

*@return*@throwsIOException*/

public byte[] convertInputStreamToByteArray(InputStream content) throwsIOException {//输入流转化为一个字节数组

byte[] by = new byte[4096];

ByteArrayOutputStream bos= newByteArrayOutputStream();int l = -1;while((l = content.read(by)) > 0){

bos.write(by,0, l);

}byte[] s =bos.toByteArray();returns;

}/*** 从字节数组中获取到meta里面的charset的值

*@parambyteArray

*@return*@throwsIOException*/

public String getCharsetFromMeta(byte[] byteArray) throwsIOException {//将字节数组转化为bufferedReader,从中一行行的读取来,再判断

String htmlSource = newString(byteArray);

StringReader in= newStringReader(htmlSource);

BufferedReader reader= newBufferedReader(in);

String line= null;while((line = reader.readLine()) != null){

line=line.toLowerCase();if(line.contains("

String regex = "\"text/html;[\\s]*?charset=([\\S]*?)\"";

Pattern pattern=Pattern.compile(regex);if(pattern != null){

Matcher matcher=pattern.matcher(htmlSource);if(matcher != null){if(matcher.find()){return matcher.group(1);

}

}

}

}else{continue;

}

}return null;

}//测试:

public static voidmain(String[] args) {

String htmlsource= new Download().getHtmlSource("http://news.youth.cn/gn/");

System.out.println("源码:");

System.out.println(htmlsource);

}

}

结果:

7822252783ccc1c79add092333a671fc.png

收藏的相关博客:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值