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;
    }

这样我就获得了我需要查询的数据。。如果大家没有看明白的话,求留言,如看到留言会为你一一解答,谢谢观看!

posted on 2013-12-10 15:48  谢皓宇  阅读(847)  评论(0编辑  收藏  举报

导航