何以解忧/唯有暴富/用代码实现人生的致富理想-大乐透
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给过了一遍