投票系统——爬虫+容器克隆技术

序:昨天是所谓的单身狗节,作为一名不折不扣的程序员...

我想找点乐子,我找了实验室的好基友(单身狗程序员一只)准备商讨出去浪的想法,刚想发信息,一想最近工资没发,钱不够不能出去浪啊,寻思着找啥乐子,突然一个灵感划过脑海,要不做个校花评选系统找理工的校花吧,但是照片哪来呢,大一时天真的认为让他们自己交出照片,想想这么逗比的行为不现实了,那么只能做一会hacker了,hack什么呢,教务系统把,当即发信息联系了实验室的老朋友,

约好下午一起hack教务系统,毕竟我一个写网站爬数据恐怕不够玩,带上人总是快一点的,python爬图就靠他了。

刚开始,我选择最简单的方法,直接查看自己的图片路径然后通过请求url获取别人的,但是万万没想到正方还是做安全了这一点,他把图片写入了aspx文件,并且赋予了权限,也就是自己登录后只能查看自己的图片,但转念一想也许能找到这个图片文件夹目录呢,也许这个目录在网站目录下并且不要求权限呢,试探了一下,在url域名下加上了"/uploads/",不得了果然有这样的文件夹,但IIS拒绝列出文件树,万不得已,我特地上网下了正方教务系统的源码,来查看他的命名存放规则,不看不知道,一看吓一跳,方正教务系统源码我只想用一个字去评价“乱!”,简直乱七八糟,各种无法理解的命名aspx文件,各种没有目录安放的aspx,我的天!怎么看?我放弃了。

基友喊我去吃晚饭,我在刚在抱怨正方教务系统的网站乱的不堪入目,他突然提出了进入学校信息门户这一想法,对啊,也许行呢,吃完回头试试吧!

果然又是不试不知道,一试吓一跳,一样使用后台文件访问图片,但不同的是,文件为jsp而且并没有加权限,更换学号轻松扫别人的图片了,立刻开工!一个爬图一个拟网站

爬图python在这儿:

#!/usr/bin/env python

# coding: utf-8
import requests
import os
def getStuNoList(class_info,number):
    stu_list = []
    for i in range(1,number):
        stu_list.append(class_info + ('%02d' % i))
    return stu_list
def getImgContent(url):
    header_info = {
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0',
        'Host': 'portal.cslg.cn',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
        'Accept-Encoding': 'gzip, deflate',
        'Cookie': 'safedog-flow-item=34F163E4F93347D4A1E6DB385029DCE9; JSESSIONID=0A1BBF33679FC4B484FEBD011273F8B0',
        'Connection': 'keep-alive',
        'Cache-Control': 'max-age=0',
        'Content-Type': 'image/gif;charset=GB2312'
    }
    img = requests.get(url,headers = header_info,verify=False)
    return img.content
def downLoadImg(class_num,stu_list):
    url_info = 'http://portal.cslg.cn//showImg.do?yhm='
    if not os.path.exists('./pic/' + class_num):
        os.mkdir('./pic/' + class_num)
    for no in stu_list:
        url = url_info + no
        if getImgContent(url):
            print('download %s' % no)
            f = open('./pic/%s/%s.jpg' % (class_num,no), 'wb')
            f.write(getImgContent(url))
            if os.path.getsize('./pic/%s/%s.jpg' % (class_num,no))/1024.0 < 3.0:
                os.remove('./pic/%s/%s.jpg' % (class_num,no))
                print('remove file %s.jpg' % no)
if __name__ == '__main__':
    class_num = '0921132'        //班级号
    stu_number = 40                //学生数目
    stu_list = getStuNoList(class_num,stu_number+1)
    downLoadImg(class_num,stu_list)

上面这段Python代码是最初的原型,事实上,在爬图片以后再用php+表单的方式存入数据库是件恶心的事情,之所以发明计算机是为了免除做循环这种事的劳烦,所以第二天早上,我打算亲自修改这段代码,实现存入数据库的功能,第二版本的爬虫软件是可以边下载边删除不存在照片还可以写入数据库,只需要输入三大变量,第一个女生学号,年级,还有需要存入的表库名附上代码,自己看下,由于我不会Python,代码质量不高请谅解吧

基本思想是,首先取得头信息,必须要有自己已经登录的cookie信息从而使python有访问图片的权限,然后需要两个参数,班级号,学生数目,通过循环学生数目来获得所有图片的地址(因为图片是以学生号命名的jpg后缀文件,非常简单),并下载。

接下来只要不停vim那个python文件并执行,获取一个个学院的图片就是轻而易举的事儿了,然后我们开始写网站,需要用到thinkphp框架

具体前后端什么的代码思想我就不扯了,重点是投票系统如何反刷票

因为以前开发过投票系统吃过一次苦头(被别人的python一秒刷了10000多)

随机投票:

最白痴的办法,肯定所有程序员都想得到,我们直接从MySQL rand() select十条数据即可,这样把他们assign到前端,然后表单记录id,返回id后再指定setInc()给字段加1,但是这种方法只要一段python或者js,写个for循环不停的向同一个方法提交同一个id的话,就能指定刷票了,一秒钟破万不是梦,还可以ddos占用服务器资源,导致服务器拒绝访问,这很糟糕啊,而且这个投票系统不需要登录注册什么的,更加让黑客们钻了空子!

解决办法:用容器随机的思想,举个例子:给你一缸的水,给别人盛水,用原来的方法,我让你们用户随机从中盛一碗尝一口,再吐回去,有人就会一直盛同一个地方的水吐回去(真恶心,我都佩服自己的想法),那么加上了容器呢,我作为管理员,不许你们随便取水吐水,来的每一个用户,我给你们盛,每人随机十碗水,自己再从中挑一碗,然后喝完吐回去。

在实际项目中,我们可以用session来实现,第一安全性高,第二针对不同的用户有不同的随机人物,thinkphp实现非常简单,方法如下:

$obj = D('User');
        //筛选那女,由于0会产生数据类型转换错误故而男=2,女=1
        if($sex === 2){
            //只看男
            $where['sex'] = 1;
            $rands = $obj->where($where)->order('RAND() LIMIT 10')->select();
        }else if($sex === 1){
            //只看女
            $where['sex'] = 0;
            $rands = $obj->where($where)->order('RAND() LIMIT 10')->select();
        }else{
            $where['sex'] = 1;
            $boy = $obj->where($where)->order('RAND() LIMIT 10')->select();
            $where['sex'] = 0;
            $girl = $obj->where($where)->order('RAND() LIMIT 10')->select();
            $rands=array_merge($boy,$girl); //男女都有就合并
        }
        /*把随机数据存储到个人session中,不允许修改其他人的,防止刷票*/
        session('rands',null); //在此之前先清空session
        session('rands',$rands);
        $this->assign('rands',$_SESSION['rands']);
        $this->assign('p_l',$where['level']);
        $this->assign('p_s',$sex);
        $this->display();

注意,这段代码重点在下面的session[‘rands’],存入session后,只可以吧session传入前端,也就是我刚刚所说的控制容器,我只给你我随机挑个你的,不允许你自己取到!

这样前端返回的表单数据,也返回的session[‘rands’]数组的索引1,2,3,4.......;有多少就多少,我们也要控制别人恶意刷session数组,以下代码是投票存入数据库的方法:

 public function vote(){
        //取得表单投票两个重要数据
        $id = intval($_POST['vote_id']);
        $verify = trim($_POST['verify']);
        if(isset($_POST['p_level']) && $_POST['p_level']!="")
            $p_l = intval($_POST['p_level']);

        if(empty($verify)){
            $this->error('验证码不能为空!');
        }
        if(session('verify') != md5($verify)) {
            $this->error('验证码错误!');
        }

        /*检查随机session的存在,范围*/
        if(!session("?rands") || $id>sizeof($_SESSION['rands']) || $id<0){
            $this->redirect('Index/index', array('cate_id' => 2), 5, 'ERROR:投票超出范围...或长时间未操作');
        }

        //获取在session中的实际数据
        $sid = $_SESSION['rands'][$id]['sid'];
        $flag = $this->do_vote_one($sid);

        //清空当前用户session
        session('rands',null);

        if($flag)
            $this->success("投票成功!");
        else
            $this->error("数据错误:投票失败!");
    }
   public function do_vote_one($sid){
        $obj = D("User");
        $where['sid'] = $sid;
        $obj_id = $obj->where($where)->setInc('vote');
        if($obj_id){
            //最后一次投票时间修改
            $obj->where($where)->setField('vote_time',NOW_TIME);

            //记录投票日志
            $stu_id = $obj->where($where)->getField("student_id");
            $this->record_vote($stu_id);
            return true;
        }else{
            return false;
        }
    }

到此为止,我们的随机投票区的随机容器反刷票技术已经实现。

 

接下来还有一个搜索投票如何反刷票呢,一开始,我是照搬照抄,任然打算用session的方式,把投过的人记录下次数,然后一旦扫到这个session投票超过一定次数就禁止了,但是万万没有想到啊,这次试用颠覆了我对session的看法,以前看书和百度都说,session是保存在服务端的,具有较cookie更高的安全性,于是我想保存在服务端,你们就改不了session对吧,但是session是改不掉,却可以放弃或者说删除,接下来我要描述一个session的特点:

首先session确实保护在服务端,客户端无法修改,但是session和前端的cookie是有交际的,这么说,就是即使你代码完全用了session根本没想用cookie,cookie还是会在前端产生的,为什么呢?

因为session是个会话,要知道首先http是无状态的,必须要有客户发送请求才能收到服务器的消息,那么,为了维持这个会话,服务端会把session的id保存在前端cookie当中,用于前端返回的时候识别这个会话是否是刚刚那个,这样只要我们清空了浏览器的cookie,后端服务器会以为是新用户上来了,建立新的session发送新的cookie给浏览器,这样一来,懂点电脑的人就会利用这一点,刷完票数后可以清空cookie重新进行投票,而服务器只会傻傻的把他当成新用户,不拒绝!

 

综上考虑,只有一点能解决,但并不完美,起码比清空cookie来的难做到一点,那就是指定ip只能12小时刷10票特定票,怎么做呢?很简单,利用数据库存储用户信息,新建一个vote_limit表,把ip,时间,设定到MySQL,ip要设定为unique,存在的就直接修改,不添加,不然表会炸了!实现代码如下:

public function vote_one(){

        $ip = get_client_ip();

        if(isset($_POST['vote_id']) && trim($_POST['vote_id'])!=""){

            $sid = trim($_POST['vote_id']);

            //获取搜索投票数据表

            $obj = D("Vote_limit");

            $where['ip'] = $ip;

            $vsearch = $obj->where($where)->find();

            if($vsearch){

//大于12个小时重置,允许继续投票

                if((NOW_TIME-$vsearch['time']) > 12*3600){

                    $data = array('vote'=>0,'time'=>NOW_TIME); //重置时间,票数

                    $obj->where($where)->setField($data);

                    $vflag = $this->do_vote_one($sid);

                }else{

                    if($vsearch['vote']>=10)

                        $this->error("12小时内特定投票,搜索以及top10投票,只能干十次~");

                    else

                        $vflag = $this->do_vote_one($sid);

                }

            }else{

                //不存在这个ip就添加,并且初始化票数,时间

                $data['ip'] = $ip;

                $data['vote'] = 0;

                $data['time'] = NOW_TIME;

                $obj->add($data);

                $vflag = $this->do_vote_one($sid);

            }

            if($vflag){

                $obj->where($where)->setInc("vote");

                $this->success("投票成功!");

            }else{

                $this->success("投票失败,数据错误!");

            }

        }else{

            $this->error("投票对象呢?");

        }

}

 好了一切ok,万事具备,剩下的代码都是些接收表单发布新信息了,很简单,针对这个校花校草投票系统,我只是讲述一下两大反刷票的技术,这次黑了学校图库的故事就讲到这儿了,技术和代码会全部公开,网站火玩之后我就下线,毕竟黑客也有职业道德的,恩!

 

小成绩:

 

 

 

 

 

转载于:https://www.cnblogs.com/devilyouwei/p/6336785.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python是一种强大的编程语言,其应用领域广泛,包括了数据处理、数据挖掘和爬虫等方面。在这其中,Python的爬虫技术已经成为数据获取和处理的重要建设板块。同时,数据库是存储和管理数据的基本方式,其由于高效、安全和稳定等特性而被广泛应用在各个领域中。 在Python的Web框架中,Flask是一种极为流行的工具,其为开发Web应用提供了很多便利,尤其适合小型和中型的Web应用开发。在Flask框架中,开发者可以使用Python编写各种功能,如路由、拦截器、数据验证、数据渲染等等。 在就业系统的建设过程中,Python和Flask可以负责Web应用的开发。爬虫技术则可以用于从多个网站获取招聘信息,并将其存储在数据库中,包括职位、公司、薪资、职位要求等信息。数据库技术则可以用于数据的管理和访问,包括SQL Server、MySQL、PostgreSQL等多种方式。 总而言之,Python、Flask、爬虫和数据库技术可以结合起来,为企业提供高效、准确和可靠的招聘数据,提高招聘质量和效率。 ### 回答2: Python是一门非常流行的编程语言,被广泛应用于爬虫、数据处理、Web开发等领域。在Web开发方面,Flask是一种轻量级的Web应用框架,易于上手,同时也有很好的扩展性和灵活性。 爬虫是将互联网上的数据爬取下来,并进行处理和分析的过程。Python中有很多爬虫框架,比如Scrapy、Beautiful Soup等。而在爬取数据后,需要对其进行存储和管理,这时数据库就成了必不可少的一环。Python中常用的数据库有MySQL、SQLite、PostgreSQL等。 在就业系统中,我们可以利用爬虫来获取各种招聘信息,并将其储存在数据库中,方便后续查询和管理。Flask则可以搭建一个基于Web的简单就业系统,可以实现用户注册、登录、简历管理、招聘信息查看等功能。 总的来说,Python、Flask、爬虫和数据库在就业系统中的应用,提高了数据的收集和管理效率,同时也提供了更加丰富、便捷的招聘信息查询和管理方式,帮助求职者和企业更好地完成匹配和招聘。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值