컴퓨터/Python

Python (22) - 로또 API이용하여 당첨번호를 크롤링해보자

달서비 2024. 1. 29. 22:25

요즘 관심을 진행중인 토이 프로젝트는 인공지능에 로또 번호를 학습시키는 프로젝트를 하고 있습니다. 미리 말씀드리자면 독립시행이라 토이 프로젝트 정도로 생각하고 있습니다. 학습 재료로 로또 1회부터 최신화까지 당첨 번호를 가지고 오려고 하는데 해당 방법을 업로드 하려고 합니다.

 

우선 사용 전 동행복권에서 최신 특정 회차까지 뽑을 수 있습니다. 미리 참조 부탁합니다.

https://dhlottery.co.kr/gameResult.do?method=byWin

 

로또6/45 - 회차별 당첨번호

1103회 당첨결과 (2024년 01월 20일 추첨) 당첨번호 10 12 29 31 40 44 1103회 순위별 등위별 총 당첨금액, 당첨게임 수, 1게임당 당첨금액, 당첨기준, 비고 안내 순위 등위별 총 당첨금액 당첨게임 수 1게임

dhlottery.co.kr

 

사용했던 모듈

모듈 명 사용 이유
requests 웹사이트를 조회 및 수집하는 모듈
BeautifulSoup 웹사이트 자체(html)에서 정보를 가져오는 경우 request는 복잡하여 이용
csv CSV 포맷으로 데이터 생성

 

로또 데이터를 가져오자

우선 RNN 모델을 만들기 전에 가장 중요한 것은 먹이를 만들어주는 것입니다. 

동행복권 웹사이트에서 로또 당첨 번호를 API로 제공해 줍니다. 해당 데이터는 JSON 타입입니다. 아래 URL에 마지막 파라미터에 drwNo=1 이것이 해당 타입입니다. 해당 타입을 텍스트 파일로 만들어보겠습니다. 

https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=1 

#로또 결과에 대한 JSON 타입
'''
{
  "returnValue": "success",
  "drwNo": 1,
  "drwNoDate": "2002-12-07",
  "firstAccumamnt": 863604600,
  "firstPrzwnerCo": 0,
  "firstWinamnt": 0,
  "totSellamnt": 3681782000,
  "drwtNo1": 10,
  "drwtNo2": 23,
  "drwtNo3": 29,
  "drwtNo4": 33,
  "drwtNo5": 37,
  "drwtNo6": 40,
  "bnusNo": 16
}
'''

 

학습 데이터 수집

우리가 수집해야 하는 데이터는 drwtNo1 ~ drwtNo6의 데이터입니다. 또한 해당 설명을 할 수 있게끔 drwNo와 drwNoDate까지 럼으로 추가하도록 합니다. 정리하면 각 시트는 해당 형식으로 저장 시키겠습니다.

회차 일자 번호1 번호2 번호3 번호4 번호5 번호6 보너스번호
drwNo drwNoDate drwtNo1 drwtNo2 drwtNo3 drwtNo4 drwtNo5 drwtNo6 bnusNo

파이썬에 request 모듈을 이용하여 해당 데이터를 출력 폼으로 바꾸겠습니다.

 

getLottoNumber이라는 함수는 특정 회차의 정보를 JSON 형식으로 받고 해당 데이터를 출력하도록 하도록 합니다. 아래 소스코드는 1회차 정보를 호출하였습니다.

import requests

def getLottoNumber(draw_no):
    api_url = f"https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo={draw_no}"

    try:
        res = requests.get(api_url)
        res.raise_for_status()

        data = res.json()

        # Request 데이터 출력
        print(f"로또 회차: {data['drwNo']}")
        print(f"로또 일자: {data['drwNoDate']}")        
        print("당첨 번호:", [data[f"drwtNo{i}"] for i in range(1, 7)])
        print(f"보너스 번호: {data['bnusNo']}")
        print("---------------------------------")

    except requests.exceptions.RequestException as e:
        print(f"오류가 발생했습니다: {e}")


getLottoNumber(1) #1회차정보호출
'''
로또 회차: 1
로또 일자: 2002-12-07
당첨 번호: [10, 23, 29, 33, 37, 40]
보너스 번호: 16
'''

 

1회부터 최신화까지 출력하기

getLottoNumber 함수를 이용하여 for 문을 이용하여 출력할 수 있으나 최신화를 알 수 없습니다. 최신화를 알 수 있도록 나눔로또 사이트에 있는 lottoDrwNo의 정보를 가지고 왔습니다.

import requests
from bs4 import BeautifulSoup

def maxRound():
    url = "https://dhlottery.co.kr/common.do?method=main"
    html = requests.get(url).text
    soup = BeautifulSoup(html, "lxml")
    max_numb = soup.find(name="strong", attrs={"id": "lottoDrwNo"}).text
    return int(max_numb)

print(maxRound()) #1104

 

CSV 파일 변환

마지막으로 해당 데이터를 CSV 포맷으로 바꿀 수 있도록 로또의 출력을 딕셔너리로 변경하였습니다.

def get_lotto_numbers(draw_no):
    api_url = f"https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo={draw_no}"

    try:
        response = requests.get(api_url)
        response.raise_for_status()

        data = response.json()

        # Request 데이터 출력
        return {
            'drwNo' : data['drwNo'],
            'date': data['drwNoDate'], 
            'lottoNumb': [data[f"drwtNo{i}"] for i in range(1, 7)], 
            'bonusNumb': data['bnusNo']
        }

해당 데이터를 딕셔너리로 뽑았습니다. 딕셔너리 데이터를 뽑는 방법은 다음과 같습니다.

# CSV 파일 쓰기
with open('lottoRes.csv', 'w', newline='') as csvfile:
    # CSV 파일 쓰기
    writer = csv.writer(csvfile, delimiter=',')
    
    res = get_lotto_numbers(1)
    # 순서 : 회차, 날짜, 로또번호1, 로또번호2, 로또번호3, 로또번호4, 로또번호5, 로또번호6, 보너스번호
    writer.writerow([res.get('drwNo'), res.get('date')] + res.get('lottoNumb') + [res.get('bonusNumb')])

 

전체 소스코드

마지막으로 해당 함수들을 반복문으로 태워 1화부터 최신화까지 데이터를 추출하였습니다.

import requests
from bs4 import BeautifulSoup
import csv

def get_lotto_numbers(draw_no):
    api_url = f"https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo={draw_no}"

    try:
        response = requests.get(api_url)
        response.raise_for_status()

        data = response.json()
        print(f"{draw_no}회 결과추출")
        # Request 데이터 출력
        return {
            'drwNo' : data['drwNo'],
            'date': data['drwNoDate'], 
            'lottoNumb': [str(data[f"drwtNo{i}"]) for i in range(1, 7)], 
            'bonusNumb': data['bnusNo']
        }
        
        
    except requests.exceptions.RequestException as e:
        print(f"오류가 발생했습니다: {e}")
        
def maxRound():
    url = "https://dhlottery.co.kr/common.do?method=main"
    html = requests.get(url).text
    soup = BeautifulSoup(html, "lxml")
    max_numb = soup.find(name="strong", attrs={"id": "lottoDrwNo"}).text
    return int(max_numb)

        
# 최신 회차 가져오기
maxCount = maxRound()
draw_no  = 1

# CSV 파일 쓰기
with open('lottoRes.csv', 'w', newline='') as csvfile:
    # CSV 파일 쓰기
    writer = csv.writer(csvfile, delimiter=',')
    
    # 1화부터 최신화까지 크롤링
    for draw_no in range(1, maxCount+1):
        res = get_lotto_numbers(draw_no)
        # 순서 : 회차, 날짜, 로또번호1, 로또번호2, 로또번호3, 로또번호4, 로또번호5, 로또번호6, 보너스번호
        writer.writerow([res.get('drwNo'), res.get('date')] + res.get('lottoNumb') + [res.get('bonusNumb')])