Httpcilent获取带验证码的网站内容
大家可能都遇到过网站带验证码的,用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; }
这样我就获得了我需要查询的数据。。如果大家没有看明白的话,求留言,如看到留言会为你一一解答,谢谢观看!