`
isiqi
  • 浏览: 16126562 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

自己动手写CSDN博客提取器源码分析之四:抓取网页源码

 
阅读更多

前几天公布了保存文件的一些源码,今天我发一下怎么抓取网页源码。学过java和C的都知道,java抓取源码要比C语言简单的多,很多东西java都封装好了,只需要调用URL这个类的一些接口就可以获得我们需要的一些资源,而不像C一样,自己构造包,自己再发送,自己要非常懂HTML的一些发送和接收消息包的格式,相当的麻烦。。。下面就是我工程里面的获取源码的类(精简了)。

/**
 * 
 */
package com.wyp.HTML;

/**
 * @author w397090770
 * Create Data: 2012-7-17
 * Email: wyphao.2007@163.com
 * 
 * 版权所有,翻版不究,但是在修改本程序的时候务必加上这些注释。谢谢 
 * 仅用于学习交流之用
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

//import org.apache.log4j.Logger;
//import org.apache.log4j.PropertyConfigurator;

import com.wyp.utils.BlogReturnStatus;
import com.wyp.utils.Pair;

/**
 **网页抓取 通用类
 * 
 * @author
 */

public class SpiderHTML {
	// 定义一个logger
	//static Logger logger = Logger.getLogger(SpiderHTML.class.getName());
	//用户,用来生成保存爬取到文件的文件夹
	public static String userName = null;
	//保存路径
	public static String pathText = null;
	public SpiderHTML() {
		// 加载log4j.properties配置文件
		//PropertyConfigurator.configure("log4j.properties");
	}
	
	/**
	 * 抓取页面返回的几个状态
	 * */
	/**
	 *网页抓取方法
	 * 
	 * @param urlString
	 *            要抓取的url地址
	 * @param charset
	 *            网页编码方式
	 * @param timeout
	 *            超时时间
	 * @param type
	 * 			  获取网页的格式 0 网页 1 图片
	 * @param userName
	 *            博客用户的名称
	 * @return 抓取的网页内容和读取网页的返回状态
	 * @throws IOException
	 *             抓取异常
	 */
	public static Pair<String, BlogReturnStatus> GetWebContent(String urlString, final String charset,
			int timeout, int type) throws IOException {
		if (urlString == null || urlString.length() == 0) {
			return null;
		}

		//System.out.println("***********************" + urlString);
		//String imgAbsolutePath = null;
		BlogReturnStatus blogReturnStatus = null;
		urlString = (urlString.startsWith("http://") || urlString
				.startsWith("https://")) ? urlString : ("http://" + urlString)
				.intern();
		URL url = new URL(urlString);

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		
		// 只接受text/html类型,当然也可以接受图片,pdf,*/*任意,就是tomcat/conf/web里面定义那些
		conn.setRequestProperty("Accept", "text/html");
		// 设置超时为timeout毫秒
		conn.setConnectTimeout(timeout);
		try {
			// 如果失败
			if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
				//logger.warn("Connection failed! URL: [" + urlString + "]");
				blogReturnStatus = BlogReturnStatus.TIME_OUT;
				return new Pair<String, BlogReturnStatus>(null, blogReturnStatus);
			}
		} catch (IOException e) {
			// e.printStackTrace();
			//logger.error(e.toString() + " URL: [" + urlString + "]");
			blogReturnStatus = BlogReturnStatus.FAILURE;
			return new Pair<String, BlogReturnStatus>(null, blogReturnStatus);
		}
		//logger.info("Start reading [" + urlString + "]");
		// 打开输入流
		InputStream input = conn.getInputStream();
		// 设置流读取函数,并设置字符集为charset
		BufferedReader reader = new BufferedReader(new InputStreamReader(input,
				charset));

		String line = null;
		// 用来存储读取到的网页
		StringBuffer sb = new StringBuffer();
		
		switch(type){
		case 0:
			// 直到读去网页源码结束
			while ((line = reader.readLine()) != null) {
				sb.append(line).append(System.getProperty("line.separator"));
			}
			break;
		case 1:
			sb.append(processImg(input, urlString));
			break;
		default:
			System.err.println("Unsupport File Type!");
			//logger.error("Unsupport File Type!");
			return null;
		}
		
		
		
		//logger.info("End reading [" + urlString + "]");
		// 关闭读对象
		if (reader != null) {
			reader.close();
		}
		if (conn != null) {
			conn.disconnect();
		}
		blogReturnStatus = BlogReturnStatus.OK;
		//System.out.println(sb);
		return new Pair<String, BlogReturnStatus>(sb.toString(), blogReturnStatus);

	}
	
	/**
	 * @param str 获取到的网页文件
	 * 
	 *  本函数用来保存图片到对应用户的img文件夹下面
	 */
	private static String  processImg(InputStream is, String urlString){
		String dirs = pathText + File.separator + userName + File.separator + "img" + File.separator;
		File file = new File(dirs);
		//目录不存在,创建它
		if(!file.exists()){
			file.mkdirs();
		}
		
		//得到图片的名称和格式
		String imgNameAndType = urlString.substring(urlString.lastIndexOf("/") + 1);
		
		file = new File(dirs + imgNameAndType);
		//文件不存在,则创建
		if(!file.exists()){
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//logger.error("Create " + imgNameAndType + "Failure!");
				e.printStackTrace();
				return dirs + imgNameAndType;
			}
			
			//logger.info("Starting Save: [" + imgNameAndType + "]");
			OutputStream os = null;
			try {
				os = new FileOutputStream(file);
				int bytes = -1;
				while((bytes = is.read()) != -1){
					os.write(bytes);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					is.close();
					os.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			//logger.info("End Save: [" + imgNameAndType + "]");
		}else{
			//logger.info("The file [ "+ imgNameAndType +"] is exist!");
		}
		
		
		return dirs + imgNameAndType;
	}

	/**
	 * 类测试函数
	 * 
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		Pair<String, BlogReturnStatus>pair  = GetWebContent("http://blog.csdn.net/w397090770", "utf-8", 5000, 0);
		System.out.println(pair.getSecond());
	}
}

这个类也比较简单把,这个类可以来获取网页源码以及图片,注意看获取图片和网页源码的方法不同点。下面两个类是上面要用到的。

package com.wyp.utils;

/**
 * @author w397090770 
 * Create Data 2012-7-7 
 * Email: wyphao.2007@163.com
 * 版权所有,翻版不究,但是在修改本程序的时候务必加上这些注释。谢谢 
 * 仅用于学习交流之用
 */
public class Pair<T1, T2> {

	private T1 first;
	private T2 second;

	/**
	 * 
	 */
	public Pair() {
		// TODO Auto-generated constructor stub
		first = null;
		second = null;
	}

	/**
	 * @param first
	 *            first part
	 * @param second
	 *            second part
	 */
	public Pair(T1 first, T2 second) {
		this.first = first;
		this.second = second;
	}

	public Pair(Pair<T1, T2> pair) {
		this.first = pair.getFirst();
		this.second = pair.getSecond();
	}

	public Pair<T1, T2> make_pair(T1 first, T2 second) {
		Pair<T1, T2> pair = new Pair<T1, T2>(first, second);
		return pair;
	}

	/**
	 * @return the first
	 */
	public T1 getFirst() {
		return first;
	}

	/**
	 * @param first
	 *            the first to set
	 */
	public void setFirst(T1 first) {
		this.first = first;
	}

	/**
	 * @return the second
	 */
	public T2 getSecond() {
		return second;
	}

	/**
	 * @param second
	 *            the second to set
	 */
	public void setSecond(T2 second) {
		this.second = second;
	}

}
package com.wyp.utils;


/**
 * @author w397090770
 * Create Data 2012-7-6
 * Email: wyphao.2007@163.com
 * 
 * 版权所有,翻版不究,但是在修改本程序的时候务必加上这些注释。谢谢 
 * 仅用于学习交流之用
 * 
 * 本类是用来标志获取博客返回地址的状态
 */
public enum BlogReturnStatus {
	//成功获取网页
	OK, 
	//获取网页源码超过设置的时间
	TIME_OUT, 
	//获取网页异常
	FAILURE
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics