用程序网上投票参赛获奖

来源:互联网 发布:广播电视网络客服电话 编辑:程序博客网 时间:2024/05/27 20:31

    年前佳能公司网站举办了一个星光宝贝的评选活动,通过网络投票和评委评选确定最终获奖的星光宝贝。

    一位同事正好参加了这个活动,发动大家为她千金投票,可惜通过网页投票速度很慢,佳能公司对投票数也有限制,一个IP地址24小时内只能投10张票,并且每投一次,都要输入不通的验证码。投过一次票后,我发现这些验证码是纯数字,还没有燥点,应该可以用程序自动识别,实现无人干预下的自动投票。

    没成想程序还没写到自动识别那一步呢,就发现网站居然有后门,赶紧用WireShark抓取网络数据包分析了下,原来给要发送的验证码一个空值,就可以绕过数字验证码这一关。

    虽然有后门,但是也就只能加快一点投票速度,对宝贝的排名没有一点助益。为了最大限度的增加投票量,必须利用网上丰富的代理服务器,而经过仔细分析后,我最终设计了一个架构在FreeBSD系统上的综合解决方案,这套解决方案能够24小时运行,当时正好手边有一台这样的空闲机器,就将整个系统部署在这台空闲机器上了。

    其中投票主要是分四种途径解决的:

    一:用脚本实现自动切换IP。同事借用了单位空闲的30个IP,所以我用Shell脚本控制机器每天午夜零点自动将自己的IP切换到这30个空闲ip上,每切换到一个IP投10张票。所以这种方法每天最多能投310张票。实现细节可以参看用shell脚本批量连续更改FreeBSD主机ip
   
    二:在机器上配置Privoxy,Privoxy是一个开源的匿名代理服务器网络软件,这个网络内的每台机器实质上都是一台代理服务器。配置好privoxy后,我的程序只需要把本地机器看作代理服务器,向本机IP投票就可以了。这种方法非常简单,但是经过一段时间的试用,发现平均每天只能投出不到1000张票。


    三:这种方法用Shell脚本分别从代理好助手和中国代理服务器网 采集代理服务器信息,然后启动一个进程向采集到的服务器发送投票信息,如果成功,则将该地址添加到一个列表文件中。这种方式虽然每天都会采集几百个代理服务器地址,但只有不到10%的地址有效,所以每天的投票量都超不过1000。下边就是这一部分运行时的截图:

运行截图

    用Shell脚本来提取信息并格式化非常方便,比如我曾经用来查看五大联赛计分表的脚本和下载YouTube视频的脚本。

    投票信息发出后,网站的返回信息采用了UTF-8编码,在终端是没有办法正常显示这些返回的汉字的,在Unix下的解决办法是用iconv库写一个UTF-8到GB2312的转换函数。

    四:因为第三种方法每天都会发现一些能用的代理服务器地址,并将有效地址保存到一个列表文件中,所以第四种方法就是向这个列表文件中的地址投票。

    每个代理服务器只能投10张票,并且代理服务器之间性能也有差异,有的能投10张,有的却只能投1张,因此在添加到列表中时,我根据第三种方法中成功投出的票数为每一个地址设置一个初始权值,以后如果投票失败一次,权值减1,成功一次,权值加1,如果权值为0,则自动从列表中删去该地址。而每次投票前首先对这份列表中的代理服务器按照权值排序,从权值高的代理服务器地址开始投起。
   
    事实上最终的35万张票几乎都是靠这种方法投出的,随着列表文件越来越长,在最后一段时间内,每天的投票量都稳定在10000张以上。

    这一部分运行的截图:

运行截图
   

    整个解决方案就是综合采用这四种方法进行投票的,投票部分的代码全部用C/C++完成,其余部分用Shell脚本完成。
   
    但是好景不长,很快佳能网站就封堵了后门,验证码也由纯数字改为了汉字,所以最终票数只有35万多张,并且网络投票仅是一个参考,最终结果还是评委决定的,最后同事的宝宝仅得了个三等奖。下图是同事领到的获奖证书:

 

获奖证书封面

 

 

获奖证书内容