您的位置:首页 > 理论基础 > 计算机网络

Httpcilent获取带验证码的网站内容

2013-12-10 15:48 363 查看
大家可能都遇到过网站带验证码的,用httpclient去获取会给我们造成许多困扰和麻烦,网站的写法多变,有直接赋值的、有用ajax赋值的各种各样,下面就为大家解释一下怎么获取带验证码的网站。

首先、你要知道他的验证码是怎么生成的,用工具火狐浏览器,或者Http Analyzer 直接抓取他获取验证码的连接。

然后写一个方法,读取他的验证码流吐到你的页面上。

其次、你要保证你i获取验证码和提交时一个请求。

那么怎么才能保证验证码和你的提交请求时一个请求呢,有俩种方法。

一、如果你的服务器不是分布式的,直接上来就new 一个HttpClient 放到session中。然后获取验证码和提交求情都从sesssion中获取httpclient。

二、如果你的服务器是分布式的,那么直接从cookie入手,由于大多服务器都是分布式的,这里只对分布式进行讲解。

首先获取cookie。

/**
* Description:获得cookie值
* Date:Dec 10, 2013
* @author Christopher
* @return
* @return String
*/
private String getCookie(){
HttpClient httpClient = new HttpClient();
httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);//让HttpClient使用浏览器的策略
GetMethod getMethod = new GetMethod("http://www.mdjzfgjj.cn/mdjweb/website/trans/ValidateImg");
String tmpCookies= "";
try {
int status = httpClient.executeMethod(getMethod);
if (status == HttpStatus.SC_OK) {

Cookie[] cookies=httpClient.getState().getCookies();//获取cookie
for(Cookie cookie:cookies){
tmpCookies += cookie.toString()+";";
}
}
} catch (HttpException e) {
log.error(" 执行 HTTP GET 请求时,发生异常!", e);
e.printStackTrace(System.err);
} catch (IOException e) {
log.error("返回的HTTP响应信息流转换发生问题", e);
} finally {
getMethod.releaseConnection();
}
return tmpCookies;
}


获得cookie以后,你可以放到session中,或者放到request里面带到页面,在带回来。

其次就是获得cookie了,本代码是放到session中的。

下面是获取验证码:

/**
* 读取验证码图片
*/
public  String ImageGet(){
Long time=new Date().getTime();
String passTime=time.toString();
InputStream sos=null;
HttpClient httpClient = new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true));
GetMethod getMethod = new GetMethod("http://www.mdjzfgjj.cn/mdjweb/website/trans/ValidateImg?d="+passTime);
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
String cookie=session.get("cookie");
if(! "".equals(cookie)){
getMethod.setRequestHeader("cookie",cookie);
}else{
System.out.println("cookie  is   not  found!!!!");
}
try {
int statusCode = httpClient.executeMethod(getMethod);
System.out.println("statusCode = "+statusCode);
if (statusCode == HttpStatus.SC_OK) {
response.setContentType("multipart/form-data");
sos = getMethod.getResponseBodyAsStream();
byte[] imageByteArray = IOUtil.getByteArray(sos);    //转换完byteArray以后直接关闭了sos
ServletOutputStream servletOutputStream = null;
response.setContentType("multipart/form-data");
try {
servletOutputStream = response.getOutputStream();
servletOutputStream.write(imageByteArray);
} catch (Exception e) {
log.error("AccumulationFundSearch_MDJ:ImageGet",e);
e.printStackTrace();
}finally{
servletOutputStream.flush();
servletOutputStream.close();
}
}
} catch (Exception e) {
if(!"Software caused connection abort: socket write error".equals(e.getCause().getMessage())&&!"Connection reset by peer: socket write error".equals(e.getCause().getMessage())){
log.error("AccumulationFundSearch_MDJ:ImageGet",e);
e.printStackTrace();
}
}finally{
getMethod.releaseConnection();
}
return null;
}


页面直接调用。为了方便给大家上jsp代码。

<tr>
<td  align="right">验证码:</td>
<td>
<input type="text" name="verify" id="verify" style="height:22px;width:80px" class="apps_w140 apps_hdlt" maxlength="4"/>
<a href="#" onclick="imageChange('1')">
<img src="AccumulationFundSearch_MDJ!ImageGet.action" id="image" name="image" onclick="imageChange('1');"/>
</a>
</td>
</tr>


js方法如下:

function imageChange(flag){
var timenow = new Date().getTime();
document.getElementById("image").src="AccumulationFundSearch_MDJ!ImageGet.action?d="+timenow;
}


然后就是提交请求了,请求方法如下:

private Map<String, String>  getSetCookie(String time,String accnum,String certinum,String password,String mark,String verify,String cookie){
Map<String, String> map=new HashMap<String, String>();
HttpClient httpClient = new HttpClient();
httpClient.getHostConfiguration().getParams().setParameter("http.default-headers",setHeader(cookie));
PostMethod method = new PostMethod("http://www.mdjzfgjj.cn/mdjweb/website/trans/gjjquery.do?className=TRC310504");
method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
method.setParameter("time", time);
method.setParameter("accnum", accnum);
method.setParameter("certinum", certinum);
method.setParameter("password", password);
method.setParameter("mark", mark);
method.setParameter("txt", "1");
method.setParameter("verify", verify);
try{
int state=httpClient.executeMethod(method);                        //网页返回状态
if(state==HttpStatus.SC_OK){
Cookie[] cookies=httpClient.getState().getCookies();
if(cookies.length>0){
for(int i=0;i<cookies.length;i++){
if(cookies[i].toString().contains("gjjaccnum")){
map.put("gjjaccnum", cookies[i].toString());
}
if(cookies[i].toString().contains("gjjaccname")){
map.put("gjjaccname", cookies[i].toString());
}
}
}
}
}catch(Exception e){
log.error("AccumulationFundSearch_MDJ:getSetCookie",e);
e.printStackTrace();
}finally{
method.releaseConnection();
}
return map;
}


这样我就获得了我需要查询的数据。。如果大家没有看明白的话,求留言,如看到留言会为你一一解答,谢谢观看!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: