java工具类之网页数据爬取类

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 网页数据爬取类
 * 
 * @author zql
 *
 */
public class Crawler {

	/**
	 * 获得网页数据的方法(POST请求)
	 * 
	 * @param url 要爬数据的地址。地址和参数分离,要么单独写地址,不能有?、&符号,要么把参数写在地址后面,但params必须传入null
	 * @param params 需要的参数,因为是有单独的参数,参数写在url里时,params请传入空值
	 * @return
	 */
	public String getDataFromPost(String url, Map<String,Object> params) {
		String str = "";
		try {
			// 建立一个URL物件,带入参数为想要建立HTTP连线的目的地,例如网站的网址
			URL u = new URL(url);
			// 建立一个HttpURLConnection物件,并利用URL的openConnection()来建立连线
	        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
	        
	        // 利用setRequestMethod()来设定连线的方式,一般分为POST及GET两种
	        conn.setRequestMethod("POST");
	        // 请求不能使用缓存
	        conn.setUseCaches(false);
	        
	        if (params != null) {
	        	// 设置本次连接是否自动重定向 
		        conn.setInstanceFollowRedirects(true);  
		        // 设置是否向connection输出,因为这个是post请求,参数要放在http正文内,因此需要设为true
		        conn.setDoOutput(true);
		        // Read from the connection. Default is true.
		        conn.setDoInput(true);
		        // 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的 意思是正文是urlencoded编码过的form参数
		        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
		        
		        // 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,要注意的是connection.getOutputStream会隐含的进行connect。
		        conn.connect();
		        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		        // 正文,正文内容其实跟get的URL中 '? '后的参数字符串一致
		        // String content = "字段名=" + URLEncoder.encode("字符串值", "编码");
		        StringBuffer paramsStr = new StringBuffer();
		        boolean one = true;
				for (Map.Entry<String, Object> m : params.entrySet()) {
					if (one) {
						paramsStr.append(m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
						one = false;
					} else {
						paramsStr.append("&" + m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
					}
				}
		        // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写到流里面
		        out.writeBytes(paramsStr.toString());
		        // 流用完记得关
		        out.flush();
		        out.close();
	        }
	        // 将连线取得的回应载入到一个InputStream中,然后就可以将InputStream的内容取出应用,以这个例子而言我们取得的会是网页的原始码
	        InputStream input = conn.getInputStream();
	        
	        byte[] data = readInputStream(input);
	        
	        input.read(data);
	        str = new String(data);
	        // disconnect关闭必须放在最后关闭,否则会报java.io.IOException: stream is closed
	        // 用disconnect()将连线关闭
	        conn.disconnect();
	        input.close(); 
		} catch (Exception e) {
			return "The request failed:"+e.getMessage();
		}
		return str;
	}
	
	/**
	 * 获得网页数据的方法(POST请求)
	 * 
	 * @param url 要爬数据的地址。地址和参数分离,要么单独写地址,不能有?、&符号,要么把参数写在地址后面,但params必须传入null
	 * @param params 需要的参数,因为是有单独的参数,参数写在url里时,params请传入空值
	 * @param cookie 登录的cookie,有些是必须要登录才能查询的,需要先到网页上登录得到cookie复制过来
	 * @return
	 */
	public String getDataFromPost(String url,Map<String,Object> params,String cookie) {
		String str = "";
		try {
			// 建立一个URL物件,带入参数为想要建立HTTP连线的目的地,例如网站的网址
			URL u = new URL(url);
			// 建立一个HttpURLConnection物件,并利用URL的openConnection()来建立连线
	        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
	        // 利用setRequestMethod()来设定连线的方式,一般分为POST及GET两种
	        conn.setRequestMethod("POST");
	        // 请求不能使用缓存
	        conn.setUseCaches(false);
	        
	        if (params != null) {
	        	// 设置本次连接是否自动重定向 
		        conn.setInstanceFollowRedirects(true);  
		        // 设置是否向connection输出,因为这个是post请求,参数要放在http正文内,因此需要设为true
		        conn.setDoOutput(true);
		        // Read from the connection. Default is true.
		        conn.setDoInput(true);
		        // 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的 意思是正文是urlencoded编码过的form参数
		        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
		        // 配置本次连接的Cookie
		        conn.setRequestProperty("Cookie", cookie);
		        
		        // 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,要注意的是connection.getOutputStream会隐含的进行connect。
		        conn.connect();
		        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		        // 正文,正文内容其实跟get的URL中 '? '后的参数字符串一致
		        // String content = "字段名=" + URLEncoder.encode("字符串值", "编码");
		        StringBuffer paramsStr = new StringBuffer();
		        boolean one = true;
				for (Map.Entry<String, Object> m : params.entrySet()) {
					if (one) {
						paramsStr.append(m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
						one = false;
					} else {
						paramsStr.append("&" + m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
					}
				}
		        // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写到流里面
		        out.writeBytes(paramsStr.toString());
		        // 流用完记得关
		        out.flush();
		        out.close();
	        }
	        // 将连线取得的回应载入到一个InputStream中,然后就可以将InputStream的内容取出应用,以这个例子而言我们取得的会是网页的原始码
	        InputStream input = conn.getInputStream();
	        
	        byte[] data = readInputStream(input);
	        
	        input.read(data);
	        str = new String(data);
	        // disconnect关闭必须放在最后关闭,否则会报java.io.IOException: stream is closed
	        // 用disconnect()将连线关闭
	        conn.disconnect();
	        input.close(); 
		} catch (Exception e) {
			return "The request failed:"+e.getMessage();
		}
		return str;
	}
	
	/**
	 * 获得网页数据的方法(GET请求)
	 * 
	 * @param url 要爬数据的地址。地址和参数分离,要么单独写地址,不能有?、&符号,要么把参数写在地址后面,但params必须传入null
	 * @param params 需要的参数,因为是有单独的参数,参数写在url里时,params请传入空值
	 * @return
	 */
	public String getDataFromGet(String url,Map<String,Object> params) {
		String str = "";
		try {
			StringBuffer paramsStr = new StringBuffer();
	        if (params != null) {
	        	boolean one = true;
				for (Map.Entry<String, Object> m : params.entrySet()) {
					if (one) {
						paramsStr.append("?" + m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
						one = false;
					}else{
						paramsStr.append("&" + m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
					}
				}
	        }
	        // 建立一个URL物件,带入参数为想要建立HTTP连线的目的地,例如网站的网址
			URL u = new URL(url + paramsStr.toString());
			// 建立一个HttpURLConnection物件,并利用URL的openConnection()来建立连线
	        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
	        // 利用setRequestMethod()来设定连线的方式,一般分为POST及GET两种
	        conn.setRequestMethod("GET");
	        // 请求不能使用缓存
	        conn.setUseCaches(false);
	        // 将连线取得的回应载入到一个InputStream中,然后就可以将InputStream的内容取出应用,以这个例子而言我们取得的会是网页的原始码
	        InputStream input = conn.getInputStream();
	        
	        byte[] data = readInputStream(input);
	        
	        input.read(data);
	        str = new String(data);
	        // disconnect关闭必须放在最后关闭,否则会报java.io.IOException: stream is closed
	        // 用disconnect()将连线关闭
	        conn.disconnect();
	        input.close(); 
		} catch (Exception e) {
			return "The request failed:"+e.getMessage();
		}
		return str;
	}
	
	/**
	 * 获得网页数据的方法(GET请求)
	 * 
	 * @param url 要爬数据的地址。地址和参数分离,要么单独写地址,不能有?、&符号,要么把参数写在地址后面,但params必须传入null
	 * @param params 需要的参数,因为是有单独的参数,参数写在url里时,params请传入空值
	 * @param cookie 登录的cookie,有些是必须要登录才能查询的,需要先到网页上登录得到cookie复制过来
	 * @return
	 */
	public String getDataFromGet(String url,Map<String,Object> params,String cookie) {
		String str = "";
		try {
			StringBuffer paramsStr = new StringBuffer();
	        if (params != null) {
	        	boolean one = true;
				for (Map.Entry<String, Object> m : params.entrySet()) {
					if (one) {
						paramsStr.append("?" + m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
						one = false;
					} else {
						paramsStr.append("&" + m.getKey() + "=" + URLEncoder.encode(m.getValue() + "", "utf-8"));
					}
				}
	        }
	        // 建立一个URL物件,带入参数为想要建立HTTP连线的目的地,例如网站的网址
			URL u = new URL(url+paramsStr.toString());
			// 建立一个HttpURLConnection物件,并利用URL的openConnection()来建立连线
	        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
	        // 利用setRequestMethod()来设定连线的方式,一般分为POST及GET两种
	        conn.setRequestMethod("GET");
	        // 请求不能使用缓存
	        conn.setUseCaches(false);
	        // 配置本次连接的Cookie
	        conn.setRequestProperty("Cookie",cookie);
	        // 将连线取得的回应载入到一个InputStream中,然后就可以将InputStream的内容取出应用,以这个例子而言我们取得的会是网页的原始码
	        InputStream input = conn.getInputStream();
	        
	        byte[] data = readInputStream(input);
	        
	        input.read(data);
	        str = new String(data);
	        // disconnect关闭必须放在最后关闭,否则会报java.io.IOException: stream is closed
	        // 用disconnect()将连线关闭
	        conn.disconnect();
	        input.close(); 
		} catch (Exception e) {
			return "The request failed:"+e.getMessage();
		}
		return str;
	}
	
	/**
	 * 完全读取流的方法
	 * 
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }
}
发布了55 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/mr_zql/article/details/100059431