最近在做java的爬虫,由于刚开始的时候使用的是httpclient,但是逐渐发现,有的功能不能实现,因此,自己利用java的net包做了一个爬虫,实现网页的基本抓取,其中考虑了浏览器的伪装,gzip格式的解码等困扰比较久的问题。代码如下
/**
* @author houlaizhexq
* @function:依靠java自己的net包实现的爬虫,解决浏览器伪装,gzip解码等问题
* @time:2013年12月6日 星期五
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPInputStream;
public class Test5 {
public static void main(String args[]){
URL url;
try {
url = new URL("http://www.baidu.com");
HttpURLConnection httpClientConnection=(HttpURLConnection) url.openConnection();
// 模仿IE的浏览器信息,防止网站禁止抓取网页
// Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*
// Accept-Language: zh-cn
// Accept-Encoding: gzip, deflate
// User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
// Host: 192.168.109.130
// Connection: close
httpClientConnection.addRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*");
httpClientConnection.addRequestProperty("Accept-Language", "zh-cn");
httpClientConnection.addRequestProperty("Accept-Encoding", "gzip, deflate");
httpClientConnection.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
httpClientConnection.addRequestProperty("Connection", "close");
//设置为get方法,默认即为get方法
httpClientConnection.setRequestMethod("GET");
// //如果是表单的提交之类的需要设置为POST方法,如下
// //因为需要写数据,所以设置为true
// httpClientConnection.setDoOutput(true);
// httpClientConnection.setRequestMethod("POST");
// //设置表单内的数据
// String username="user=admin";
// httpClientConnection.getOutputStream().write(username.getBytes());
// //写入服务器
// httpClientConnection.getOutputStream().flush();
// //关闭写出流
// httpClientConnection.getOutputStream().close();
httpClientConnection.connect();
//提取返回头信息
System.out.println(httpClientConnection.getResponseCode());
for(int j=1;;j++){
String header=httpClientConnection.getHeaderField(j);
if(header==null){
break;
}
System.out.println(httpClientConnection.getHeaderFieldKey(j)+":"+header);
}
//获取返回体正文信息
BufferedReader bufferedReader=null;
InputStream inputStream=null;
//查看encoding是不是gzip,是的话,先解压成inputstream正常文件流,否则,不需要转换
if(httpClientConnection.getContentEncoding()!=null){
String encode=httpClientConnection.getContentEncoding().toLowerCase();
if(encode.indexOf("gzip") >= 0){
//转化gzip
inputStream = new GZIPInputStream(httpClientConnection.getInputStream());
}else{
inputStream = httpClientConnection.getInputStream();
}
}
if(inputStream!=null){
bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
//关闭流
inputStream.close();
bufferedReader.close();
//断开连接
httpClientConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:其中的gzip主要是用来解决压缩的问题,以减少流量,其中返回的是否gzip主要根据你发送的请求Accept-Encoding字段判断,由于浏览器都会自动解码,所以一般返回gzip格式,但是自己的爬虫,如果不声明能接受gzip编码,则会返回正常的编码,这样在抓取的返回头文件不会出现content-encoding:gzip字段