关于httpclient处理图片验证码提交的问题

JavaLiver 2013-03-27 04:59:20
本人之前用httpclient 3做了个自动登录网站的程序,实现的功能为登录网站,并在另一个页面post一个请求,请求时有图片验证码。

登录功能没有问题,在后面的post之前,我先从网站用get方法获取这个最新的验证码图片,然后调用本地程序解析成正确的String,但是提交了之后还是回到这个提交页面。

我用浏览器模拟了一下这些操作,提交成功的话应该是返回302,并转到另一个page。如果是验证码错误,就会返回200,并回到提交的页面,原来的字段输入都会保存在页面上(用的应该是aspx的__VIEWSTATE和__EVENTVALIDATION)但不会提示验证码错误。
就因为网站本身不会提示验证码错误,所以我程序返回200,并回到原来的页面我就无从判断到底是什么原因,因为我在本地程序里看到的验证码的确是解析正确的。

猜测会不会是cookie的问题,但我登录之后,每次操作前都会获取一下cookie,并且在get或者post前,用httpclient再把cookie set回request里,这样跳转页面的话,session还能保持的。

或者是验证码重复刷新的问题,但是我用fiddler看过浏览器的请求过程,它先用get获取那个要提交的页面,然后会自动用get获取那个验证码,再人工点击提交form。我只不过是直接用get获取了那个验证码,然后post提交了那个页面。

也怀疑过是aspx的__VIEWSTATE和__EVENTVALIDATION,在我的post request里有这两个字段的值,每次用浏览器提交,似乎都是不变的,所以我直接写进request了。如果不包括这两个值,那么如果验证码错误的话,返回到提交页面,上面原来部分输入的字段就是空的要重新输入,所以这两个参数应该是用来记录页面信息并还原的。

请有经验的朋友指教指教,如果能解决,立马结贴,谢谢!
...全文
440 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzzgym 2013-10-14
  • 打赏
  • 举报
回复
网站把验证码写在cookie里??这种方式也太不安全了吧 一般的做法都是直接放在session啊。。。 最近一直在研究验证码,有兴趣交流。。。。
JavaLiver 2013-03-29
  • 打赏
  • 举报
回复
如果用一个httpclient依次做,会不会有问题? 还是说要new多个httpclient?
  • 打赏
  • 举报
回复
看着没啥问题 httpClient.getCookieStore().getCookies() 获取cookie,看看有没有set进去吧
  • 打赏
  • 举报
回复
并发问题。。
JavaLiver 2013-03-28
  • 打赏
  • 举报
回复
调试通了!!!Cookie没问题。是一个很低级的问题,这个网站通过获取另个值来判断是否实际做了操作的,而我提交的那个值的name打错了一个字母,等于没提交成功。。瀑布汗。。。。。。。。。。。 依然谢谢楼上看了我的代码,并回复。 我顺便在这里问最后个问题,如果我要同时用3个用户名登录网站,都做一遍上面这个操作,(3个依次做也可以),是不是要用3个httpclient呢?怎么实现效率较高呢?最好不要用线程,感觉太麻烦。谢谢回答!
JavaLiver 2013-03-27
  • 打赏
  • 举报
回复
上面getFinalPostMethod里面 post.setRequestBody(new NameValuePair[] { _EVENTTARGET, _EVENTARGUMENT, _VIEWSTATE, _EVENTVALIDATION, t1, t2, CheckCode, CheckCode }); 上面多输入了一个CheckCode,实际代码里是没有的。
JavaLiver 2013-03-27
  • 打赏
  • 举报
回复
HttpClient client = new HttpClient(); client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT, "http"); client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); client.getParams().setParameter(HttpMethodParams.USER_AGENT, "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0"); HttpMethod method_post = getPostMethod(); // 使用 POST 方式提交数据 method_post.getParams().setParameter("http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY); client.executeMethod(method_post); method_post.releaseConnection(); String tmpcookies = GetCookies(client); GetCheckCode(client, tmpcookies); HttpMethod final_post = getFinalPostMethod(); final_post.getParams().setParameter("http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY); tmpcookies = GetCookies(client); final_post.setRequestHeader("cookie", tmpcookies); client.executeMethod(final_post); int statuscode = final_post.getStatusCode(); if (statuscode == 200) { String response = final_post.getResponseBodyAsString(); System.out.println(response); //如果验证码错误,返回的应该是200 } if (statuscode == 302) { //如果验证码正确,并且正确提交,返回的应该是302 Header header = final_post.getResponseHeader("location"); newuri = header.getValue(); System.out.println("final_post newuri:" + newuri); if ((newuri == null) || (newuri.equals(""))) newuri = "/"; GetMethod redirect = new GetMethod(newuri); tmpcookies = GetCookies(client); redirect.setRequestHeader("cookie", tmpcookies); client.executeMethod(redirect); System.out.println("==========Final Redirect:==========\n" + redirect.getStatusLine().toString()); System.out.println(redirect.getResponseBodyAsString()); redirect.releaseConnection(); } final_post.releaseConnection(); private static HttpMethod getPostMethod() { PostMethod post = new PostMethod("/login.aspx"); NameValuePair username = new NameValuePair("name", "my name"); NameValuePair password = new NameValuePair("password", "pass"); post.setRequestBody(new NameValuePair[] { username, password}); return post; } private static HttpMethod getFinalPostMethod() { PostMethod post = new PostMethod("/finalpost.aspx?m1=100"); NameValuePair _EVENTTARGET = new NameValuePair("__EVENTTARGET", ""); NameValuePair _EVENTARGUMENT = new NameValuePair("__EVENTARGUMENT", ""); NameValuePair _VIEWSTATE = new NameValuePair( "__VIEWSTATE", "/asdfuovansodfhasdhsdfkasdf="); NameValuePair _EVENTVALIDATION = new NameValuePair( "__EVENTVALIDATION", "/sdfgsdfasdfasdf=="); NameValuePair t1 = new NameValuePair("t1", "test"); NameValuePair t2 = new NameValuePair("t2", "test@sina.com"); NameValuePair CheckCode = new NameValuePair("CheckCode", code); post.setRequestBody(new NameValuePair[] { _EVENTTARGET, _EVENTARGUMENT, _VIEWSTATE, _EVENTVALIDATION, t1, t2, CheckCode, CheckCode }); post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8"); post.setRequestHeader("referer","http://fortest.com.cn/finalpost.aspx?m1=100"); return post; } private static String GetCookies(HttpClient client) { String tmpcookies = ""; Cookie[] cookies = client.getState().getCookies(); for (Cookie c : cookies) { tmpcookies += c.toString() + ";"; } return tmpcookies; } public static void GetCheckCode(HttpClient client, String tmpcookies) throws HttpException, IOException { /********** Get Checkcode **********/ GetMethod getcode = new GetMethod("/getCode.aspx"); getcode.setRequestHeader("cookie", tmpcookies); client.executeMethod(getcode); System.out.println("getting code status: " + getcode.getStatusLine().toString()); InputStream inStream = getcode.getResponseBodyAsStream(); BufferedImage iag = ImageIO.read(inStream); //以下省略了较长的解析代码,弄成本地图片在本地解析,然后赋值到这个public类的String类型的code字段,code字段是在getFinalPostMethod方法中所使用到的。 }
  • 打赏
  • 举报
回复
没错误,就上代码先。
-AJ- 2013-03-27
  • 打赏
  • 举报
回复
我觉得这样的描述,不太容易找到原因。 你用httpwatch看一下。这里有范例http://www.cnblogs.com/mayingbao/archive/2007/11/30/978530.html
JavaLiver 2013-03-27
  • 打赏
  • 举报
回复
关键就是没有错误信息,我上面也提到,最后那个post的页面,我用浏览器去访问并且用错误验证码去提交的话,结果会是继续返回到这个提交页面,然后系统刷新了一下那个验证码,并不会有报错。如果我用程序去post,然后打印出200 response的结果,也是返回到这个页面,但是我用的是正确的验证码,所以有点怀疑post之后是不是系统又刷新了一下验证码,但是用wiresharp和fiddler并没有看到,也没有理由post后服务器会去调用get刷新验证码。所以怀疑cookie/session的问题,但每次我都是设置cookie了的。。。所以是不是做这种程序还有什么特别要注意的地方。 实在不行,打算用httpclient4做一下,或者模仿浏览器访问的流程,登录后先get一下这个提交页面,然后从上面拿下那个验证码图片。。。
  • 打赏
  • 举报
回复
具体错误信息。
JavaLiver 2013-03-27
  • 打赏
  • 举报
回复
顺便说一下,显示我的结贴率为0,因为这个id很久没用了,之前一直用另一个id的。这次特地上来把这个id里的分给用完。

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧