如何写一个自动投票工具

当然,自动投票这个违反了正常竞争,不提倡,这里只就技术问题做个探讨。

投票服务器一般的验证条件:
[list]
[*]IP地址不能重复
[*]Cookie验证
[*]验证码验证
[/list]
一个自动投票工具可能涉及的问题:
[list]
[*]自动变换IP地址
[*]识别验证码
[*]伪装成浏览器提交
[/list]

[b]自动变换IP地址[/b]

一种直接的办法就是控制ADSL的链接状态来实现IP变换,具体可以参考[url=http://sesame.iteye.com/blog/434088]这里[/url]。但如果你使用的不是ADSL,那么更直接的办法就是使用代理了。

首先你需要一个有效代理列表,可以从网上专门提供代理网站收集,也可以有专门的工具,比如商易代理IP获取器。如果是网站获取,你可以写个页面解析程序,分页获取;如果是软件,在获取可用代理后,一般可以直接导成txt文本。

接下来就是要测试代理的可用性,一般可用代理不到采集下来的1/10。
测试代理的有效性:

static String myIP = "X.X.X.X";//自己原来的对外IP
private static boolean testProxy(String ip, String port) {
System.getProperties().setProperty("http.proxyHost", ip);
System.getProperties().setProperty("http.proxyPort", port);

InputStream in = null;
try {
in = new URL("http://iframe.ip138.com/ic.asp").openStream();
String string = IOUtils.toString(in, "GBK");
System.out.println(string);

return string.indexOf(myIP) < 0;
} catch (Exception e) {
return false;
} finally {
if (in != null)
IOUtils.closeQuietly(in);
}
}



[b]伪装成浏览器提交[/b]

这里是斗智斗勇的时候,有时候投票服务器会使用一些小手段来阻碍模拟者,你需要伪装成一个普通浏览器,并具有和用户操作一样的行为。

你可以使用firefox(firebug)或是chrome的调试器查看正常投票的网络信息,从而进行模拟。

一般的伪装:

DefaultHttpClient httpclient = new DefaultHttpClient();
// 代理的设置
HttpHost proxy = new HttpHost(ip, Integer.parseInt(port));
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
proxy);
httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
CookiePolicy.BROWSER_COMPATIBILITY);
httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0");
httpclient.getParams().setParameter( CoreProtocolPNames.HTTP_CONTENT_CHARSET, "GBK");

HttpPost httppost = new HttpPost("http://XXX");

httppost.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0");
httppost.addHeader("Host", "XXX);
httppost.addHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httppost.addHeader("Accept-Encoding", "gzip, deflate");
httppost.addHeader("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
httppost.addHeader("Cache-Control", "max-age=0");
httppost.addHeader("Connection", "keep-alive");
httppost.addHeader("Referer","http://XXX");



[b]识别验证码[/b]

这个是个大话题,识别验证码方法很多,比较有效的方法是采用[url=https://code.google.com/p/tesseract-ocr/downloads/list]tesseract-ocr[/url]。一般的验证码都不在话下,个别的需要自己训练一下,可以参考[url=http://my.oschina.net/lixinspace/blog/60124]这里[/url]。
一般的用法:
tesseract test.jpg out -l eng digits

test.jpg为验证码图片,out为识别的验证码存放的txt文件名,-l eng为指定语言,也可以下载支持中文的包识别中文,digits为指定只识别数字,这样对于只是数字的验证码可以提高识别率。

如果你发现tesseract提示empty page!!,则需要修改一下参数:

Here's a summary of compression support and limitations:
- All formats except JPEG support 1 bpp binary.
- All formats support 8 bpp grayscale (GIF must have a colormap).
- All formats except GIF support 24 bpp rgb color.
- All formats except PNM support 8 bpp colormap.
- PNG and PNM support 2 and 4 bpp images.
- PNG supports 2 and 4 bpp colormap, and 16 bpp without colormap.
- PNG, JPEG, TIFF and GIF support image compression; PNM and BMP do not.
- WEBP supports 24 bpp rgb color.

比如最后的指令可能为:
tesseract test.jpg out -l eng -psm 7 digits


tesseract识别格式有限,有的网站的验证码格式是bmp或其他,这个时候需要先获取下来byte[],保存成原有格式,然后再转化成支持的格式,比如jpg,tif等。转化工作可以使用[url=http://www.oracle.com/technetwork/cn/java/javaee/downloads/readme-1-1-2-137176.html]JAI(Java Advanced Imaging API)[/url]。

对于有的验证码,还需要做一些前期处理,比如去掉背景噪点,灰度化,增大对比度,去掉干扰线条等。

用java调用是必须的:

public static String doOCR(File imageFile) throws Exception {
String result = "";
File outputFile = new File(imageFile.getParentFile(), "output");
StringBuffer strB = new StringBuffer();

List<String> cmd = new ArrayList<String>();
cmd.add(tessPath + "\\tesseract");
cmd.add("");
cmd.add(outputFile.getName());
cmd.add(LANG_OPTION);
cmd.add("eng");
cmd.add("-psm");
cmd.add("7");
// cmd.add("nobatch");
cmd.add("digits");

ProcessBuilder pb = new ProcessBuilder();
pb.directory(imageFile.getParentFile());

cmd.set(1, imageFile.getName());
System.out.println(cmd.toString());
pb.command(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();

int w = process.waitFor();
logger.debug("Exit value = {}", w);

if (w == 0) {
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream(outputFile.getAbsolutePath() + ".txt"),
"UTF-8"));

String str;

while ((str = in.readLine()) != null) {
strB.append(str).append(EOL);
}
in.close();
} else {
String msg;
switch (w) {
case 1:
msg = "Errors accessing files. There may be spaces in your image's filename.";
break;
case 29:
msg = "Cannot recognize the image or its selected region.";
break;
case 31:
msg = "Unsupported image format.";
break;
default:
msg = "Errors occurred.";
}
System.err.println("验证码获取失败:" + msg);
}

new File(outputFile.getAbsolutePath() + ".txt").delete();
result = strB.toString().trim();
return result;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值