java模拟有验证码的Http登陆
所需资源下载链接(资源免费,重在分享)
Tesseract:http://download.csdn.net/detail/chenyangqi/9190667
jai_imageio-1.1-alpha,swingx-1.0:http://download.csdn.net/detail/chenyangqi/9190683
HttpWatch Professional:http://download.csdn.net/detail/chenyangqi/9208339
HttpClient.jar codec.jar logging.jar:http://download.csdn.net/detail/chenyangqi/9208315
简介:
模拟如下登陆页面,需要大家自行掌握HttpWatch使用方法
OCR-Tesseract如何识别验证码可参考我的另一篇博客http://www.cnblogs.com/chenyangqi/p/4906282.html
一:
使用eclipse建一个项目,引入OCR-Tesseract 和HttpClient所要使用的几个jar包(jar包在文章开头已提供了下载链接)
项目思路:
1:第一次Http请求验证码URL(一般是get请求)下载验证码到本地,通过OCR-Tesseract识别,返回验证码,并保存Cookie
一下是HttpWatch中验证码URL的请求抓包,只需要使用get方式和URL地址。
2:第二次Http请求登陆URL(一般是post请求)发送HttpWatch中的Postdata一栏中的数据。同步Cookie,并返回Inputstream数据
3:请求成功,匹配返回的InputStream数据,若有匹配则登陆成功。
这就是返回的数据和预期的是否一样了,返回的数据在HttpWatch里面的Content可看到,对比一下请求成功和失败的不同,可以使用SubString看有没有匹配的,或者是正则表达式
二:难点解决
要实现登陆最重要的就是验证码识别和Cookie同步的问题了,验证码识别在我的另一篇博客已解决http://www.cnblogs.com/chenyangqi/p/4906282.html
所以只剩下Cookie的问题了,之前使用的是HttpConnection老是Cookie不同步,后面换了HttpClient(使用HttpClient需应用HttpClient.jar codec.jar logging.jar三个jar包,可在文章开头处下载),HttpClient对象可以很好的管理
Cookie和请求头。所以Cookie的读取和同步,我们不需要操作,只要保证是同一个HttpClient对象就ok了,所以定义HttpClient为全局变量比较好,也注意避免多线程造成HttpClient对象变化,应为HttpClient对象一变化Cookie也就变了
无法同步Cookie造成登陆失败。
三:代码实现:
package com.cyq.request; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Scanner; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; public class RequestMain {static HttpClient client = new HttpClient(); public static void main(String[] args) { Init(); } private static void Init() { getImage("用户名","密码"); } private static void getImage(String name_get, String password_get) { GetMethod get = new GetMethod( "验证码URL地址"); try { client.executeMethod(get); File storeFile = new File("D:/verifycode.jpg");//验证码暂存本地位置 FileOutputStream output = new FileOutputStream(storeFile); InputStream is = get.getResponseBodyAsStream(); FileOutputStream fos = new FileOutputStream(storeFile); byte[] b = new byte[1024]; while ((is.read(b)) != -1) { fos.write(b); } is.close(); fos.close(); String codeVal = getCode(); try { String code = codeVal.substring(0, codeVal.indexOf("\n") - 1); postRequest(name_get, password_get, code); } catch (Exception e) { System.out.println("e" + name_get + "验证码错误"); } } catch (IOException e) { e.printStackTrace(); } } private static void postRequest(String name_data, String password_data, String code) { PostMethod postMethod = new PostMethod( "登陆时的post请求URL地址"); NameValuePair[] data = { new NameValuePair("act", "add"), new NameValuePair("name", name_data), new NameValuePair("password", password_data), new NameValuePair("verify", code) }; postMethod.setRequestBody(data); try { client.executeMethod(postMethod); String text = postMethod.getResponseBodyAsString(); // 匹配结果集中是否有匹配的字符串 if (text.indexOf("self.location='../../../module/webcontent/web/index_self.jsf") >= 0) { RESULT_DATA.add("用户名:"+name_data+" 密码:"+password_data); WriteResultToFile("用户名:"+name_data+" 密码:"+password_data); System.out.println("用户名" + name_data + "成功"); } else { System.out.println("用户名" + name_data + "失败"); } } catch (IOException e) { e.printStackTrace(); } } private static String getCode() { String valCode = null; String path = "d://verifycode.jpg"; try { valCode = new OCR().recognizeText(new File(path), "jpg"); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return valCode; } }
好啦,over,。
声明:该博文为博主原创,转载请注明出处
本程序模拟仅用于学习,请勿使用该内容从事违法活动和暴力破解活动