记一次简单的自动投票操作

        朋友在社区居委会上班,偶尔会有一些投票活动,每个人都有任务,得投到多少票才行,有点烦人又浪费时间,所以就想写一个自动投票的,这次是这个网址,规则: 选择其中一个视频,点击下方的 "投票",输入手机号码,提交即可:
        记一次简单的自动投票操作_第1张图片    记一次简单的自动投票操作_第2张图片

        由于每个人可以重复投票,因此应该没有限制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());
				}
			}
		}
	}

你可能感兴趣的:(简易的自动投票)