最近没事买彩票的的时候就很好奇双色球还有多少注没有开到过,如果从没开到过的号码里选,是不是中奖的机会更大?如何让自己选号时不会选到以前开过的号?正好最近自学Python,那就现有的知识写一个小程序实现一下这个功能。
1.生成奖池
双色球由从1-33的红球抽取6个号码和从1-16的蓝球抽取1个号码组成,那就先生成所有红球可能的结果,然后再每样复制16份作为奖池。
import itertools
my_num = open('1.txt', mode = 'a',encoding='utf-8')
for i in itertools.combinations('1234567890ABCDEFGHIJKLMNOPQRSTUVW',6): #生成红球数据
print(i,file=my_num)
my_num.close()
#一共有1107568*16=17721088种排列组合
文件内容如下:
2.获取往期数据
用爬虫获取一下往期数据,由于还不会写爬虫就先用一下别人写好的进行修改
python3抓取-双色球开奖的所有历史数据-2003年始
#coding=utf-8
# 源链接:https://blog.csdn.net/love_bb/article/details/81223432
# 少许改动适应本项目需要
import io
import linecache
from requests import get
from bs4 import BeautifulSoup
from user_agent import generate_user_agent
import time
def request_content(start, end):
url_link = 'https://datachart.500.com/ssq/history/newinc/history.php?start={0}&end={1}'.format(start, end)
headers = {
'User-Agent': generate_user_agent(device_type='desktop', os=('mac', 'linux', 'win', 'android'))
}
response = get(url_link, headers=headers, timeout=6)
page_content = BeautifulSoup(response.content, "html.parser")
html_tag = page_content.find_all('tbody', id='tdata')[0]
return html_tag.find_all('tr', 't_tr1')
class ssqclazz:
def __init__(self):
self.period = '' # 期号
self.red_1 = '' # 红球
self.red_2 = ''
self.red_3 = ''
self.red_4 = ''
self.red_5 = ''
self.red_6 = ''
self.blue_1 = '' # 蓝球
def __str__(self):
return '{0} {1} {2} {3} {4} {5} {6} {7}'.format(self.period, self.red_1,self.red_2, self.red_3,self.red_4, self.red_5,self.red_6,self.blue_1)
def tr_tag(self, tag):
tds = tag.find_all('td')
index = 0
self.period = tds[index].string
index += 1
self.red_1 = tds[index].string
index += 1
self.red_2 = tds[index].string
index += 1
self.red_3 = tds[index].string
index += 1
self.red_4 = tds[index].string
index += 1
self.red_5 = tds[index].string
index += 1
self.red_6 = tds[index].string
index += 1
self.blue_1 = tds[index].string
def get_history_data():
file = io.open('ssq.txt', mode='w', encoding='utf-8')
localtime = time.localtime(time.time())
lyear = localtime.tm_year
ymin = 3 # 开始年份
ymax = lyear - 2000
print('===抓取数据开始===,20%s-20%s' % (ymin, ymax))
file.truncate()
for year in range(ymin, ymax + 1):
start = '{0}001'.format(year)
end = '{0}300'.format(year)
trs = request_content(start, end)
for tr in trs:
ssqobj = ssqclazz()
ssqobj.tr_tag(tr)
objstr = ssqobj.__str__()
file.write(objstr)
file.write('\n')
print(objstr)
print()
time.sleep(1)
file.close()
print('抓取完毕!!!')
if __name__ == '__main__':
get_history_data()
抓取的文件内容如下:
3.清洗数据
为了不会在随机抽取时抽到以前开过的号码,需要把现有奖池中以前的号码进行剔除从根本上防止浪费运气的情况发生 :
def clean_data ():
count = len(open('ssq.txt', 'r').readlines()) #打开历史开奖数据
num = 0 #计数器
for i in range(1, count+1): #对文件每一行循环
read_history_line = linecache.getline('ssq.txt', i) #抽取某一行
red = [] #历史开奖号码
for j in range(6,24 ,3): #取出历史红球
m = read_history_line[j]+read_history_line[j+1] #红球
n =change_to_data(m) #转换格式
red.append(n) #组装
str_bull = read_history_line[24]+read_history_line[25] #历史的蓝球
bull_ball = int(str_bull) #去0操作
bull_ball_path = 'data/'+str(bull_ball)+'.txt' #蓝球的文件路径
print("此次从这个文件删除:",bull_ball_path)
red_s = str(red)
red_s = red_s.replace('[','(')
red_s = red_s.replace(']', ')')
print("删除这个:",red_s)
count_data1 = len(open(bull_ball_path, 'r').readlines())
with open(bull_ball_path, 'r') as r:
lines = r.readlines()
with open(bull_ball_path, 'w') as w:
for l in lines:
if red_s not in l:
w.write(l)
count_data2 = len(open(bull_ball_path, 'r').readlines())
if count_data1 == count_data2:
print("没删")
if count_data1 != count_data2:
print("删除一条")
num = num+1
print("已经删除了",num)
print('删除的条数',num)
print('现有开奖条数:', count)
def change_to_data(m):
if m == '01': n = '1'
elif m == '02':n = '2'
elif m == '03':n = '3'
elif m == '04':n = '4'
elif m == '05':n = '5'
elif m == '06':n = '6'
elif m == '07':n = '7'
elif m == '08':n = '8'
elif m == '09':n = '9'
elif m == '10':n = '0'
elif m == '11':n = 'A'
elif m == '12':n = 'B'
elif m == '13':n = 'C'
elif m == '14':n = 'D'
elif m == '15':n = 'E'
elif m == '16':n = 'F'
elif m == '17':n = 'G'
elif m == '18':n = 'H'
elif m == '19':n = 'I'
elif m == '20':n = 'J'
elif m == '21':n = 'K'
elif m == '22':n = 'L'
elif m == '23':n = 'M'
elif m == '24':n = 'N'
elif m == '25':n = 'O'
elif m == '26':n = 'P'
elif m == '27':n = 'Q'
elif m == '28':n = 'R'
elif m == '29':n = 'S'
elif m == '30':n = 'T'
elif m == '31':n = 'U'
elif m == '32':n = 'V'
elif m == '33':n = 'W'
return n
清理的结果如下:
4.抽取
最后就是抽一注双色球啦:
def random_sampling ():
bull_ball = random.randint(1, 16) #抽蓝球
bull_ball_path = 'data/' + str(bull_ball) + '.txt' # 蓝球的文件路径
# count = len(open(bull_ball_path, 'r').readlines())
file =open(bull_ball_path, 'r',buffering=1)
file_list = file.readlines()
count = len(file_list)
file.close()
file_list.clear()
red_ball = random.randint(1, count) #抽红球
red_ball_line = linecache.getline(bull_ball_path, red_ball)#抽取文件中的一行作为开奖
list_num = change_to_list(red_ball_line)#开奖结果
if bull_ball=10:
list_num.append(str(bull_ball))
print ('抽取结果是:',list_num)
linecache.clearcache() #清除缓存
return list_num
def change_to_list(red_ball_line):
list_num = [] # 开奖结果
for i in range(2, 28, 5) :
j = str(red_ball_line[i])
if j == '1'or j == '2'or j == '3'or j == '4'or j == '5'or j == '6'or j == '7'or j == '8'or j == '9':j='0'+j
elif j =='0':j='10'
elif j =='A':j='11'
elif j =='B':j='12'
elif j =='C':j='13'
elif j =='D':j='14'
elif j =='E':j='15'
elif j =='F':j='16'
elif j =='G':j='17'
elif j =='H':j='18'
elif j =='I':j='19'
elif j =='J':j='20'
elif j =='K':j='21'
elif j =='L':j='22'
elif j =='M':j='23'
elif j =='N':j='24'
elif j =='O':j='25'
elif j =='P':j='26'
elif j =='Q':j='27'
elif j =='R':j='28'
elif j =='S':j='29'
elif j =='T':j='30'
elif j =='U':j='31'
elif j =='V':j='32'
elif j =='W':j='33'
list_num.append(j)
return list_num
抽取结果:
5.总结
写这个小玩意也不是很容易,之后就是用flask框架搭建一个web应用放到服务器上就可以随时使用啦,值得注意的是linecache.getline()这个用完之后一定要clearcache(),不然分分钟爆内存。
我部署项目的网站:
抽取一注没开过的双色球
github源码:
我的github源码地址