파이썬 역대 로또 당첨번호 크롤링 및 어떤 번호가 많이 나왔을까(1028회차 까지)
import numpy as np
import requests
from tqdm import tqdm
from collections import Counter
import json
import matplotlib.pyplot as plt
def lotto(minD, maxD):
num1=[]
num2=[]
num3=[]
num4=[]
num5=[]
num6=[]
bnum=[]
nonum=[]
for i in tqdm(range(minD, maxD+1)):
url="https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo="+str(i)
req=requests.get(url)
result=req.json()
num1.append(result["drwtNo1"])
num2.append(result["drwtNo2"])
num3.append(result["drwtNo3"])
num4.append(result["drwtNo4"])
num5.append(result["drwtNo5"])
num6.append(result["drwtNo6"])
bnum.append(result["bnusNo"])
#for문 끝
h= np.hstack((num1, num2, num3, num4, num5, num6))
cnt=Counter(h)
cntB=Counter(bnum)
for j in range(1, 46):
if j not in h:
nonum.append(j)
lotto함수 정의.
lotto(minD, maxD) - 분석 하려는 회차의 변수를 (시작 회차=minD, 끝 회차=maxD)받는
num1~6[] -1~6번까지의 추첨번호를 담을 리스트 생성
bnum[] - 보너스 번호를 담을 리스트 생성
nonum[] - 뽑히지 않은 번호를 담을 리스트 생성
for i in tqdm(range(minD, maxD+1)):
for문으로 minD 부터 maxD까지 반복하고 range()를 tqdm()으로 감싸서 진행률 확인
url=https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=%d
+ str(i) 로또번호를 스크롤링 해서 가져 올 주소로
'=' 뒤에 원하는 회차 입력 여기서는 str로 형 변환 한 i 값을 넣는다 (int형은 에러)
req=requests.get(url) - 위 url에 get 요청 응답을 저장
result=req.json() 받아온 정보를 json() 메서드를 이용하여 dict 타입으로 result저장
{'totSellamnt': 101948323000, 'returnValue': 'success', 'drwNoDate': '2022-04-23', 'firstWinamnt': 1861944318, 'drwtNo6': 45, 'drwtNo4': 20, 'firstPrzwnerCo': 13, 'drwtNo5': 35, 'bnusNo': 3, 'firstAccumamnt': 24205276134, 'drwNo': 1012, 'drwtNo2': 11, 'drwtNo3': 18, 'drwtNo1': 5}
num1.append(result["drwtNo1"])
.
.
bnum.append(result["bnusNo"])
생성해 둔 각 배열에 result에서 해당 key값을 찾아 벨류값을 append 해 준다
https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=1015
에서 제공되는 1015회차 정보
{"totSellamnt":102562683000,"returnValue":"success","drwNoDate":"2022-05-
14","firstWinamnt":3051105610,"drwtNo6":40,"drwtNo4":33,"firstPrzwnerCo":8,"
drwtNo5":37,"bnusNo":44,"firstAccumamnt":24408844880,"drwNo":1015,"
drwtNo2":23,"drwtNo3":31,"drwtNo1":14}
drwNoDate:추첨일
firstWinamnt:1등 당첨금
firstPrzwnerCo:1등 당첨자 수
drwNo:회차
drwtNo1~6(해당 회차의 1~6번째 당첨번호) ,bnusNo(보너스 번호) - 받아 온 자료
h=np.hstack((num1, num2, num3, num4, num5, num6))
numpy.hstack을 사용하여 num1~6 리스트를 ndarray형으로 h에 저장한다.
(ndarray는 메모리에 연속적으로 배치되어 연산속도 향상)
print(h)해보면, 각 배열에 저장되어있던 당첨번호들이 옆으로 쭈욱 어가 있다.
[ 5 21 3 14 15 12 3 11 22 11 23 26 18 19 18 26 14 31 28 22 21 20 34 18
33 34 23 25 35 36 26 37 41 30 37 45 41 27 40 42 34 45]
count=Counter(h)
위 ndarray에서 (각 번호별 몇개 들어있는지 )
요소를 키값으로 해당 개수를 사전형태로 당첨 번호들을 Counter하여 저장
cntB=Counter(bnum)
보너스번호를 Counter하여 저장
for j in range(1, 46):
if j not in h:
nonum.append(j)
당첨 되지 않은 번호 찾아보자
당첨번호들이 저장 된 h 배열에 1~45까지 있는지 확인하여 값이 없으면 append 해준다.
조회차수가 15회정도 되면 대부분이 당첨번호가 되니 단기 분석이 아니면 무쓸모.
#출력부
print("(로또번호/ 뽑힌 횟수)",sorted(cnt.items(), key=lambda x: x[1], reverse=True))
print("보너스 번호:", sorted(cntB.items(), key=lambda x: x[0]))
print('아직 안나옴:', nonum)
#그레프 부분
plt.figure(figsize=(20,10))
plt.bar(range(len(cnt)), list(cnt.values()), align='center', width=0.8, color="pink")
plt.xticks(range(len(cnt)), list(cnt.keys()), rotation=45 )
plt.show()
#1001회부터 1019회까지 로또함수 일 시작!!
lotto(1001, 1019)
출력값
(로또번호/ 뽑힌 횟수) [(34, 6), (15, 5), (11, 5), (12, 4), (25, 4), (26, 4), (18, 4), (37, 4), (45, 4), (17, 3), (1, 3), (8, 3), (9, 3), (21, 3), (14, 3), (23, 3), (29, 3), (30, 3), (35, 3), (39, 3), (41, 3), (44, 3), (3, 2), (4, 2), (13, 2), (22, 2), (19, 2), (33, 2), (16, 2), (31, 2), (20, 2), (38, 2), (27, 2), (40, 2), (36, 2), (42, 2), (6, 1), (7, 1), (5, 1), (10, 1), (28, 1), (24, 1), (43, 1)]
보너스 번호: [(3, 2), (6, 1), (15, 2), (17, 1), (18, 1), (20, 1), (21, 1), (31, 1), (32, 2), (33, 1), (35, 1), (36, 1), (40, 1), (42, 1), (44, 2)]
아직 안나옴: [2, 32]
print("(로또번호/뽑힌 횟수)", sorted(count.items(), key= lambda item:item[1], reverse=True))
count.items() key값(로또번호)과 value값(당첨 횟수) 출력
kye= lambda item:item[1]
람다 함수는 item을 받아 item의 두 번째 요소인 item[1]을 반환
[0]은 key값 [1]은 벨류값. 벨류값으로 내림차순 정리를 위해 사용
print("(보너스번호, 당첨 횟수)", sorted(cntB.items(), key= lambda x:x[0]))
보너스번호는 key값인 번호 순서로 정렬하여 출력
print("아직 안나온 번호", nonum)
그래프 값은 아래 1~1019회에 양보
lotto(1001, 1015)
로또함수 1000~1015회차의 로또 결과를 분석
결과는 '11'이 5번으로 가장 많이 당첨된 번호이며 '28'이 1000회 이후 아직 안나온 번호.
1016회차에 11과 28의 결과가 기대된다.
2022_0703_수정
로또함수 1001~1022회차의 로또 결과를 분석
(1등 번호/ 뽑힌 횟수): [(45, 7), (15, 6), (12, 6), (11, 6), (29, 6), (34, 6), (17, 4), (25, 4), (26, 4), (18, 4), (37, 4), (41, 4), (1, 3), (8, 3), (9, 3), (21, 3), (14, 3), (23, 3), (27, 3), (30, 3), (35, 3), (39, 3), (38, 3), (42, 3), (44, 3), (6, 2), (5, 2), (3, 2), (4, 2), (13, 2), (22, 2), (19, 2), (33, 2), (16, 2), (31, 2), (24, 2), (20, 2), (40, 2), (36, 2), (7, 1), (10, 1), (28, 1), (43, 1)]
(보너스 / 뽑힌 횟수): [(3, 2), (6, 2), (15, 2), (16, 1), (17, 1), (18, 1), (20, 1), (21, 1), (28, 1), (31, 1), (32, 2), (33, 1), (35, 1), (36, 1), (40, 1), (42, 1), (44, 2)]
아직 안나옴: [2, 32]
결과는 '45' 번호가 7번으로 가장 많이 당첨되었으며
'11', '15', '12', '29', '34' 번이 6번 당첨되어 그 뒤를 잇고있다.
'2', '32' 번은 1001회 부터 나오지 않고 있다.
몇 회차에 2, 32번이 나올까?
2022_0710_Updated
np arrya 저장 및 불러오기와 재가공
기존에 크롤링하여 저장해 둔 로또 1회~1021회차의 np array 를 load 후
새로운 회차(1022회) 정보를 append하여 출력하였다.
그리고 다시 lotto+'회차' 이름으로 np.array를 저장 다음주에 써먹을 것
import numpy as np
from collections import Counter
#구글드라이브의 colab notebooks 폴더에 lotto1021 이름으로 저장
np.save('/content/drive/MyDrive/Colab Notebooks/lotto1021', h)
#저장한거 lo불러오기
lotto1022 = np.load("/content/drive/MyDrive/Colab Notebooks/lotto1021.npy")
#배열에 새로운 회차의 당첨번호 append 하여 업데이트
h = np.append(lotto1022, np.array([5, 6, 11, 29, 42, 45]))
#카운트 출력해서 결과 확인
cnt=Counter(h)
print("(로또번호/ 뽑힌 횟수)",sorted(cnt.items(), key=lambda x: x[1], reverse=True))
#다시 lotto1022 이름으로 저장
np.save('/content/drive/MyDrive/Colab Notebooks/lotto1022', h)
22.08.14 updated
lotto(1, 1028)
전체 찾는 분을 위해 1회부터 1028회까지 번호 별 당첨횟수와 그래프 추가
최다 당첨 번호 '34' - 158회
최소 당첨 번호 '9' - 111회
회차가 반복될 수록 통계적확률은 수학적 확률에 수렴한다는 것을 생각하면 9번의 당첨 기대값이 높아지는건가?
# 1~1028회차
(로또번호/ 뽑힌 횟수) [(34, 158), (18, 154), (12, 149), (27, 149), (13, 148), (17, 147), (39, 147), (14, 146), (43, 146), (45, 146), (1, 145), (20, 143), (37, 143), (40, 143), (33, 142), (10, 140), (11, 140), (4, 140), (15, 140), (21, 138), (31, 138), (44, 138), (24, 137), (2, 136), (3, 136), (26, 136), (36, 136), (38, 136), (16, 135), (8, 135), (19, 135), (42, 135), (5, 134), (7, 134), (25, 133), (35, 130), (29, 130), (41, 128), (6, 127), (28, 125), (23, 124), (30, 123), (22, 117), (32, 115), (9, 111)]
import seaborn as sns
plt.figure(figsize=(20,10))
col=sns.color_palette('hls',len(cnt))
plt.bar(range(len(cnt)), list(cnt.values()), align='center', width=0.8, color=col)
plt.grid(color='red', linestyle='--', linewidth=1, axis='y', alpha=0.7)
plt.xticks(range(len(cnt)), list(cnt.keys()), rotation=45 )
plt.show()

시작하기 전에는 뭔가 대단한 발견을 할 수 있을거라 생각했는데
막상 하면서 이거 뭐에 쓰나 싶어진다. 어차피 난 안돼

작업하며 에러났던 부분
1. 작업환경을 여기저기 옮기다 보니 import 했던것들 중 package설치가 안된 것들이 있었다.
- 구글 Colab 환경에서 !pip install '해당패키지' 로 설치해서 해결
2. 줄 맞추기 실수
- { }요거 없어도 되서 파이썬 와 좋다 하는데 복붙하다보면 줄맞춤이 좀 햇갈림
3. 그레프 x범주 y범주 나누기가 어려웠다. 구글링 엄청해서 어디선가 주워서 적용