zoukankan      html  css  js  c++  java
  • 利用C#编写网页投票器程序

    一、前言
    看个图,了解下投票的过程。
    提交投票信息
    投票页 ――――――――>投票信息处理页
    反馈投票结果
    (请求页)<―――――――(响应页)
    一般情况下,填写投票信息,然后点提交按钮发送到响应页,这样来完成一个投票。这过程繁琐,还不能多次投票。有时,手工投票达不到所期待的效果。
    曾帮朋友弄过几次投票,坛里有朋友也PM说要看看源代码。投票器应该说没有一个固定的框架,一些处理方法上需要视响应页做针对性的改动。
    自己写的源代码太杂乱,放出来怕丢人。10.1放假窝在家里写了点心得,与大家分享一下。看过之后,你也可以写。不当之处请指正。

     制作投票器,最关键的二样东西是获得投票信息和找到响应页。也就是说通过请求页访问(提交)响应页时,提交了什么信息,并且这个响应页是什么。找到了这两样,投票器完成了一大半。
    二、编写投票器所需要的一些HTTP知识
    1、 最好是写过一些网页。看某网页的源文件,可以很快找到哪些是form表单、BUTTON提交按钮、INPUT文件框等内容。
    恶补网站:
    http://www.lib.tsinghua.edu.cn/chinese/INTERNET/HTML/Normal/html_design.html
    http://www.w3.org/TR/REC-html40/index/elements.html
    http://www.w3.org/TR/REC-html32.html

    2、了解一个HTTP的消息头由哪些内容组成。如下是一个表单提交后,向网站发送的消息头内容:

    POST /redsky/temp/whu_tp/vote.asp HTTP/1.1 //定义HTTP是一个POST动作
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
    //响应页可以使用的媒体类型
    Referer: http://pmc.whu.edu.cn/redsky/temp/whu_tp/whu_tp.asp //请求页的网址
    Accept-Language: zh-cn //指定的字符集类型
    Content-Type: application/x-www-form-urlencoded
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; FunWebProducts; mxie; .NET CLR 1.1.4322)
    Host: pmc.whu.edu.cn
    Content-Length: 46 //提交数据的长度
    Connection: Keep-Alive
    Cache-Control: no-cache
    Cookie: ASPSESSIONIDQSCDRSCC=NHNDPPNDPJJFBBJMLBAOMHOD //提交时所传送的Cookie值。

    voted=25&voted=30&voted=35&Submit=%CD%B6%C6%B1 //提交时,所传送的数据

    恶补网站:
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14

    小结: WIN form 、WEB FORM两样都得精通,这是师傅2002年说的。


    三、辅助软件
    查看HTTP消息头的软件,专门的软件有HTTP Watch(
    http://www.hanzify.org/index.php?Go=Show::List&ID=4384)或IEWatch,
    也可以用 CommView (这些天www.ttdown.com上的软件没法下载:-()之类抓包的软件。


    四、手工分析投票过程
    先说说手工操作时一个正常的投票过程(以武汉大学的这个投票为例)
    http://pmc.whu.edu.cn/redsky/temp/whu_tp/whu_tp.asp
    选择被投票人石云霞(在姓名前面打勾),然后点“投票”,响应页接收被投票人的姓名并记录投票数记录投票人的IP,然后返回投票成功或重复投票的信息。
    这一过程很简单,但我们不知道点投票后,浏览器向网页发送了什么信息。在这里,先别急着用软件来看,尝试手工分析,这有助于一些复杂情况的解决。
    回到投票的网页,查看源文件(前面所提到的http基本知识派上用场了),
    a)首先找响应页是什么,也就是接收处理投票信息的网页。在记事本中按Ctrl+f,查找’<form’字符串。通过搜索,找到这么一行:
    <form name="form1" method="post" action="vote.asp">
    Form表单的名称name=form1,方法method=post,动作action=vote.asp 。vote.asp是我们所关心的,这个就是响应页的地址。
    整理地址得到:http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp
    b)查找被投票人的信息。被投票人的选择是通过一个多选框来完成,那么在源文件里查找’<input’字样。通过搜索,找到了以下内容。
    <input type="checkbox" name="voted" value="25">
    <a href="whu_tp_more.asp?id=25" class="index" target="_blank">
    石云霞</a> <b><font color="#FFFF00" size="2">  </font></b>

    <input type="checkbox" name="voted" value="26">
    <a href="whu_tp_more.asp?id=26" class="index" target="_blank">
    李义天</a> <b><font color="#FFFF00" size="2">  </font></b>
    ………………………….
    从这一大串内容中可以看出,石云霞的编号为25,李义天的编号为26 ,input元素的名称为voted。 整理一下voted=25这是被投票人的信息。
    查找input的时候需要注意,看是否有hidden类型的input元素。隐藏一定数量的input元素,可以起到一定的防范作用。
    在源文件里一直看下去,只到</form>为止。在</form>前还有两个按钮,
    <input type="submit" name="Submit" value="投票">
    <input type="reset" name="Submit2" value="重置">
    组合一下 submit=投票 submit2=重置(这个内容可以忽略)。
    c) 最后整理一下,得到一个完整的网址
    http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp?voted=25& submit=投票
    在浏览器中访问一下这个地址,看有什么提示??,提示“投票成功“。再次访问提示“你的IP已经投过一次了^_^”。这说明这个网址就是真正的投票网址。只要不断地访问这个网址,就可以达到投票的目的。

    小结:没写过网页也没关系,通过辅助软件也可以分析出这一网址。


    五、软件分析投票过程
    安装HTTPWATCH后,重启机器,可以在IE标准按钮栏中找到它的图标(没有的话,从菜单‘查看’->‘浏览器栏’中选择),单点图标后如图,IE窗口下半部分显示出HTTPWATCH的工作窗口。
    http://bbs.et8.net/bbs/attachment.php?attachmentid=339392&stc=1
    图中显示的内容是选择点击‘投票’按钮后,IE与网站之间的数据流。上半部分记录了IE访问了哪几个网页,下半部分是访问某个网页时,具体的数据流。
    (HTTPWATCH的使用方法在这里不细讲了。)
    我们在正常浏览网页时,IE一般的动作都是GET。而投票过程中,IE需要将你的选择(被投票人的姓名)提交给投票的网址,访问这个网址时,IE将产生一个POST动作。查看HTTPWATCH的记录,URL=http: //pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp时,IE的动作是POST。那么http: //pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp就是投票的响应页。这和前面手工分析时找到的响应页是一致的。
    找到了响应页,接下来找投票的信息,也就是IE提交了什么数据。这里看HTTPWATCH窗口的下半部分。
    下半部分是一个TAB PANEL,看重要的几个标签。
    HEADERS:提交到响应页的HTTP HEADER的内容。
    Cookies:提交时,Cookies的内容。
    POST DATA:提交时,IE向响应页发送的数据。
    STREAM:提交时,本地机器与网站之间的传输的数据流。
    http://bbs.et8.net/bbs/attachment.php?attachmentid=339393&stc=1
    显而易见,POST DATA是我们要找的内容。看到这个标签,左边是两个参数名voted 和submit ,右边是两个参数的值,‘25’和‘投票’。整理一下得到:
    Voted=25 submit=投票
    将这两个参数值与前面找到的网址整理一下,得到
    http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp?voted=25& submit=投票

    六、编写投票器
    找到了真正的投票URL,用C#做投票器就简单了,无非是做到:如何循环地访问这个网页。
    看下面的这个过程。

    ………
    using System.Net;
    ………

    public int GotoURL( out string message,string url,int timeout,string proxyurl,string keyword,out int rate,bool proxyed)
    /*
    Message:返回的信息
    Url:需要访问的地址
    Timeout:超时时间
    Proxyurl:代理的地址
    Keyword:判断投票成功的标志
    Rate:访问url所花费的时间
    Proxyed:是否使用代理
    */
    {
    byte[] gbyte=new byte[1024];
    string strInput;
    int iret=3;
    int i,len=0;
    DateTime dtBegin=DateTime.Now;
    message="正在访问中。。。";
    try
    {

    url=@"http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp?voted=25& submit=投票";
    WebRequest myWebRequest=WebRequest.Create(url);
    myWebRequest.Timeout=timeout;//设置超时时间=15000毫秒

    if (proxyed)//是否使用代理功能
    {

    WebProxy myProxy=new WebProxy();//实例化一个WebProxy类,这个类设置WebRequest的Proxy属性,这样可以通过代理来访问url。
    myProxy=(WebProxy)myWebRequest.Proxy;
    string proxyAddress= proxyurl;
    Uri newUri=new Uri(proxyAddress);
    myProxy.Address=newUri;
    myWebRequest.Proxy=myProxy;
    }
    WebResponse myWebResponse=myWebRequest.GetResponse();//实例化一个WebResponse类,用于接收WebRequest的响应内容,依据内容来判断投票是否成功。
    Stream streamResponse=myWebResponse.GetResponseStream();// 实例化一个Stream类,从WebResponse接收数据流。

    i=streamResponse.Read(gbyte,len,1024);
    len+=i;
    while(i!=0)
    {
    i=streamResponse.Read(gbyte,len,1024);
    len+=i;
    }

    strInput=System.Text.Encoding.GetEncoding("gb2312").GetString(gbyte);
    i=strInput.IndexOf("成功");
    Console.WriteLine(i);
    if (i==-1)
    message="访问成功";
    else
    message="访问失败";// 将数据流转换成字符串,并从中判断投票是否成功。
    iret=0;
    streamResponse.Close();
    }

    catch (System.Net.WebException we)
    {
    message="NetError"+we.Message;
    }
    catch (System.IO.IOException ie)
    {
    message="IOError"+ie.Message;
    }
    catch (System.Exception ex)
    {

    message=ex.Message;


    }

    TimeSpan ts=DateTime.Now-dtBegin;
    rate=(int)ts.TotalMilliseconds; //获取访问的时间。
    return iret;
    }

    过程很简单,就是使用System.Net中的两个类来访问网页。
    创建实例:WebRequest myWebRequest=WebRequest.Create(url);
    访问网页:WebResponse myWebResponse=myWebRequest.GetResponse();
    流StreamResponse视响应页的处理方法,可能没有任何返回内容。
    Stream streamResponse=myWebResponse.GetResponseStream();

    考虑到一个IP只能投票一次的限制,过程加了使用代理的功能
    WebProxy myProxy=new WebProxy();
    这样即可以当投票器来使用,也可以用于检测代理的有效性。

    接下来的事,就容易多了。找代理,循环调用这个过程。循环速度感觉慢的话,可以用多个线程一起来跑。


    小结:直接访问响应页就能投票,这是最常见的投票方式。网页设计人员没有在响应页做防范处理,从而为投票器创造了的条件。
    防范措施通常有以下几种:
    1、 对HTTP HREADERS里的REFERER做判断,为空表示没有访问过投票页(提交页)。这样绕开请求页,直接访问响应页是无效的。
    2、 访问投票页时,在headers里的cookies里设置某种标志,提交时,响应页对这个标志做判断。没有这个标志,直接访问响应页是无效的。
    3、 访问投票页时,随机生成N位数字验证码,响应页对验证码做判断。
    4、 生成图形验证码。响应页对验证码做判断。
    第1、2种方法容易处理,研究出规律,设置WebRequest的headers属性。
    第3种方法需要多加个过程,首先访问投票页得到验证码,然后与其他data组合一同post给响应页。
    第4种无解,和和。不过,还没发现哪种投票会用上图形验证码这措施。手工投票不仅麻烦,同时也关闭了自己、他人的方便之门。


    结言:
    不管投票方式如何,投票所需填写的内容有多复杂,最终它还是要提交给响应页做处理。多看看http watch。
    不会编程也没关系,找代理软件,利用代理检测的功能,投票。

  • 相关阅读:
    ProGuard代码混淆
    电影资源网站分享
    mvn高级构建
    BeanUtils对象属性copy的性能对比以及源码分析
    你可能用到的Spring工具类?
    搭建K8s集群
    IDEA部署Spring-boot到Docker容器
    搭建团队协作办公wiki (confluence)
    Linux中关闭SSH的DNS解析
    责任链异步处理设计模型
  • 原文地址:https://www.cnblogs.com/hackpig/p/1668378.html
Copyright © 2011-2022 走看看