美文网首页我爱编程
python菜鸟开发日记-基于pyhon及django进行公司打

python菜鸟开发日记-基于pyhon及django进行公司打

作者: python菜鸟 | 来源:发表于2018-04-11 09:20 被阅读123次
    打卡打卡,忘记一次扣你一天工资没商量,坑
    

    在分公司领导及同事的强烈要求下,将公司总部的打卡系统进行破解。
    破解历程:
    找出公司打卡的方式-----利用电脑每天打卡-------利用django进行手机打卡------自动打卡。

    步骤1:

    我公司利用移动的和我信app进行打卡,需要登入移动的和我信app,之后在里面进行打卡。
    分析如下:
    1.我公司的打卡系统网页直接和和我信的接口进行关联,等于是登入和我信就等于登入我公司的打卡系统。
    2.等于是打卡的cookie可能是固定的。


    利用工具就行数据抓取,我这边使用的是charle,软件教程自己百度。通过电脑共享wifi,设置代理,通过手机连接该代理,连接完成,手机打开公司软件,进行打卡,点击打开的时候抓取打卡地址,及post上传的数据,及cookie。
    抓取得信息如下:

        http打卡post地址:http://******.******.com/DaKa/DaKaHome/DaKa
        data数据:
                var data = {
                time: 2018-03-08:15:23,
                address: *****,
                jingdu: "****",
                weidu: "*****"
            };
      网页反馈的数据,通过分析js文件得到信息如下。
            反馈代码:
                    ok001: 打卡成功
                    ok002:打卡异常
                    ok003:打卡异常
     反馈的cookie地址:
          UserloginNameCookie=18179*******
    

    通过以上信息得知结果如下:

    • 上传打卡时间,地址,经度跟纬度。
    • 通过反馈的结果可以得知是否打卡成功。
    • 通过cookie得知,cookie值就是UserloginNameCookie=+手机号

    信息得到后,通过网址进行测试:
    http://www.atool.org/httptest.php
    输入网址,参数,cookie,点击发送请求,得出反馈结果为ok001。
    打卡成功,运行一段时间后发现都没有问题,

    但是每次上班下班不可能打开电脑进行打卡,特别麻烦。下面就是django打卡的开发。

    首先,利用pycharm自动创建一个django框架。
    创建完成后设置setting.py

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'dakamanager',
    ]
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    ROOT_URLCONF = 'kamanager.urls'
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    WSGI_APPLICATION = 'kamanager.wsgi.application'
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    LANGUAGE_CODE = 'zh-hans'
    
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    STATIC_URL = '/static/'
    # STATIC_ROOT = os.path.join(BASE_DIR, 'collectstatic')#此处必须,为新添加
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )
    STATIC_ROOT = os.path.join(BASE_DIR, "static_all")
    

    urls.py设置如下:

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r"^$", views.Index, name="index"),
        url(r"^login/",views.Login,name = "login"),
        #url(r"^ceshi/",views.ceshi,name = "ceshi"),
      #采用ajax异步登入
        url(r"^login_daka_ajax/",views.login_daka_ajax,name = "login_daka_ajax"),
      #采用ajax异步打卡
        #url(r"^yanzhengma_ajax/",views.yanzhengma_ajax,name = "yanzhengma_ajax"),
    ]
    

    models.py文件展示如下:

    from django.db import models
    
    # Create your models here.
    class daka(models.Model):
        phone = models.CharField(max_length=12, verbose_name="手机号", blank=True)
        cookie = models.CharField(max_length=999, verbose_name="cookie", blank=True)
        name = models.CharField(max_length=999, verbose_name="姓名", blank=True)
    

    views.py文件如下:

    from django.shortcuts import render
    
    # Create your views here.
    # -*- coding: utf-8 -*-
    from django.contrib.auth.decorators import login_required
    from django.shortcuts import render
    from django.http import HttpResponse
    # Create your views here.
    from django.template.loader import get_template
    from django.shortcuts import render
    from django.template import RequestContext, loader
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.db.models import Q
    import json
    from dakamanager import models
    from dakamanager.get_jiancha import select_cookie,POST_daka
    # Create your views here.
    def Index(request):
        return render(request,"index.html")
    def Login(request):
    #查询数据库内是否存在手机号,不存在联系管理员,存在时反馈ok,跳出打卡按钮
        ret = {"status": True, "error": None, "data": None,"cookie":True}
        if request.method == "POST":
            obj = models.daka.objects.filter(phone=request.POST.get("phone"))
            if not obj:
                ret["status"] = False
                ret["error"] = "请联系管理员"
            else:
                #查询cookie是否可用,能否利用cookie登入网站。
                if select_cookie(obj[0].cookie):
                    ret["cookie"] = True
                else:
                    ret["cookie"] = False
        print(ret)
        return HttpResponse(json.dumps(ret))
    #通过ajax异步点击打卡,打卡反馈数据,成功或者失败
    def login_daka_ajax(request):
        ret = {"status": True, "error": None, "data": None, "cookie": True}
        if request.method == "POST":
            obj = models.daka.objects.filter(phone=request.POST.get("phone"))
            if POST_daka(obj[0].cookie):
                pass
            else:
                ret["status"] = False
        print(ret)
        return HttpResponse(json.dumps(ret))
    
    

    最重要的打卡调用文件get_jiancha.py

    # -*- coding: UTF-8 -*-
    import urllib
    import http.cookiejar
    import time,re,json
    from pacong.zuobiao import zuobiao
    def Re(res,total,id = "1"):
        if id == "1":
            data = re.findall(str(res),total)
        if id == "2":
            data = re.findall(str(res),total,re.S)
        return data
    #打卡,传入cookie
    def POST_daka(cookie):
        a = zuobiao()
        URL_ROOT = 'http://******.&&&&&.com/DaKa/DaKaHome/DaKaRcsA'
        timename = time.strftime("%H:%M")
        values = {'time': str(timename), 'address': u'#########999号', "jingdu": str(a[0]), "weidu": str(a[1])}
        cookie_headers = {
            "Cookie": cookie,
        }
        URL_ROOT = 'http://******.YYYYYYY.com/DaKa/DaKaHome/DaKaRcsA'
        cookie = http.cookiejar.LWPCookieJar()
        handler = urllib.request.HTTPCookieProcessor(cookie)
        opener = urllib.request.build_opener(handler)
        postdata = urllib.parse.urlencode(values).encode()
        try:
            request = urllib.request.Request(URL_ROOT, postdata, cookie_headers)
            get_response1 = opener.open(request)
            # print(get_response1.read().decode(),type(get_response1.read().decode()))
            if Re("001",str(get_response1.read().decode())):
                ret = True
            else:
                ret = False
        except Exception as e:
            ret = False
        return ret
    #查看  cookie是否可用,可用的话 开始打卡
    def select_cookie(cookie):
        ret = True
        cookie_headers = {
            "Cookie": cookie,
        }
        cookie = http.cookiejar.LWPCookieJar()
        handler = urllib.request.HTTPCookieProcessor(cookie)
        opener = urllib.request.build_opener(handler)
    #利用cookie查询网站是否能登入
        get_url = 'http://######.########.com/DaKa/DaKaHome/DaKaRCS'
        get_request = urllib.request.Request(get_url, headers=cookie_headers)
        try:
            get_response = opener.open(get_request)
            data = get_response.read().decode()
            k = Re("<p><b>请稍等...</b></p>",data)
            if k:
                ret = True
            else:
                ret = False
        except Exception as e:
            ret = False
        return ret
    

    还有个坐标随机值zuobiao.py

    #主要让坐标进行随机生成,会在打卡位置的随机100米范围内,这样每次打卡的位置都完全不一样。
    import random
    def zuobiao():
        a = random.randint(11,99)
        b = random.randint(11,99)
        c =  format(str(*******) + str(a))
        d =format(str(*******) + str(b))
        return [c,d]
    

    index.html文件展示,里面还设计扩展手机验证码登入,但用不上。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta content="text/html" charset="utf-8">
        <title>打卡系统</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        {#    <meta name="viewport" content="width=device-width, initial-scale=1">#}
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">
    </head>
    <body>
    <style>
        .hide{
            display:none;
        }
    
    
    </style>
    
    <div>
        <div class="col-md-offset-4 col-md-4 col-xs-12" style="margin-top: 10%">
            <div class="text-center">
                <h1>打卡系统</h1>
            </div>
            <div class="center-block">
                <input type="text" class="form-control" name="phone" id="phone">
            </div>
            <div>
                <h4 class="text-center bg-danger" id="error"></h4>
            </div>
            <div class="col-md-offset-5 col-md-4 col-xs-offset-4" style="margin-top: 30px">
                <button type="submit" class="btn btn-primary" id="dengru">登     入</button>
            </div>
            <div>
                <input type="text" id="yanzhengma" class="hide">
                <button type="submit" id="yzmdaoru" class="hide">获 取 验 证 码</button>
                <button type="submit" id="dakadengru" class="hide">登入打卡系统</button>
            </div>
            <div class="col-md-offset-5 col-md-4 col-xs-offset-4" style="margin-top: 30px">
                <button type="submit" id="daka" class="hide btn btn-info ">打  卡</button>
            </div>
            <div id="app">
                <p>{{ message }}</p>
            </div>
        </div>
    </div>
    
    </body>
    <script src="/static/js/jquery.min.js"></script>
    <script>
        $("#dengru").click(function () {
            var phone = $("#phone").val()
            $.ajax({
                url: "{% url "login" %}",
                type: 'POST',
                data:{"phone":phone},
                success: function(data){
                    var obj = JSON.parse(data);
                    if(obj.status){
                        $("#dengru").addClass("hide")
    
                        if (obj.cookie){
                            $("#daka").removeClass("hide")
                            $("#error").text()
                        }else{
                            $("#yzmdaoru").removeClass("hide")
                            $("#yanzhengma").removeClass("hide")
                            $("#dakadengru").removeClass("hide")
                        }
                    }else{
                        $("#error").text(obj.error)
                    };
                }
            });
        });
        $("#daka").click(function () {
            var phone = $("#phone").val()
            $.ajax({
                url: "{% url "login_daka_ajax" %}",
                type: 'POST',
                data:{"phone":phone},
                success: function(data){
                    var obj = JSON.parse(data);
                    if(obj.status){
                        $("#error").text("打卡成功")
                    }else{
                        $("#error").text("打卡失败")
                    };
                }
            });
        });
        $("#yanzhengma").click(function () {
            var phone = $("#phone").val()
            $.ajax({
                url: "{% url "yanzhengma_ajax" %}",
                type: 'POST',
                data:{"phone":phone},
                success: function(data){
                    var obj = JSON.parse(data);
                    if(obj.status){
                        $("#yzmdaoru").addClass("hide")
                    }else{
    
                    };
                }
            });
        });
    
    </script>
    </html>
    

    关键代码基本已经完成,上图。用的是bootstrap,所以会根据手机分辨率进行自动响应,以后可以很happy的在家里打卡在上班啦。


    登入界面 打卡界面
    打卡成功界面

    后期扩展:
    这个功能基本实现啦。但也有很多缺陷,比如忘记啦打卡。
    后期有空扩展下:

    • 方法一:
      直接利用django celery每天定时任务打卡,这个功能很容易实现,傻瓜化,但哪天家里的服务器挂啦都不知道,导致没打卡,不合适。
    • 方法二(还是利用celery,有空实现下,这个也简单):
      每天在上班的前十分钟对打卡记录进行检测,检测没打卡,则自动补上打卡记录。只要每天打卡时自动生成一个时间。并且检测的时候对时间进行比对,确认异常的进行打卡。
    利用定时打卡,确实好用,又出啦一个关键的问题,定时打卡肯定不能在周末或者过节进行打卡啊。这个需要利用其他网站上的日历,对每天的日历信息进行抓取,确认今天是否存在(休,节等等关键字),存在则不进行打卡检测。

    相关文章

      网友评论

        本文标题:python菜鸟开发日记-基于pyhon及django进行公司打

        本文链接:https://www.haomeiwen.com/subject/eapnhftx.html