STUDY/Python

파이썬 역대 로또 당첨번호 크롤링 및 어떤 번호가 많이 나왔을까(1028회차 까지)

uragiljay 2022. 5. 18. 16:15
반응형
import numpy as np
import requests
from tqdm import tqdm
from collections import Counter
import json
import matplotlib.pyplot as plt
import numpy as np - ndarray 형으로 저장하는데 사용
 
import requests  - Http에 요청을 보내는데 사용 
 
from tqdm import tqdm  -  loading 막대기 효과 tqdm( ) 으로 감싸주어서 진행 상황 파악
 
from cllections import Counter - 요소를 키값으로 해당 개수를 사전형태로 저장하는데 사용
 
import json - json() - 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저장

print(result) 를 해보면 아래와 같이 {'key값' :'value값'}으로 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)]
 
 
부족한 실력과 귀차니즘으로 번호 순서 정렬  못하고 나오는대로 만들어진 그래프 입니다.
그레프 부분 색추가 seaborn color_palette 이용한 색 추가
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범주 나누기가 어려웠다. 구글링 엄청해서 어디선가 주워서 적용

반응형