HttpClient的爬取网页源代码

巴扎黑
巴扎黑 原创
2016-12-20 12:00:30 1338浏览

包UTIL;

进口java.io.BufferedReader中;
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.InputStreamReader中;
进口java.text.DateFormat中;
进口java.text.SimpleDateFormat的;
进口的java.util.ArrayList;
进口java.util.Date;
进口的java.util.HashMap;
进口的java.util.List;
进口的java.util.Map;
进口java.util.Set中;
进口java.util.Map.Entry;
进口java.util.zip.GZIPInputStream;

进口org.apache.commons.httpclient.Header;
进口org.apache.commons.httpclient.HttpClient;
进口org.apache.commons.httpclient.HttpException;
进口org.apache.commons.httpclient.HttpMethod;
进口org.apache.commons.httpclient.HttpStatus;
进口org.apache.commons.httpclient.NameValuePair;
进口org.apache.commons.httpclient.SimpleHttpConnectionManager;
进口org.apache.commons.httpclient.methods.GetMethod;
进口org.apache.commons.httpclient.methods.PostMethod;
进口org.apache.commons.httpclient.params.HttpConnectionManagerParams;
进口org.apache.commons.httpclient.params.HttpMethodParams;

/ **
* @author六味
*日期:2009年12月18日
*
* TODO
* HttpClient的辅助类
* /
public类HttpClientHelper
{

/ **
* HttpClient的连接超时,读取数据超时时间设置(单位:毫秒)
* /
公共静态最终诠释HTTPCLIENT_CONNECTION_TIMEOUT = 30000;
公共静态最终诠释HTTPCLIENT_SO_TIMEOUT = 120000;
公共静态最终诠释HTTPMETHOD_SO_TIMEOUT = 5000;

//让的ConnectionManager管理httpclientconnection时是否关闭连接
私有静态布尔alwaysClose = FALSE;
私人静态字符串defaultEncode =“UTF-8”;

私有静态最后的DateFormat DATE_FORMAT =新的SimpleDateFormat(“YYYY-MM-DD HH:MM:SS”);

/ **
*获取HttpClient的连接,并设置相关参数
*
* @return
* /
公共静态HttpClient的getHttpClient()
{
HttpClient的客户端=新的HttpClient(新SimpleHttpConnectionManager(alwaysClose));
HttpConnectionManagerParams managerParams = client.getHttpConnectionManager()getParams()方法。
//设置连接超时时间(单位毫秒)
managerParams.setConnectionTimeout(HTTPCLIENT_CONNECTION_TIMEOUT);
//设置读数据超时时间(单位毫秒)
managerParams.setSoTimeout(HTTPCLIENT_SO_TIMEOUT);
返回客户端;
}

/ **
*获取HttpClient的连接,并设置相关参数
*
* @参数logonSite
* @参数logonPort
* @参数协议
* @return
* /
公共静态HttpClient的getHttpClient(最后弦乐logonSite,最终诠释logonPort,最后弦乐协议)
{
HttpClient的客户端=新的HttpClient(新SimpleHttpConnectionManager(alwaysClose));
client.getHostConfiguration()setHost(logonSite,logonPort,协议)。
HttpConnectionManagerParams managerParams = client.getHttpConnectionManager()getParams()方法。
//设置连接超时时间(单位毫秒)
managerParams.setConnectionTimeout(HTTPCLIENT_CONNECTION_TIMEOUT);
//设置读数据超时时间(单位毫秒)
managerParams.setSoTimeout(HTTPCLIENT_SO_TIMEOUT);
返回客户端;
}

私有静态列表<标题> getHeaders(地图<String,字符串>头)
{
名单<标题> =报头的ArrayList新<标题>();
布尔includeUserAgent = FALSE;
如果(空=头&&假== header.isEmpty()!)
{
集<进入<字符串,字符串>> =的entrySet header.entrySet();
对于(进入<String,字符串>项:的entrySet)
{
如果(假== includeUserAgent
&&“用户代理”.equals(entry.getKey()))
{
includeUserAgent = TRUE;
}
headers.add(新报头(entry.getKey(),entry.getValue()));
}
}

如果(假== includeUserAgent)
{
headers.add(新标题(
“用户代理”,
“Mozilla的/ 4.0(兼容; MSIE 7.0; Windows NT的5.1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0 0.50727; Alexa工具条; MAXTHON 2.0)“));
}
返回头;
}

私有静态的NameValuePair [] getPairs(地图<String,字符串> POSTDATA)
{
如果(空== || POSTDATA postData.isEmpty())
{
返回NULL;
}

设置<输入<字符串,字符串>> =的entrySet postData.entrySet();
INT DATALENGTH = entrySet.size();
的NameValuePair [] =对新的NameValuePair [DATALENGTH]
INT I = 0;
对于(进入<String,字符串>项:的entrySet)
{
双[我++] =新的NameValuePair(entry.getKey(),entry.getValue());
}
返回对;
}

/ **
*请求网页内容信息
*
* @参数的HttpClient
* @参数reqUrl
*参数标题
* @参数POSTDATA
*参数编码
* @return
* /
公共静态字符串doRequest(HttpClient的HttpClient的,字符串reqUrl,
地图<字符串, String>的头,地图<String,字符串> POSTDATA,字符串编码)
{
字符串htmlContent = NULL;
如果(空== HttpClient的)
{
返回htmlContent;
}

//请求编码设置
编码=(空==编码defaultEncode:编码);

//头部请求信息
列表<标题> =头getHeaders(头);

的System.out.println(“[”+ DATE_FORMAT.format(新的Date())+“] - doRequest - ”+ reqUrl);

//交方式
,如果(空= POSTDATA!)
{
的PostMethod的PostMethod =新EncodePostMethod(reqUrl,编码);
对于(头tempHeader:头)
{
postMethod.setRequestHeader(tempHeader);
}

//后参数设置
的NameValuePair [] = PARAMS getPairs(POSTDATA);
如果(空=参数!)
{
postMethod.setRequestBody(PARAMS);
}

//提取网页内容
htmlContent = executeMethod(HttpClient的,后方法,编码,getWebSite(reqUrl));
}
其他
{
GetMethod getMethod =新的实现getMethod(reqUrl);
对于(头tempHeader:头)
{
getMethod.setRequestHeader(tempHeader);
}

//提取网页内容
htmlContent = executeMethod(HttpClient的,getMethod,编码,NULL);
}
返回htmlContent;
}

私有静态字符串getWebSite(字符串reqUrl)
{
字符串网站= NULL;
如果(空== reqUrl || reqUrl.isEmpty())
{
返回网站;
}

字符串前缀=“HTTP://”;
如果(reqUrl.startsWith(前缀))
{
INT指数= reqUrl.substring(prefix.length())的indexOf(“/”)+ prefix.length();
网站= reqUrl.substring(0,索引);
}
返回网站;
}

/ **
*通过列举HTTPMethod获取网页内容
*
* @参数的HttpClient
* @参数requestMethod
*参数编码
*参数的网站
* @return
* /
私有静态字符串executeMethod(HttpClient的HttpClient的,列举HTTPMethod requestMethod,编码字符串,字符串网站)
{
字符串responseContent = NULL;
如果(空== HttpClient的)
{
返回responseContent;
}

//判断是否请求加密数据
的布尔dataEncrypt = FALSE;
头acceptEncoding = requestMethod.getRequestHeader(“接受编码”);
如果(!空= acceptEncoding
。&& acceptEncoding.getValue()包含(“gzip的”))
{
dataEncrypt = TRUE;
}

的InputStream responseStream = NULL;
尝试
{
INT状态= httpClient.executeMethod(requestMethod);
如果(HttpStatus.SC_OK ==状态)
{
responseStream = requestMethod.getResponseBodyAsStream();
responseContent = getContentByStream(dataEncrypt新GZIPInputStream(responseStream):responseStream,编码);
responseStream.close();
}
//返回代码为301302303307时,表示页面己经重定向,则重新请求位置的URL,这在一些登录授权取饼干时很重要
否则,如果(HttpStatus.SC_MOVED_PERMANENTLY ==状态
|| HttpStatus.SC_MOVED_TEMPORARILY ==状态
|| HttpStatus.SC_SEE_OTHER ==状态
|| HttpStatus.SC_TEMPORARY_REDIRECT ==状态)
{
//读取新的URL地址
头球冲顶= requestMethod.getResponseHeader(“位置”);
如果(!头= NULL)
{
字符串的redirectUrl = header.getValue();
如果(零=的redirectUrl!
&&假== redirectUrl.isEmpty())
{
responseContent =无效;
如果(空==的redirectUrl || redirectUrl.isEmpty())
{
的redirectUrl =“/”;
}

如果(假== redirectUrl.startsWith(“HTTP://”)
!&&空=网站)
{
如果(website.startsWith(“/”))
{
的redirectUrl =网站+的redirectUrl;
}
其他
{
的redirectUrl =网站+“/”+的redirectUrl;
}
}

GetMethod重定向=新的实现getMethod(的redirectUrl);
头引荐= requestMethod.getRequestHeader(“引荐”);
如果(空=引用者!)
{
redirect.addRequestHeader(引荐);
}
头的cookie = requestMethod.getRequestHeader(“曲奇”);
如果(空=饼干!)
{
redirect.addRequestHeader(饼干);
}
状态= httpClient.executeMethod(重定向);
如果(HttpStatus.SC_OK ==状态)
{
responseStream = redirect.getResponseBodyAsStream();
responseContent = getContentByStream(responseStream,编码);
responseStream.close();
}
}

} //端头

} //结束状态

}赶上(例外五)
{
e.printStackTrace();
}最后
{
如果(requestMethod!= NULL)
{
requestMethod.releaseConnection();
}
}
返回responseContent;
}

/ **
*按照指定编码从流中读取信息
*
* @参数inStream中
*参数编码
* @返回
*引发IOException
* /
公共静态字符串getContentByStream(的InputStream inStream中,字符串编码)抛出IOException异常
{
如果(空= =插播广告)
{
返回NULL;
}

StringBuilder的内容=新的StringBuilder();
//采用指定编码格式读取流内容
的BufferedReader读者=新的BufferedReader(新的InputStreamReader(插播广告,编码));
字符串消息= NULL;
而(空=(消息= reader.readLine())!)
{
content.append(消息);
content.append(“\ r \ n”);
}
//关闭读取器,释放资源
reader.close();
返回(content.toString());
}

/ **
*内部类,继承于的PostMethod,用来指定邮政请求编码格式
* /
公共静态类EncodePostMethod扩展的PostMethod
{
私人字符串编码= NULL;

公共EncodePostMethod(URL字符串,字符串编码)
{
超(URL);
this.encode =编码;
}

@覆盖
公共字符串getRequestCharSet()
{
// TODO自动生成方法存根
回报(this.encode);
}

}

/ **
*测试
*
* @参数ARGS
* /
公共静态无效的主要(字串[] args)
{
//System.setProperty("http.proxyHost“,”165.228.128.10“);
//System.setProperty("http.proxyPort“,”3128“);
//System.setProperty("http.proxySet“,”真“);


字符串reqUrl =“ http://news.39.net/jbyw/index.html ”;
reqUrl =“ http://news.39.net/a/2010722/1404231.html ”;
地图<String,字符串>标题=新的HashMap <String,字符串>();
headers.put(“接受编码”,“gzip的,放气”);

HttpClient的HttpClient的= getHttpClient();
字符串htmlContent = doRequest(HttpClient的,reqUrl,头,空,“GBK”);
的System.out.println(htmlContent);

}
}


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。