Java 读取HTML页面源代码工具类


 以前抓淘宝数据和抓取优酷、土豆的源视频地址的时候需要通过IO流获取它们的HTML的源代码,为了方便所以写了这个工具类。

 

package com.hanyastar.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import com.hanyastar.exception.HanyaException;
import com.hanyastar.exception.HanyaToolsException;

/**
 * HTML操作工具类。
 * @author Belen
 * @since 2013/05/25
 */
public abstract class HTMLUtils {

	/**
	 * 通过BufferedInputStream,根据URL获取页面的源代码(源代码转化成小写字母返回).
	 * 
	 * @param url
	 *            url地址
	 * @param encode
	 *            编码 如果encode为空,则以GBK形式转换. 
	 * @return 页面源代码
	 * @author Belen
	 * @throws HanyaException 
	 */
	public static String getHtml2(String url, String encode)
			throws HanyaException {
		if(url == null)
			throw new HanyaToolsException("url",new NullPointerException("url"));
		if(encode == null){
			encode = "GBK";
		}
		StringBuffer html = new StringBuffer();
		String result = null;
		URLConnection conn = null;
		BufferedInputStream in = null;
		try {
			URL u = new URL(url);
			conn = u.openConnection();
			conn.setRequestProperty("User-Agent",
							"Mozilla/4.0 (compatible; MSIE 7.0; NT 5.1; GTB5; .NET CLR 2.0.50727; CIBA)");
			// 设置连接主机超时(单位:毫秒)
			conn.setConnectTimeout(30000);
			// 设置从主机读取数据超时(单位:毫秒) 
			conn.setReadTimeout(30000); 
			in = new BufferedInputStream(conn.getInputStream());
			String inputLine;
			byte[] buf = new byte[4096];
			int bytesRead = 0;
			while (bytesRead >= 0) {
				inputLine = new String(buf, 0, bytesRead, "ISO-8859-1");
				html.append(inputLine);
				bytesRead = in.read(buf);
				inputLine = null;
			}
			buf = null;
			result = new String(html.toString().trim().getBytes("ISO-8859-1"),
					encode).toLowerCase();
		} catch (MalformedURLException e) {
			throw new HanyaException(e);
		} catch (IOException e) {
			throw new HanyaException(e);
		} finally {
			try {
				if (in != null) {
					in.close();
				}
				if (conn != null) {
					conn = null;
				}
			} catch (IOException e) {
				throw new HanyaException(e);
			}
		}
		return result;
	}
	
	/**
	 * 通过ByteArrayOutputStream,根据URL获取页面的源代码(HTML源代码返回).
	 * 
	 * @param url
	 * @param encode 以encode编码类型转换数据,如果encode为空,则以GBK形式转换. 
	 * @return
	 * @throws HanyaException 
	 */
	public static String getHtml(String url,String encode) throws HanyaException{
		if(url == null)
			throw new HanyaToolsException("url",new NullPointerException("url"));
		if(encode == null){
			encode = "GBK";
		}
		InputStream in = null;
		ByteArrayOutputStream bos = null;
		try {
			URL u = new URL(url);
			HttpURLConnection httpConn = (HttpURLConnection) u.openConnection();
			// 设置user agent确保系统与浏览器版本兼容
			HttpURLConnection.setFollowRedirects(true);
		    httpConn.setRequestMethod("GET"); 
		    httpConn.setRequestProperty("User-Agent","Mozilla/4.0 " +
		    		"(compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");
			in = u.openStream();
			// 设置连接主机超时(单位:毫秒)
			httpConn.setConnectTimeout(30000);
			// 设置从主机读取数据超时(单位:毫秒) 
			httpConn.setReadTimeout(30000); 
			int length = 0;
			bos = new ByteArrayOutputStream(); 
	        while((length = in.read()) != -1) { 
	        	 bos.write(length);
	        	 bos.flush();
	        }
	        in.close();
			return new String(bos.toByteArray(),encode);
		} catch (MalformedURLException e) {
			throw new HanyaException(e);
		} catch (IOException e) {
			throw new HanyaException("流处理失败。"+e);
		} finally{
			try {
				if(in != null){
					in.close();
				}
				if(bos != null){
					bos.close();
				}
			} catch (IOException e) {
				throw new HanyaException(e);
			}
		}
	}
}

获取网站的网页源码时,一般网站都有访问次数限制,也就是说如果发现一个IP多次访问他们的网站,一般都会在几分钟内限制你的IP,所以:

1、可以使用动态更换IP的方式来获取,但更换IP后获取源码的速度相对会降低。

2、也可以弄一个定时器或线程睡眠下,如果获取失败定时器将自动启动,定时5分钟后在继续访问,从而提高成功率。


以前帮一个公司弄一些淘宝数据,按他们的要求抓取一些数据从而生成报表,这些数据都是通过多次访问而组装起来的。

所以每一组数据大概需要请求淘宝10次左右,大概有20多万条数据,一共就需要请求超过200多万次。

一般情况下3分钟内同一IP请求淘宝的数据超过3000次就会限制你的IP(估计)。淘宝会在5分钟后解除限制,这时候我采用以上第二种方式就解决了这个问题。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值