java代码抓取网页

从指定的url抓取网页,思路很清晰,使用java.net.URL得到url对应的二进制流,然后就可以像操作普通文件那样操作这个流了。

下面的例子演示了从百度抓取一个搜索网页,将网页存入到文件当中;同时,还对网页进行了简单的分析,得到了检索结果的数量。

不过在分析网页内容的时候不可避免的要处理编码问题,因为从url读取的时候是字符流,网页上字符的编码是多样的,如果直接用java默认的字符集,十有八九会出现乱码。因此要在二进制流全部读取后,为其指定编码。

需要说明的是,从url读取的二进制流中既有控制信息(html标签,cssjs等),又有文本信息(我们在网页上看到的文字),又有二进制信息(图片等),因此如论我们指定何种编码方式,有些信息始终是无法解析成文字的。但是对于简单分析来说,只要将原来的文本信息解析出来就行了

如果想对得到的二进制文件作精确的分析,比如分别取出里面的图片、文字、样式等信息,恐怕需要不少工作,这个简单的小程序就做不到了。

下面是程序代码:

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Arrays;

public class MySpider {
	public static void main(String[] args) throws Exception{
		String rscount = new MySpider().grepAndgetRSCount("http://www.baidu.com/s?wd=北京雾霾");
		System.out.println("搜索结果的个数为:" + rscount);
	}
	
	private String grepAndgetRSCount(String urlstr) throws Exception{
		URL url = new URL(urlstr);
		InputStream inStm = url.openConnection().getInputStream();// 得到url对用的二进制流
		File outFile = new File("C:/grep.html");// 把得到的网页写入到这个文件
		if (!outFile.exists()) {
			outFile.createNewFile();
		}
		OutputStream outStm = new FileOutputStream(outFile);
		byte[] buffer = new byte[4096];
		int bytes_read;
		ByteArrayBuffer byteAbuf = new ByteArrayBuffer();
		while ((bytes_read = inStm.read(buffer)) != -1) {
			outStm.write(buffer, 0, bytes_read);// 把得到的二进制流写入到文件
			byteAbuf.append(buffer, bytes_read);// 缓存一份,供后面分析结果使用
		}
		inStm.close();
		outStm.close();
		String rscount = "-1";
		// 将得到的二进制流解析成文字,注意字符编码
		String rsStr = new String(byteAbuf.getBytes(), 0, byteAbuf.getByteslen(), "utf-8");
		if(rsStr.contains("百度为您找到相关结果约")){
			try{
				rscount = rsStr.split("百度为您找到相关结果约")[1].split("个")[0];
			}catch(Exception e){
				// do nothing
			}
		}
		return rscount;
	}
}
class ByteArrayBuffer{
	/**
	 * 一个byte容器,存储读取的字节流
	 */
	private byte bytes[];
	public byte[] getBytes() {
		return bytes;
	}
	public int getByteslen() {
		return byteslen;
	}
	private int byteslen;
	public ByteArrayBuffer(){
		bytes = new byte[1024];
		byteslen = 0;
	}
	public ByteArrayBuffer append(byte[] bytesAppend, int len){
		int freespace = bytes.length - byteslen;
		if(freespace < len){
			resize(len + byteslen);
		}
		System.arraycopy(bytesAppend, 0, bytes, byteslen, len);
		byteslen += len;
		return this;
	}
	private void resize(int newsize){
		int newsize1 = 1;
		while(newsize1 < newsize)
			newsize1 <<= 1;
		bytes = Arrays.copyOf(bytes, newsize1);
	}
}


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值