파이썬 실전/로또 번호 생성기

파이썬 실전) 로또 번호 생성기 5. 이전 회차 당첨번호

마리사라 2021. 2. 11. 23:11
반응형

이번 강의는 requests와 BeautifulSoup를 이용하여 이전 회차 당첨 번호를 조회하는 코드를 만들어 보겠습니다.


1. 이전 회차 당첨 번호

네이버 로또 당첨번호

보통 로또 당첨번호를 조회하실 때에는 네이버에서 확인하실 겁니다. 한국인이 가장 많이 사용하는 검색 엔진이기도 하고, 로또 번호라고 입력만 하면 바로 당첨번호가 조회가 되니 일반적으로는 가장 편하게 당첨번호를 조회하는 방법일 것입니다.

 

파이썬에서 네이버의 당첨번호를 조회하기 위해서는 로또 번호를 검색한 결과 화면에서 위의 번호를 추출해야 합니다. 하지만 네이버는 일반적인 파이썬 requests의 접근을 정상적으로 인식하지 못하는 경우가 많아서 사용하기 힘들 때가 있습니다.

 

동행복권 홈페이지 당첨번호

동행 복권 홈페이지에서는 메인 화면에 당첨번호를 공지하고 있습니다. 동행 복권 홈페이지는 requests를 통해 접속해도 아무 문제없이 모든 정보를 전송해 줍니다. 그래서 네이버보다는 검색 결과를 조회하기 편합니다.

 

좌 : 네이버 당첨번호의 html / 우 : 동행복권 당첨번호의 html

네이버에서는 당첨 번호를 표시하기 위해 class의 이름을 당첨 번호와 똑같은 번호로 사용중입니다. 그렇기에 당첨번호를 정확하게 찾기 위해서는 class="num_box"의 하위 class들을 조회하는 코드의 형식으로 짜야하므로 코드가 필요 이상으로 길어집니다. 하지만 동행 복권에서는 모든 id를 No1부터 No6까지 지정해두었기에 각각의 당첨 번호를 id별로 바로바로 추출해서 저장이 가능합니다. 따라서 이번 이전 회차 당첨번호 조회 기능에서는 동행 복권에서 정보를 받아오도록 하겠습니다.


2. 코드

우선 requests모듈과 BeautifulSoup모듈을 import해 줍니다.

import requests
from bs4 import BeautifulSoup

해당 모듈이 있어야 HTTP 통신이 가능하며, HTML코드에서 정보를 추출할 수 있습니다.

 

이후 url을 지정해 줍니다. url은 동행복권 홈페이지로 설정합니다.

url = "https://dhlottery.co.kr/common.do?method=main"

 

이제 requests모듈을 통해 동행복권 사이트의 정보를 얻어오는 get통신을 합니다.

query = requests.get(url=url)

 

동행 복권 사이트에서 얻어온 정보를 사용하기 좋게 BeautifulSoup를 통해 가공합니다.

soup = BeautifulSoup(query.content, "html.parser")

 

가공된 데이터에서 id="drwtNo1"부터 id="drwtNo6"까지 추출합니다. 보너스 번호는 의미가 없으므로 추출하지 않겠습니다만 필요하신 분들은 id="bnusNo"를 추출하시면 됩니다.

no_1 = soup.find("span", {"id": "drwtNo1"})
no_2 = soup.find("span", {"id": "drwtNo2"})
no_3 = soup.find("span", {"id": "drwtNo3"})
no_4 = soup.find("span", {"id": "drwtNo4"})
no_5 = soup.find("span", {"id": "drwtNo5"})
no_6 = soup.find("span", {"id": "drwtNo6"})

 

위의 데이터들을 하나의 list 자료형에 담아줍니다. 이때 저장되는 타입은 int형으로 저장하는 것이 좋습니다.

extract_number = [int(no_1.get_text()), int(no_2.get_text()), int(no_3.get_text()), int(no_4.get_text()), int(no_5.get_text()), int(no_6.get_text())]

 

마무리로 위의 코드를 하나의 함수로 만들어서 이전 회차 당첨번호를 return하도록 합니다.

def extractor(self):
    url = "https://dhlottery.co.kr/common.do?method=main"
    query = requests.get(url=url)
    soup = BeautifulSoup(query.content, "html.parser")
    no_1 = soup.find("span", {"id": "drwtNo1"})
    no_2 = soup.find("span", {"id": "drwtNo2"})
    no_3 = soup.find("span", {"id": "drwtNo3"})
    no_4 = soup.find("span", {"id": "drwtNo4"})
    no_5 = soup.find("span", {"id": "drwtNo5"})
    no_6 = soup.find("span", {"id": "drwtNo6"})
    extract_number = [int(no_1.get_text()), int(no_2.get_text()), int(no_3.get_text()), int(no_4.get_text()),
                      int(no_5.get_text()), int(no_6.get_text())]
    return extract_number

이때, class Mainframe에 함수를 추가한다면 함수 인자에 self는 반드시 포함되어야 하며 class 밖에 추가한다면 self는 제거해 주셔야 합니다.

 

정상적으로 작동하는지 테스트 하기 위해 print문을 추가해 보았습니다.

print(self.extractor())

class 안에서 함수의 호출은 반드시 self를 통해서 이루어집니다.

 

이제 결과를 확인해 보겠습니다.

동행 복권 사이트의 당첨번호와 같은 번호가 print 되는 것을 볼 수 있습니다.


3. 마치며

이번 시간에는 여러 필터링의 베이스가 되는 이전 회차 당첨번호를 받아오는 코드를 작성해 보았습니다. 여러 로또 번호 사이트들에서는 이전 회차 당첨번호를 토대로 몇 가지 필터를 사용 중이며, 다음 시간부터 해당 필터들을 만들어 보겠습니다.

import random
import wx
import requests
from bs4 import BeautifulSoup


class Mainframe(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 450))
        panel = wx.Panel(self)
        self.count = wx.TextCtrl(panel, id=1, pos=(5, 5))
        self.count.SetHint("시행 횟수 입력")
        self.generate_button = wx.Button(panel, id=2, label='생성', pos=(5, 50))
        self.output = wx.ListBox(panel, id=3, choices=[], pos=(120, 5), size=(150, 400))

        fixed_number_box = wx.StaticBox(panel, id=5, label="고정수", pos=(5, 100), size=(80, 50))
        self.fixed_number_1 = wx.TextCtrl(fixed_number_box, id=6, size=(30, 20), pos=(5, 20))
        self.fixed_number_2 = wx.TextCtrl(fixed_number_box, id=7, size=(30, 20), pos=(40, 20))
        self.fixed_number_check = wx.CheckBox(panel, id=8, pos=(100, 120))

        self.consecutive_number = wx.CheckBox(panel, id=9, pos=(10, 160), label="연속수 제거")

        self.Bind(wx.EVT_BUTTON, self.lotto, id=2)

        print(self.extractor())

    def lotto(self, event):
        for i in range(int(self.count.GetValue())):
            number = set()
            if self.fixed_number_check.GetValue():
                try:
                    fixed_number_1 = int(self.fixed_number_1.GetValue())
                    number.add(fixed_number_1)
                except:
                    pass
                try:
                    fixed_number_2 = int(self.fixed_number_2.GetValue())
                    number.add(fixed_number_2)
                except:
                    pass
            while len(number) < 6:
                number.add(random.randint(1, 45))
                if len(number) == 6:
                    number = list(number)
                    number.sort()
                    if self.consecutive_number.GetValue():
                        for j in range(len(number) - 1):
                            try:
                                if number[j] + 1 == number[j + 1]:
                                    del number[j + 1]
                            except:
                                pass
                        if not len(number) == 6:
                            number = set(number)
                            if self.fixed_number_check.GetValue():
                                try:
                                    fixed_number_1 = int(self.fixed_number_1.GetValue())
                                    number.add(fixed_number_1)
                                except:
                                    pass
                                try:
                                    fixed_number_2 = int(self.fixed_number_2.GetValue())
                                    number.add(fixed_number_2)
                                except:
                                    pass
            self.output.Append(str(number))

    def extractor(self):
        url = "https://dhlottery.co.kr/common.do?method=main"
        query = requests.get(url=url)
        soup = BeautifulSoup(query.content, "html.parser")
        no_1 = soup.find("span", {"id": "drwtNo1"})
        no_2 = soup.find("span", {"id": "drwtNo2"})
        no_3 = soup.find("span", {"id": "drwtNo3"})
        no_4 = soup.find("span", {"id": "drwtNo4"})
        no_5 = soup.find("span", {"id": "drwtNo5"})
        no_6 = soup.find("span", {"id": "drwtNo6"})
        extract_number = [int(no_1.get_text()), int(no_2.get_text()), int(no_3.get_text()), int(no_4.get_text()),
                          int(no_5.get_text()), int(no_6.get_text())]
        return extract_number


def run():
    app = wx.App()
    frame = Mainframe(None, -1, 'Lotto Number Generator')
    frame.Show()
    app.MainLoop()


run()
반응형