朋友在社区居委会上班,偶尔会有一些投票活动,每个人都有任务,得投到多少票才行,有点烦人又浪费时间,所以就想写一个自动投票的,这次是这个网址,规则: 选择其中一个视频,点击下方的 "投票",输入手机号码,提交即可:
由于每个人可以重复投票,因此应该没有限制ip,提交的时候也没有验证码之类的限制手段,因此属于比较简单类型的,第一次做这种事情,没什么技术含量,记录下而已,基本思路是: 批量随机生成电话号码,修改上传数据中的手机号码信息,循环提交即可; 另外,项目文件地址;
1. 获取http交互数据信息
可以使用抓包软件,如wireshark,我就简单使用浏览器调试插件firebug直接获取;
单击视频"回归社会"的"提交"按钮后抓取到的post请求信息如下:
Post请求信息为:
Parameters
id 146
outside 0
tel 18965866666
Source
id=146&tel=18965866666&outside=0
服务端返回信息为:
{"result":2}
其对应页面提示为 "30秒内只允许投一次!"
从上面的信息中我们知道:
URL_ADDRESS : http://116.213.200.40/vote/zan
请求方式 : POST
提交信息内容 : id=146&tel=18965866666&outside=0
可以猜测,id表示展播视频的标识,tel是填写的投票号码,outside是国内国外的区分标识,具体作用可通过html源码确认;
将展播网页保存下来,查看源码,搜索"146"可以发现它就是该视频的rel属性:
2. 生成随机手机号码
源文件: https://github.com/lucid-lynxz/AutoVotingDemo/blob/master/src/org/lynxz/utils/Commonfunctions.java
/**
* @function 生成随机电话号码
* @param totalCount 总共生成多少个11位手机号码
* @param preFix 号码开头前缀 如,13,14,15,17,18等等
* @return
*/
public Set<String> getRandomPhoneNumSet(int totalCount, String preFix) {
String[] validPrefix = { "13", "14", "15", "17", "18" };
boolean isPrefixValid = false;
for (String tempFre : validPrefix) {
if (tempFre.equals(preFix)) {
isPrefixValid = true;
}
}
if (!isPrefixValid) {
logger.info("preFix异常 preFix = " + preFix);
preFix = validPrefix[0];
}
HashSet<String> phoneSet = new HashSet<>();
StringBuilder sb = new StringBuilder();
double randomDouble = 0;
BigDecimal bg = null;
int index = 0;
for (int i = 0; i < totalCount;) {
if (index >= totalCount * 5) {
return phoneSet;
}
sb.setLength(0);
sb.append(preFix);
randomDouble = Math.random() * Math.pow(10, 11);
bg = new BigDecimal(randomDouble);
sb.append(bg.toString().substring(0, 9));
phoneSet.add(sb.toString());
index++;
i = phoneSet.size();
}
return phoneSet;
}
3. 创建post方法
/**
* @function 向指定 URL 发送POST方法的请求
* @param url 发送请求的 URL
* @param param 请求参数,使用key,value的形式,会自动使用"&"进行连接
* @return 响应结果
*/
public static String sendPost(String url, Map<String, String> params) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
String param = "";
String connector = "&";
for (Map.Entry<String, String> entry : params.entrySet()) {
param += connector + entry.getKey() + "=" + entry.getValue();
}
if (param.startsWith(connector)) {
param = param.substring(1);
}
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性 - 可以通过firebug直接抓取
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/5.0 (X11; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
// flush输出流的缓冲
out.print(param);
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
logger.info("发送 POST 请求出现异常!" + e);
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
4. 开启线程循环刷新请求
源文件: https://github.com/lucid-lynxz/AutoVotingDemo/blob/master/src/org/lynxz/vote/AutoVote.java
// 通过firebug调试得到投票时上传的数据为: id=146&tel=18965870620&outside=0
private static final String URL_ADDRESS = "http://116.213.200.40/vote/zan";// 居委会文艺展播投票地址
private static String[] workIds = { "146" };// 投票作品id
private static final String outside = "0";
private static Logger logger = Logger.getLogger("AutoVote");
private static final long SLEEP_DUARATION = 90000;
public static void submitPhoneNum(int count, String preFix) {
Commonfunctions utility = Commonfunctions.getInstance();
HashMap<String, String> params = new HashMap<>();
String phoneNum = "", result = "";
params.put("outside", outside);
for (int i = 0; i < workIds.length; i++) {
Set<String> randomPhoneNumSet = utility.getRandomPhoneNumSet(count,
preFix);
if (randomPhoneNumSet == null) {
logger.info("randomPhoneNumSet == null");
return;
}
Iterator<String> iterator = randomPhoneNumSet.iterator();
while (iterator.hasNext()) {
phoneNum = iterator.next();
logger.info("phoneNum " + phoneNum);
params.put("id", workIds[i]);
params.put("tel", phoneNum);
result = Commonfunctions.sendPost(URL_ADDRESS, params);
logger.info("result " + result);
if (result.contains("0")) {
logger.info("投票成功 " + phoneNum);
} else if (result.contains("2")) {
//logger.info("30秒内只允许投一次");
} else if (result.contains("8")) {
//logger.info("每个手机号只能投票一次 " + phoneNum);
}
try {
Thread.sleep(SLEEP_DUARATION);
} catch (InterruptedException e) {
logger.info(e.toString());
}
}
}
}