用python的Django框架写大乐透数据采集预测系统

何以解忧/唯有暴富/用代码实现人生的致富理想-大乐透

资源下载

1.数据采集的实现

#-*-coding:utf-8-*-
import requests
import re
from lxml import etree
import datetime
import requests
import json
def geturl(URL="http://datachart.500.com/dlt/history/newinc/history.php?limit=3000"):
    try:
        data = requests.get(URL).content.decode('utf-8')
        return data
    except:
        data = requests.get(URL).content.decode('gb2312')
        return data
    else:
        data = requests.get(URL).content.decode('gbk')
        return data

几行代码,获取所有的大乐透数据[好像实际只有2010条左右的数据]

2.搭建django项目

创建项目框架

django-admin startproject lottery 

创建app模块

python manage.py startapp dlt

创建一个文件夹管理封装的其他工具函数

---LOTTERY
   |---lottery
       |---asgi.py
       |---settings.py
       |---urls.py
       |---wsgi.py
   |---dlt
       |---admin.py
       |---tests.py
       |---apps.py
       |---models.py
       |---serializers.py
       |---views.py
       |---tool[工具类文件夹]
           |---getnum.py
           |---guess.py

3.编辑settings.py进行项目的相关设置

INSTALLED_APPS:注册创建好的模块包,如果创建多个要在这里写明

INSTALLED_APPS = [...
   'rest_framework',
   'rest_framework.authtoken',
   'dlt' ,#自己创建的app模块
]

ALLOWED_HOSTS:让局域网内的用户能够访问

ALLOWED_HOSTS = ["*"]

上传文件:要给上传文件的地方配置一个路径

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

LANGUAGE_CODE = ‘en-us’ :修改下admin管理中文

LANGUAGE_CODE = 'zh-hans'

如果不使用本地数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库名字',
        'USER': 'root',
        'PASSWORD': '数据库密码',
        'HOST': '数据库路径:127.0.0.1',
        'PORT': '数据库端口',
    }
}

4.设计整个django项目的models结构

from django.db import models
from django.contrib import admin
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.conf import settings
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)
class LotteryData(models.Model):
    """
    每期开奖数据
    """
    order = models.PositiveIntegerField(verbose_name='期号', help_text='期号(PositiveIntegerField)', blank=True,null=True)
    red1 = models.PositiveIntegerField(verbose_name='红球1', help_text='红球1(PositiveIntegerField)', blank=True,null=True)
    red2 = models.PositiveIntegerField(verbose_name='红球2', help_text='红球2(PositiveIntegerField)', blank=True,null=True)
    red3 = models.PositiveIntegerField(verbose_name='红球3', help_text='红球3(PositiveIntegerField)', blank=True,null=True)
    red4 = models.PositiveIntegerField(verbose_name='红球4', help_text='红球4(PositiveIntegerField)', blank=True,null=True)
    red5 = models.PositiveIntegerField(verbose_name='红球5', help_text='红球5(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.PositiveIntegerField(verbose_name='蓝球1', help_text='蓝球1(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.PositiveIntegerField(verbose_name='蓝球2', help_text='蓝球2(PositiveIntegerField)', blank=True,null=True)
    date = models.CharField(max_length=20, verbose_name='开奖日期', help_text='开奖日期(CharField)', blank=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '开奖数据'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return str(self.order)+'期:'+str(self.red1)+' ' +str(self.red2)+' ' +str(self.red3)+' ' +str(self.red4)+' ' +str(self.red5)+'  ' +str(self.blue1)+' ' +str(self.blue2)+' 开奖时间' +str(self.date)
@admin.register(LotteryData)
class LotteryDataAdminModel(admin.ModelAdmin):
    """
    注册开奖数据到admin系统进行管理
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2','date')
    # 搜索框
    search_fields=('id','order','date')
class LotteryDataForecast(models.Model):
    """
    每期开奖预测数据
    """
    order = models.ForeignKey("LotteryData",verbose_name='上期', help_text='上期(ForeignKey)', blank=True,null=True, on_delete=models.PROTECT)
    red1 = models.PositiveIntegerField(verbose_name='红球1', help_text='红球1(PositiveIntegerField)', blank=True,null=True)
    red2 = models.PositiveIntegerField(verbose_name='红球2', help_text='红球2(PositiveIntegerField)', blank=True,null=True)
    red3 = models.PositiveIntegerField(verbose_name='红球3', help_text='红球3(PositiveIntegerField)', blank=True,null=True)
    red4 = models.PositiveIntegerField(verbose_name='红球4', help_text='红球4(PositiveIntegerField)', blank=True,null=True)
    red5 = models.PositiveIntegerField(verbose_name='红球5', help_text='红球5(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.PositiveIntegerField(verbose_name='蓝球1', help_text='蓝球1(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.PositiveIntegerField(verbose_name='蓝球2', help_text='蓝球2(PositiveIntegerField)', blank=True,null=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '开奖预测数据'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return str(self.order.order)+'期下一期预测数据:'+str(self.red1)+' ' +str(self.red2)+' ' +str(self.red3)+' ' +str(self.red4)+' ' +str(self.red5)+'  ' +str(self.blue1)+' ' +str(self.blue2)
@admin.register(LotteryDataForecast)
class LotteryDataForecastAdminModel(admin.ModelAdmin):
    """
    注册开奖预测数据到admin系统进行管理
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2')
    # 搜索框
    search_fields=('id','order')
class Difference(models.Model):
    """
    每期开奖预测数据和真实开奖差异
    """
    order = models.ForeignKey("LotteryData",verbose_name='上期', help_text='上期(ForeignKey)', blank=True,null=True, on_delete=models.PROTECT)
    red1 = models.IntegerField(verbose_name='红球1差异', help_text='红球1差异(PositiveIntegerField)', blank=True,null=True)
    red2 = models.IntegerField(verbose_name='红球2差异', help_text='红球2差异(PositiveIntegerField)', blank=True,null=True)
    red3 = models.IntegerField(verbose_name='红球3差异', help_text='红球3差异(PositiveIntegerField)', blank=True,null=True)
    red4 = models.IntegerField(verbose_name='红球4差异', help_text='红球4差异(PositiveIntegerField)', blank=True,null=True)
    red5 = models.IntegerField(verbose_name='红球5差异', help_text='红球5差异(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.IntegerField(verbose_name='蓝球1差异', help_text='蓝球1差异(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.IntegerField(verbose_name='蓝球2差异', help_text='蓝球2差异(PositiveIntegerField)', blank=True,null=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '开奖和预测数据之前的差异'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return self.order
@admin.register(Difference)
class DifferenceAdminModel(admin.ModelAdmin):
    """
    注册开奖预测数据到admin系统进行管理
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2')
    # 搜索框
    search_fields=('id','order')
class ChangeNum(models.Model):
    """
    本期比上期差值
    """
    order = models.ForeignKey("LotteryData",verbose_name='本期', help_text='本期(ForeignKey)', blank=True,null=True, on_delete=models.PROTECT)
    red1 = models.IntegerField(verbose_name='红球1比上期', help_text='红球1比上期(PositiveIntegerField)', blank=True,null=True)
    red2 = models.IntegerField(verbose_name='红球2比上期', help_text='红球2比上期(PositiveIntegerField)', blank=True,null=True)
    red3 = models.IntegerField(verbose_name='红球3比上期', help_text='红球3比上期(PositiveIntegerField)', blank=True,null=True)
    red4 = models.IntegerField(verbose_name='红球4比上期', help_text='红球4比上期(PositiveIntegerField)', blank=True,null=True)
    red5 = models.IntegerField(verbose_name='红球5比上期', help_text='红球5比上期(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.IntegerField(verbose_name='蓝球1比上期', help_text='蓝球1比上期(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.IntegerField(verbose_name='蓝球2比上期', help_text='蓝球2比上期(PositiveIntegerField)', blank=True,null=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '比上期变化'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name    #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return self.order
@admin.register(ChangeNum)
class ChangeNumAdminModel(admin.ModelAdmin):
    """
    本期比上期差值
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2')
    # 搜索框
    search_fields=('id','order')
class ChangeNumMean(models.Model):
    """
    差值均值
    """
    order = models.ForeignKey("LotteryData",verbose_name='本期', help_text='本期(ForeignKey)', blank=True,null=True, on_delete=models.PROTECT)
    red1 = models.FloatField(verbose_name='红球1平均变化', help_text='红球1平均变化(PositiveIntegerField)', blank=True,null=True)
    red2 = models.FloatField(verbose_name='红球2平均变化', help_text='红球2平均变化(PositiveIntegerField)',blank=True,null=True)
    red3 = models.FloatField(verbose_name='红球3平均变化', help_text='红球3平均变化(PositiveIntegerField)',blank=True,null=True)
    red4 = models.FloatField(verbose_name='红球4平均变化', help_text='红球4平均变化(PositiveIntegerField)',blank=True,null=True)
    red5 = models.FloatField(verbose_name='红球5平均变化', help_text='红球5平均变化(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.FloatField(verbose_name='蓝球1平均变化', help_text='蓝球1平均变化(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.FloatField(verbose_name='蓝球2平均变化', help_text='蓝球2平均变化(PositiveIntegerField)',blank=True,null=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '差值均值'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name    #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return self.order
@admin.register(ChangeNumMean)
class ChangeNumMeanAdminModel(admin.ModelAdmin):
    """
    注册开奖预测数据到admin系统进行管理
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2')
    # 搜索框
    search_fields=('id','order')
class ChangeNumSum(models.Model):
    """
    差值均值
    """
    order = models.ForeignKey("LotteryData",verbose_name='本期', help_text='本期(ForeignKey)', blank=True,null=True, on_delete=models.PROTECT)
    red1 = models.IntegerField(verbose_name='红球1变化合计', help_text='红球1变化合计(PositiveIntegerField)', blank=True,null=True)
    red2 = models.IntegerField(verbose_name='红球2变化合计', help_text='红球2变化合计(PositiveIntegerField)',blank=True,null=True)
    red3 = models.IntegerField(verbose_name='红球3变化合计', help_text='红球3变化合计(PositiveIntegerField)',blank=True,null=True)
    red4 = models.IntegerField(verbose_name='红球4变化合计', help_text='红球4变化合计(PositiveIntegerField)',blank=True,null=True)
    red5 = models.IntegerField(verbose_name='红球5变化合计', help_text='红球5变化合计(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.IntegerField(verbose_name='蓝球1变化合计', help_text='蓝球1变化合计(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.IntegerField(verbose_name='蓝球2变化合计', help_text='蓝球2变化合计(PositiveIntegerField)',blank=True,null=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '变化合计'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name    #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return self.order
@admin.register(ChangeNumSum)
class ChangeNumSumAdminModel(admin.ModelAdmin):
    """
    注册开奖预测数据到admin系统进行管理
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2')
    # 搜索框
    search_fields=('id','order')
class Reptiles(models.Model):
    """
    爬虫执行模型:用于执行爬虫程序
    """
    title = models.CharField(max_length=255, verbose_name='记录操作', help_text='记录操作', blank=True)
    class Meta:
        ordering = ['-id']
        verbose_name = '爬虫执行'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title
@admin.register(Reptiles)
class ReptilesAdminModel(admin.ModelAdmin):
    """
    爬虫执行
    """
    list_per_page = 50
    list_display = ('id','title')
    search_fields=('id','title',)
class Guess(models.Model):
    """
    预测模型:用于执行预测程序
    """
    title = models.CharField(max_length=255, verbose_name='记录操作', help_text='记录操作', blank=True)
    # begin = models.CharField(max_length=255, verbose_name='开始时间 格式:14:05', help_text='开始时间 格式:14:05', blank=True)
    class Meta:
        ordering = ['-id']
        verbose_name = '预测执行'
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.title
@admin.register(Guess)
class GuessAdminModel(admin.ModelAdmin):
    """
    预测执行
    """
    list_per_page = 50
    list_display = ('id','title')
    search_fields=('id','title',)
class LotteryDataForecast2(models.Model):
    """
    每期开奖预测数据
    """
    order = models.ForeignKey("LotteryData",verbose_name='上期', help_text='上期(ForeignKey)', blank=True,null=True, on_delete=models.PROTECT)
    red1 = models.IntegerField(verbose_name='红球1', help_text='红球1(PositiveIntegerField)', blank=True,null=True)
    red2 = models.IntegerField(verbose_name='红球2', help_text='红球2(PositiveIntegerField)', blank=True,null=True)
    red3 = models.IntegerField(verbose_name='红球3', help_text='红球3(PositiveIntegerField)', blank=True,null=True)
    red4 = models.IntegerField(verbose_name='红球4', help_text='红球4(PositiveIntegerField)', blank=True,null=True)
    red5 = models.IntegerField(verbose_name='红球5', help_text='红球5(PositiveIntegerField)', blank=True,null=True)
    blue1 = models.IntegerField(verbose_name='蓝球1', help_text='蓝球1(PositiveIntegerField)', blank=True,null=True)
    blue2 = models.IntegerField(verbose_name='蓝球2', help_text='蓝球2(PositiveIntegerField)', blank=True,null=True)
    class Meta:
        ordering = ['-id']    #排序
        verbose_name = '开奖预测数据'            #表示要显示的应用模块的中文名        
        verbose_name_plural = verbose_name #表示已经是复数形式不用再自动加S
    def __str__(self):
        # 返回部门名称
        return self.order
@admin.register(LotteryDataForecast2)
class LotteryDataForecast2AdminModel(admin.ModelAdmin):
    """
    注册开奖预测数据到admin系统进行管理
    """
    # 添加分页
    list_per_page = 100
    # 列表页展示的字段
    list_display = ('id','order','red1','red2', 'red3', 'red4', 'red5', 'blue1','blue1','blue2')
    # 搜索框
    search_fields=('id','order')

5.设计整个django项目的序列化结构serializers

from django.contrib.auth.models import User, Group
from django.utils.timezone import now
from rest_framework import mixins
from rest_framework import serializers
#导入在models层写的数据模型
from dlt.models import LotteryData,LotteryDataForecast,Difference,Reptiles,Guess,ChangeNum,ChangeNumMean,ChangeNumSum,LotteryDataForecast2
class LotteryDataSerializer(serializers.ModelSerializer):
    """
    LotteryData模型的序列化器
    """
    class Meta:
        model = LotteryData                        #声明模型
        fields = '__all__'                         #声明序列化字段
class LotteryDataForecastSerializer(serializers.ModelSerializer):
    """
    LotteryDataForecast模型的序列化器
    """
    class Meta:
        model = LotteryDataForecast                        #声明模型
        fields = '__all__'                         #声明序列化字段
class LotteryDataForecast2Serializer(serializers.ModelSerializer):
    """
    LotteryDataForecast2模型的序列化器
    """
    class Meta:
        model = LotteryDataForecast2                       #声明模型
        fields = '__all__'                         #声明序列化字段
class DifferenceSerializer(serializers.ModelSerializer):
    """
    Difference模型的序列化器
    """
    class Meta:
        model = Difference                        #声明模型
        fields = '__all__'                         #声明序列化字段
class ChangeNumSerializer(serializers.ModelSerializer):
    """
    ChangeNum模型的序列化器
    """
    class Meta:
        model = ChangeNum                        #声明模型
        fields = '__all__'                         #声明序列化字段
class ChangeNumMeanSerializer(serializers.ModelSerializer):
    """
    ChangeNumMean模型的序列化器
    """
    class Meta:
        model = ChangeNumMean                        #声明模型
        fields = '__all__'                         #声明序列化字段
class ChangeNumSumSerializer(serializers.ModelSerializer):
    """
    ChangeNumSum模型的序列化器
    """
    class Meta:
        model = ChangeNumSum                        #声明模型
        fields = '__all__'                         #声明序列化字段
class ReptilesSerializer(serializers.ModelSerializer):
    """
    爬虫执行序列化器
    """
    class Meta:
        model = Reptiles                            #声明模型
        fields = '__all__'                         #声明序列化字段
class GuessSerializer(serializers.ModelSerializer):
    """
    预测执行序列化器
    """
    class Meta:
        model = Guess                            #声明模型
        fields = '__all__'                         #声明序列化字段

6.根据需要编写自己的工具函数

#获取数据
#-*-coding:utf-8-*-
import requests
import re
from lxml import etree
import datetime
import requests
import json
def geturl(URL="http://datachart.500.com/dlt/history/newinc/history.php?limit=3000"):
    try:
        data = requests.get(URL).content.decode('utf-8')
        return data
    except:
        data = requests.get(URL).content.decode('gb2312')
        return data
    else:
        data = requests.get(URL).content.decode('gbk')
        return data
#概率分布做机器训练
import numpy as np
import pandas as pd
import math
#导入在models层写的数据模型
from dlt.models import LotteryData,LotteryDataForecast,ChangeNum

#2.计算数据分布
def distribution(maxnum):
    data = {}
    #按照7个球,35位号码,生成一个最大二维表
    #给这个二维表存入每次开奖对比上次的差异
    for order in range(7):
        for number in range(1, 36):
            data[order,number] = []
            for num in range(1,maxnum):
                thisobj = LotteryData.objects.filter(id = num).first()
                nextobj = LotteryData.objects.filter(id = num+1).first()
                thisdata = 0
                if order==0:
                    thisdata = thisobj.red1
                    if thisdata == number:
                        diff = nextobj.red1-thisdata
                        data[order,number].append(diff)
                elif order==1:
                    thisdata = thisobj.red2
                    if thisdata == number:
                        diff = nextobj.red2-thisdata
                        data[order,number].append(diff)
                elif order==2:
                    thisdata = thisobj.red3
                    if thisdata == number:
                        diff = nextobj.red3-thisdata
                        data[order,number].append(diff)
                elif order==3:
                    thisdata = thisobj.red4
                    if thisdata == number:
                        diff = nextobj.red4-thisdata
                        data[order,number].append(diff)
                elif order==4:
                    thisdata = thisobj.red5
                    if thisdata == number:
                        diff = nextobj.red5-thisdata
                        data[order,number].append(diff)
                elif order==5:
                    thisdata = thisobj.blue1
                    if thisdata == number:
                        diff = nextobj.blue1-thisdata
                        data[order,number].append(diff)
                elif order==6:
                    thisdata = thisobj.blue2
                    if thisdata == number:
                        diff = nextobj.blue2-thisdata
                        data[order,number].append(diff)
    #设置几个全局变量,在循环内部变化赋值
    enlarge = {}    # 增大的次数
    reduce = {}     # 减小的次数
    enlarge_num = {}# 每个数字增大的概率
    enlarge_dict = {}
    da = {}
    jian = {}
    da1 = []
    jian1 = []
    dict21 = []
    #遍历这个三维差异表
    for order,number in data.items():
        enlarge[order] = 0
        reduce[order] = 0
        da[order] = 0
        jian[order] = 0
        #计算增减的次数
        for diff in number:
            if diff > 0:
                enlarge[order] += 1
            elif diff <0:
                reduce[order] += 1
        enlarge_num[order] = round(enlarge[order] / (reduce[order] + enlarge[order] + 1), 4)
        for set_diff in set(number):
            if set_diff > 0:
                enlarge_dict[order, set_diff] = (round(number.count(set_diff) / enlarge[order], 4)) * set_diff
                da[order] += enlarge_dict[order, set_diff]
                '''
                这是基于首先判断当前期每个数字增大或减小概率哪个大
                数值大的进一步细化,即将具体增大或减小的值得概率当
                成权重再分别与之对应值相乘,在全部相加为下一次预测值
                '''
            elif set_diff < 0:
                enlarge_dict[order, set_diff] = (round(number.count(set_diff) / reduce[order], 4)) * set_diff
                jian[order] += enlarge_dict[order, set_diff]
            elif set_diff == 0:
                enlarge_dict[order, set_diff] = 0  # 两次数字不变
    for n, m, l in zip(da.values(), jian.values(), enlarge_num.values()):
        da1.append(n)  # 原来是字典现在要将其弄成矩阵
        jian1.append(m)
        dict21.append(l)
    da1 = np.array(da1).reshape(7, 35)
    jian1 = np.array(jian1).reshape(7, 35)
    dict21 = np.array(dict21).reshape(7, 35)
    return da1, jian1, dict21

def predict(maxnum):
    da1, jian1, dict21 = distribution(maxnum)
    # predict = np.zeros(7)
    predict = np.zeros(7)
    Thisobj = LotteryData.objects.filter(id = maxnum).first()
    DataForecast = LotteryDataForecast()
    DataForecast = LotteryDataForecast.objects.filter(order__id=maxnum).first()
    if DataForecast == None:
        DataForecast = LotteryDataForecast()
        DataForecast.order = LotteryData.objects.all().order_by('-id') .first()
    for order in range(7):
        predict[order] = 0
        for number in range(1, 36):
            if order == 0:
                if Thisobj.red1 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.red1 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.red1 + jian1[order][number - 1])
                    DataForecast.red1 = int(predict[order])
            elif order == 1:
                if Thisobj.red2 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.red2 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.red2 + jian1[order][number - 1])
                    DataForecast.red2 = int(predict[order])
            elif order == 2:
                if Thisobj.red3 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.red3 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.red3 + jian1[order][number - 1])
                    DataForecast.red3 = int(predict[order])
            elif order == 3:
                if Thisobj.red4 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.red4 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.red4 + jian1[order][number - 1])
                    DataForecast.red4 = int(predict[order])
            elif order == 4:
                if Thisobj.red5 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.red5 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.red5 + jian1[order][number - 1])
                    DataForecast.red5 = int(predict[order])
            elif order == 5:
                if Thisobj.blue1 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.blue1 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.blue1 + jian1[order][number - 1])
                    DataForecast.blue1 = int(predict[order])
            elif order == 6:
                if Thisobj.blue2 == number:
                    if dict21[order][number - 1] > 0.5:
                        predict[order] = round(Thisobj.blue2 + da1[order][number - 1])
                    elif dict21[order][number - 1] < 0.5:
                        predict[order] = round(Thisobj.blue2 + jian1[order][number - 1])
                    DataForecast.blue2 = int(predict[order])
    DataForecast.save()
    return predict

7.在views层调用写好的函数

#-*-coding:utf-8-*-
import requests
import re
from lxml import etree
import datetime
import requests
import json

from rest_framework.viewsets import ModelViewSet
from django_filters.rest_framework import DjangoFilterBackend
from django.db.models import Q
from django.db.models import Count
from django.db.models import Q
from django.utils.timezone import now
from django.utils import timezone
from django.contrib.auth.models import User

from rest_framework import filters
from rest_framework import mixins
from rest_framework import permissions
# from rest_framework import authentication
from rest_framework import status
from rest_framework import viewsets
# from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

#导入分页模块并改写
from rest_framework import filters
from rest_framework.pagination import PageNumberPagination
from rest_framework import permissions
class CommonPagination(PageNumberPagination):
    """
    通用分页配置类
    """
    # 每页的记录数
    page_size = 100
    # url中请求“页”的参数名
    page_query_param = 'page'
    # url中请求“每页记录数”的参数名
    page_size_query_param = 'page_size'
    # 每页最大记录数
    max_page_size = 200


#从应用模块的models文件中导入对应模型[表单]
from dlt.models import LotteryData,LotteryDataForecast,Difference,Reptiles,Guess,ChangeNum,ChangeNumMean,ChangeNumSum,LotteryDataForecast2
#从应用模块的serializers文件中导入对应模型Serializer
from dlt.serializers import LotteryDataSerializer,LotteryDataForecastSerializer,DifferenceSerializer,ReptilesSerializer,GuessSerializer,ChangeNumSerializer,ChangeNumMeanSerializer,ChangeNumSumSerializer,LotteryDataForecast2Serializer

class LotteryDataViewSet(ModelViewSet):
    """
    往期开奖数据
    """
    queryset = LotteryData.objects.all()
    serializer_class = LotteryDataSerializer
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = CommonPagination
class LotteryDataForecastViewSet(ModelViewSet):
    """
    期后预测数据
    """
    queryset = LotteryDataForecast.objects.all()
    serializer_class = LotteryDataForecastSerializer
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = CommonPagination
class DifferenceViewSet(ModelViewSet):
    """
    开奖和预测差异
    """
    queryset = Difference.objects.all()
    serializer_class = DifferenceSerializer
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = CommonPagination
class ReptilesViewSet(ModelViewSet):
    """
    爬虫执行开关
    """
    serializer_class = ReptilesSerializer
    permission_classes = [permissions.IsAuthenticated]
    # 分页+统计
    pagination_class = CommonPagination

    def get_queryset(self, *args, **kwargs):
        return Reptiles.objects.filter()   
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        from dlt.tool.getnum import geturl,getdata
        urldata = geturl()
        #解析数据并存入数据库
        alldata = etree.HTML(urldata)
        beginNum = 2001
        for i in range(beginNum,0,-1):
            path1 = r'//*[@id="tdata"]/tr['+str(i)+']/td[1]'
            path2 = r'//*[@id="tdata"]/tr['+str(i)+']/td[2]'
            path3 = r'//*[@id="tdata"]/tr['+str(i)+']/td[3]'
            path4 = r'//*[@id="tdata"]/tr['+str(i)+']/td[4]'
            path5 = r'//*[@id="tdata"]/tr['+str(i)+']/td[5]'
            path6 = r'//*[@id="tdata"]/tr['+str(i)+']/td[6]'
            path7 = r'//*[@id="tdata"]/tr['+str(i)+']/td[7]'
            path8 = r'//*[@id="tdata"]/tr['+str(i)+']/td[8]'
            path9 = r'//*[@id="tdata"]/tr['+str(i)+']/td[15]'
            ordernum=int('20'+str(alldata.xpath(path1)[0].text))
            #查看是否存在这一期,如果不存在的话,创建这一期
            thisorder = LotteryData()
            thisorder = LotteryData.objects.filter(order__exact=ordernum).first()
            if thisorder == None:
                thisorder = LotteryData()
            #从前2001期到现在的每一期数据
            thisorder.order = ordernum
            thisorder.red1 =  int(alldata.xpath(path2)[0].text)
            thisorder.red2 =  int(alldata.xpath(path3)[0].text)
            thisorder.red3 =  int(alldata.xpath(path4)[0].text)
            thisorder.red4 =  int(alldata.xpath(path5)[0].text)
            thisorder.red5 =  int(alldata.xpath(path6)[0].text)
            thisorder.blue1 =  int(alldata.xpath(path7)[0].text)
            thisorder.blue2 =  int(alldata.xpath(path8)[0].text)
            thisorder.date =  alldata.xpath(path9)[0].text
            thisorder.save()
            #当超过历史第一期(即最早一期2001期)才存在两期比较变化,这里时本期比上期多的值
            if i < beginNum:
                lastorder = LotteryData.objects.filter(order__exact=int('20'+str(alldata.xpath(r'//*[@id="tdata"]/tr['+str(i+1)+']/td[1]')[0].text))).first()
                change = ChangeNum()
                change = ChangeNum.objects.filter(order=thisorder).first()
                if change == None:
                    change = ChangeNum()
                    change.order=thisorder
                change.red1 = int(thisorder.red1 - lastorder.red1)
                change.red2 = int(thisorder.red2 - lastorder.red2)
                change.red3 = int(thisorder.red3 - lastorder.red3)
                change.red4 = int(thisorder.red4 - lastorder.red4)
                change.red5 = int(thisorder.red5 - lastorder.red5)
                change.blue1 = int(thisorder.blue1 - lastorder.blue1)
                change.blue2 = int(thisorder.blue2 - lastorder.blue2)
                change.save()
                #每一期当期以往的所有期变化值的平均值,用作变化的数学期望,即最终的变化将向平均值靠拢
                changeMean = ChangeNumMean()
                changeMean = ChangeNumMean.objects.filter(order=thisorder).first()
                if changeMean == None:
                    changeMean = ChangeNumMean()
                    changeMean.order=thisorder
                #每一期当期以往所有期变化值的合计值,用作合计值变化的数学期望,暂无作用
                changeSum = ChangeNumSum()
                changeSum = ChangeNumSum.objects.filter(order=thisorder).first()
                if changeSum == None:
                    changeSum = ChangeNumSum()
                    changeSum.order=thisorder
                #每一期通过扣减变化值所计算出来的预测值,预测值-当期值=预测变化,(预测变化+合计变化)/t+1=预测平均值,(预测平均值+当期变化值)/2=预测变化
                Forecast2 = LotteryDataForecast2()
                Forecast2 = LotteryDataForecast2.objects.filter(order=thisorder).first()
                if Forecast2 == None:
                    Forecast2 = LotteryDataForecast2()
                    Forecast2.order=thisorder
                allchange = ChangeNum.objects.filter(id__lt=thisorder.pk)
                allchange_num = allchange.count()
                red_1=0
                red_2=0
                red_3=0
                red_4=0
                red_5=0
                blue_1=0
                blue_2=0
                for one_change in allchange:
                    red_1 = red_1 + one_change.red1
                    red_2 = red_2 + one_change.red2
                    red_3 = red_3 + one_change.red3
                    red_4 = red_4 + one_change.red4
                    red_5 = red_5 + one_change.red5
                    blue_1 = blue_1 + one_change.blue1
                    blue_2 = blue_2 + one_change.blue2
                changeSum.red1 = red_1
                changeSum.red2 = red_2
                changeSum.red3 = red_3
                changeSum.red4 = red_4
                changeSum.red5 = red_5
                changeSum.blue1 = blue_1
                changeSum.blue2 = blue_2
                changeSum.save()

                changeMean.red1 = red_1/allchange_num
                changeMean.red2 = red_2/allchange_num
                changeMean.red3 = red_3/allchange_num
                changeMean.red4 = red_4/allchange_num
                changeMean.red5 = red_5/allchange_num
                changeMean.blue1 = blue_1/allchange_num
                changeMean.blue2 = blue_2/allchange_num
                changeMean.save()

                Forecast2.red1 = round(thisorder.red1+changeSum.red1/(2*thisorder.pk+1)+change.red1*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.red2 = round(thisorder.red2+changeSum.red2/(2*thisorder.pk+1)+change.red2*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.red3 = round(thisorder.red3+changeSum.red3/(2*thisorder.pk+1)+change.red3*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.red4 = round(thisorder.red4+changeSum.red4/(2*thisorder.pk+1)+change.red4*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.red5 = round(thisorder.red5+changeSum.red5/(2*thisorder.pk+1)+change.red5*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.blue1 = round(thisorder.blue1+changeSum.blue1/(2*thisorder.pk+1)+change.blue1*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.blue2 = round(thisorder.blue2+changeSum.blue2/(2*thisorder.pk+1)+change.blue2*(thisorder.pk+1)/(2*thisorder.pk+1))
                Forecast2.save()
                
                if i < beginNum-1:
                    #除去最新一期的数据,每一期的预测值应该和下一期的真实值有个差异
                    lastForecast2 =  LotteryDataForecast2.objects.filter(id = LotteryDataForecast2.objects.filter(order=thisorder).first().pk-1).first()

                    difference = Difference()
                    difference = Difference.objects.filter(order=thisorder).first()
                    if difference == None:
                        difference = Difference()
                        difference.order=thisorder
                    difference.red1 = thisorder.red1 - lastForecast2.red1
                    difference.red2 = thisorder.red2 - lastForecast2.red2
                    difference.red3 = thisorder.red3 - lastForecast2.red3
                    difference.red4 = thisorder.red4 - lastForecast2.red4
                    difference.red5 = thisorder.red5 - lastForecast2.red5
                    difference.blue1 = thisorder.blue1 - lastForecast2.blue1
                    difference.blue2 = thisorder.blue2 - lastForecast2.blue2
                    difference.save()
                    
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

class GuessViewSet(ModelViewSet):
    """
    预测执行开关
    """
    serializer_class = GuessSerializer
    permission_classes = [permissions.IsAuthenticated]
    # 分页+统计
    pagination_class = CommonPagination

    def get_queryset(self, *args, **kwargs):
        return Guess.objects.filter()   
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        from dlt.tool.guess import predict,getChangeNum
        #1.获取数据最大的位置
        maxnum = LotteryData.objects.all().order_by('-id') .first().pk
        # getChangeNum(maxnum)
        predict(maxnum)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

class ChangeNumViewSet(ModelViewSet):
    """
    预测执行开关
    """
    serializer_class = ChangeNumSerializer
    permission_classes = [permissions.IsAuthenticated]
    # 分页+统计
    pagination_class = CommonPagination
    def get_queryset(self, *args, **kwargs):
        return ChangeNum.objects.filter()   
class ChangeNumMeanViewSet(ModelViewSet):
    """
    预测执行开关
    """
    serializer_class = ChangeNumMeanSerializer
    permission_classes = [permissions.IsAuthenticated]
    # 分页+统计
    pagination_class = CommonPagination
    def get_queryset(self, *args, **kwargs):
        return ChangeNumMean.objects.filter()   
class ChangeNumSumViewSet(ModelViewSet):
    """
    预测执行开关
    """
    serializer_class = ChangeNumSumSerializer
    permission_classes = [permissions.IsAuthenticated]
    # 分页+统计
    pagination_class = CommonPagination
    def get_queryset(self, *args, **kwargs):
        return ChangeNumSum.objects.filter()   

8.最后给这些代码配一下路由

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from rest_framework import routers
from rest_framework.documentation import include_docs_urls
from rest_framework.authtoken.views import obtain_auth_token
from dlt.views import LotteryDataViewSet,LotteryDataForecastViewSet,DifferenceViewSet,ReptilesViewSet,GuessViewSet
from dlt import views as DltViews
from lottery.settings import MEDIA_URL, MEDIA_ROOT#配置静态文件路径,不然打不来文件
# 定义DRF的API链接
# 使用basename可以解决drf路由被覆盖的问题
router = routers.DefaultRouter()
router.register(r'lottery-data', DltViews.LotteryDataViewSet, basename='lottery-data')
router.register(r'forecast', DltViews.LotteryDataForecastViewSet, basename='forecast')
router.register(r'difference', DltViews.DifferenceViewSet, basename='difference')
router.register(r'reptiles', DltViews.ReptilesViewSet, basename='reptiles')
router.register(r'guess', DltViews.GuessViewSet, basename='guess')
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    path('', include(router.urls)),
]+ static(MEDIA_URL, document_root=MEDIA_ROOT)#配置静态文件路径,不然打不来文件

展示一下

在这里插入图片描述
用reptiles链接触发数据采集
这里因为第一次采集,所以写入了2000条数据,第一次采集后可以在views.py文件的下把beginNum改小,如果你十天半个月才关注一次彩票的话,可以改成100或者30,当然,重新改写成一直挂载每天自动采集的也是可以的

lass ReptilesViewSet(ModelViewSet):
    """
    爬虫执行开关
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        from dlt.tool.getnum import geturl,getdata
        urldata = geturl()
        #解析数据并存入数据库
        alldata = etree.HTML(urldata)
        beginNum = 2001

然后在采集的同时,就会进行各种计算了
采集填入数据库的每一期点开奖数据
在这里插入图片描述
和每一期对应的对比上一期的数据变化
在这里插入图片描述
N期数据变化的合计值,总是在一定范围内来回震荡的
在这里插入图片描述
平均变化趋近于0
在这里插入图片描述
根据每一期的变化值给出一个帮助他趋于数学期望的预测值
在这里插入图片描述
guess链接用来触发我们编辑好的另一种预测方法
在这里插入图片描述

通过这样简单的预测一下彩票,就把基础的django配合DRF框架搭建后端API给过了一遍

要是万一中了呢?

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

isSamle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值