帮人做的,后来因为一个dll经常崩溃的问题他不要~~那白做就白做了吧 把过程分享一下
流程不难:
导入一堆账号密码文件(这边用了txt 其实用数据库好点 可以做些标识) 然后模拟网页登陆 登录成功后获取需要的数据并保存.
这边需要的工具:
- httpcomponents:用于网络连接
- java4Less:用于验证码识别
- jsoup:用于提取网页内数据
java4Less的介绍在上一篇文章中有:
http://fair-jm.iteye.com/blog/1914076
流程:
获取表单详情
这个比较简单。登陆,一般就是提交表单登陆,我们只要获得到表单的数据和提交地址就可以提交。
这里有两个常用的方式:
1,用浏览器的开发者工具
2,用wireshark抓包 分析
一般第二种比较好用,因为能抓到所有的数据,易于分析。
但这边以1用chrome为例:
打开表单提交的地址(这边以http://passport.cdcgames.net/account/login.aspx 为例了)
打开chrome的开发者工具 选中network页
乱填点数据,然后提交
查看数据:
内容很简单 以上需要注意的内容也标明了 还有一个状态码也需要注意 特别是302的状态码(要获取头中的Location进行再次跳转才可以)
用现有的用户名-密码文件不断刷就可以了。验证码用java4Less解决。
判断是否登录成功就判断返回的字段就好了,这个网站比较简单,登录成功状态码是302,得到之后再发一次请求就可以获取到了。
这边要注意一个问题:需要在客户端保存状态,也就是HttpClient的cookiestore要被保存。
在获取验证码和登录成功后,如果用了新的HttpClient对象 那么一定要把旧的对象的cookiestore给他,不然就会失败(浏览器实现了这些细节,所以不需要担心登陆之后跳转显示未登录的情况(但其实我在用一些状态极差的网络中常常遇到这样的情况....))。
涉及到在不同的网页获取的话也只要设计一下cookiestore就行了,这样就不会出现未登录的提示。
连接的工具类:
把连接的工具类发一下 不难:
package test.cc.util;
//省略导包
/**
* http的操作类
*
* @author cc(fair_jm)
* http://fair-jm.iteye.com
*/
public class HttpUtil {
private String path = "";
private String action = "";
private CookieStore cookieStore = null;
public HttpResponse sendGetTo(Map map, String encoding)
throws Exception {
StringBuffer sb = new StringBuffer();
for (Map.Entry entry : map.entrySet()) {
BasicNameValuePair bv = new BasicNameValuePair(entry.getKey(),
entry.getValue());
sb.append(entry.getKey());
sb.append("=");
sb.append(entry.getValue());
sb.append("&");
}
if (sb.length() > 0) {
sb.substring(0, sb.length() - 1);
}
HttpGet get = new HttpGet(path + action + "?" + sb.toString());
DefaultHttpClient client = new DefaultHttpClient();
if (cookieStore != null) {
client.setCookieStore(cookieStore);
}
HttpResponse response = client.execute(get);
cookieStore = client.getCookieStore();
return response;
}
/**
*
* @param map
* 传入的键值对 key=value的形式
* @param encoding
* 传入的编码
* @throws Exception
*/
public HttpResponse sendPostTo(Map map, String encoding)
throws Exception {
List list = new ArrayList();
for (Map.Entry entry : map.entrySet()) {
BasicNameValuePair bv = new BasicNameValuePair(entry.getKey(),
entry.getValue());
list.add(bv);
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encoding);
HttpPost post = new HttpPost(path + action);
System.out.println(path + action);
post.setEntity(entity);
DefaultHttpClient client = new DefaultHttpClient();
if (cookieStore != null) {
client.setCookieStore(cookieStore);
}
HttpResponse response = client.execute(post);
cookieStore = client.getCookieStore();
return response;
}
/**
*
* @param map
* 传入的键值对
* @throws Exception
*/
public HttpResponse sendPostTo(Map map) throws Exception {
return this.sendPostTo(map, "utf-8");
}
public HttpResponse sendGetTo(Map map) throws Exception {
return this.sendGetTo(map, "utf-8");
}
/**
*
* @param stream
* @return 输入流的内容
* @throws IOException
*/
private static String streamToString(InputStream stream, String encoding)
throws IOException {
ByteArrayOutputStream ba = new ByteArrayOutputStream();
byte[] bytes = new byte[512];
int len = 0;
while ((len = stream.read(bytes)) != -1) {
ba.write(bytes, 0, len);
}
return new String(ba.toByteArray(), encoding);
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public void setAction(String action) {
this.action = action;
}
public String getAction() {
return action;
}
public CookieStore getCookieStore() {
return cookieStore;
}
public void setCookieStore(CookieStore cookieStore) {
this.cookieStore = cookieStore;
}
public void clearCookieStore() {
this.cookieStore = null;
}
}
以及获取数据中的其中的一段:
while (true) {
po.clearCookieStore();
po.setPath("http://passport.cdcgames.net/account/login.aspx"); // 这边填地址
hr = po.sendGetTo(new HashMap());
String data1=null;
int hrCode=hr.getStatusLine().getStatusCode();
if(hrCode==200){
data1=streamToString(hr.getEntity().getContent(),"utf-8");
}else{
// System.out.println("连接失败,状态码:"+hrCode);
mes.setError(true);
mes.setErrorCode("连接失败,状态码:"+hrCode);
return mes;
}
//
Pattern rex = Pattern.compile("value=\"(.*)\"");
Matcher matcher = rex.matcher(data1);
// System.out.println(data1);
// System.out
// .println("______________________________+++++++++++______________________");
String code = null;
if (matcher.find()) {
code = matcher.group(1);
// System.out.println(code);
}
DefaultHttpClient client = new DefaultHttpClient();
client.setCookieStore(po.getCookieStore());
HttpGet get = new HttpGet(
"http://passport.cdcgames.net/VerifyCode.aspx");
HttpResponse res = client.execute(get);
String verify = OCRTestMine.getVerifyText(res.getEntity()
.getContent());
po.setPath("http://passport.cdcgames.net/account/login.aspx");
HashMap has = new HashMap();
has.put("__EVENTTARGET", "LB_Login");
has.put("__EVENTARGUMENT", "");
has.put("__VIEWSTATE", code);
has.put("TB_userid", userTrueName);
has.put("TB_password", userPass);
has.put("TB_rand", verify);
hr2 = po.sendPostTo(has);
String data2="";
int hr2Code=hr2.getStatusLine().getStatusCode();
if(hr2Code==302){
break; //302表示登陆成功执行跳转
}else{
if(hr2Code==200){
data2=streamToString(hr2.getEntity().getContent(), "utf-8");
}else{
// System.out.println("连接出错,状态码:"+hr2Code);
mes.setError(true);
mes.setErrorCode("连接出错,状态码:"+hr2Code);
return mes;
}
}
// System.out
// .println("______________________________+++++++++++______________________");
boolean verifyFail = false;
boolean passAndNameFail = false;
verifyFail = data2.indexOf("验证码不正确") != -1;
passAndNameFail = data2.indexOf("账号或密码错误") != -1;
// System.out.println("验证码不正确:"
// + (verifyFail = data2.indexOf("验证码不正确") != -1));
// System.out.println("账户或密码错误:"
// + (passAndNameFail = data2.indexOf("账号或密码错误") != -1));
if (verifyFail) {
if (failTime < 5) {
failTime++;
continue;
} else {
// System.out.println("验证码错误5次,退出");
mes.setVerifyError(true);
mes.setErrorCode("验证码错误5次,退出");
return mes;
}
}
if (passAndNameFail) {
// System.out.println("账户或密码错误");
mes.setPassError(true);
return mes;
}
break;
}
数据获取:
获取数据的话用jsoup完成,主要观察包含数据的html元素是否有id(因为有id获取最方便)
过程就不多说 毕竟用jsoup完成的话是很轻松的事