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

Posted 冰川孤辰csdn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次简单的自动投票操作相关的知识,希望对你有一定的参考价值。

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

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

以上是关于记一次简单的自动投票操作的主要内容,如果未能解决你的问题,请参考以下文章

记一次接收微信公众平台推送消息的实例

记一次简单的清理挖矿程序过程

记一次 .NET 某工控自动化控制系统 卡死分析

记一次站点被挂马问题排查

记一次站点被挂马问题排查

记一次 Centos 7 搭建 Nexus (Maven私服)