본문으로 바로가기
728x90
반응형

이전글보기

[정보/Discord Bot] - [discord.py 2.0] 12. Select 기능 추가하기

[정보/Discord Bot] - [discord.py 2.0] 13. Modal 기능으로 사용자입력창 띄우기

[정보/Discord Bot] - [discord.py 2.0] 14. 오류 발생 시 예외 처리하기

[정보/Discord Bot] - [discord.py 2.0] 15. 로또복권 정보 출력하기 (beautifulsoup4 library) - #1 사전 library 준비

[정보/Discord Bot] - [discord.py 2.0] 15. 로또복권 정보 출력하기 (beautifulsoup4 library) - #2 최신 로또 번호 파싱하기


이번엔 동행복권 홈페이지에서 모든 추첨내역을 다운받아 저장하는 기능을 추가해보도록 하겠습니다 

이전에 작성했던 소스코드에서 계속 덧대어 나간다는것 잊지말아주시구요..!

이후에는 자동으로 다운받도록 수정할것이지만, 당장은 다운로드 하는 동작을 명령어로 추가했습니다.

 

전체 소스코드먼저 보여드리고 설명해드리겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import os
import discord
from discord.ext import commands
from bs4 import BeautifulSoup
import urllib.request
 
 
class LotteryFunction:
    def __init__(self):
        self.lastGameCount = None  # 1033
        self.lastGameDate = None  # (2022년 09월 17일 추첨)
        self.lastGameNumbers = []
        self.parse_newest()
        self.listFilePath = f'./lottery{self.lastGameCount}.xls'
 
    # 현재 회차 정보 파싱
    def parse_newest(self):
        self.lastGameNumbers.clear()
        url = 'https://dhlottery.co.kr/gameResult.do?method=byWin'
        webpage = urllib.request.urlopen(url)
        soup = BeautifulSoup(webpage, 'html.parser')
        self.lastGameCount = soup.select_one('div.win_result > h4 > strong').get_text().split("회")[0]
        self.lastGameDate = soup.select_one('div.win_result > p').get_text()
        numberList = soup.select('div.win_result > div > .num > p .ball_645')
        for number in numberList:
            self.lastGameNumbers.append(number.get_text())
 
    # 모든 추첨 번호 다운 로드
    def download_total(self):
        if os.path.isfile(self.listFilePath):
            print("lottery list exist")
        else:
            self.delete_list('*[0-9].xls')
            start_count = 1
            url = f'https://dhlottery.co.kr/gameResult.do?method=allWinExel&gubun=byWin&nowPage=1&' \
                  f'drwNoStart={start_count}&drwNoEnd={self.lastGameCount}'
            urllib.request.urlretrieve(url, self.listFilePath)
 
 
class Lottery(commands.Cog):
    def __init__(self, app):
        self.app = app
        self.lottery = LotteryFunction()
 
    @commands.command(name="로또")
    async def lottery(self, ctx):
        self.lottery.parse_newest()
        embed = discord.Embed(title="로또 추첨 번호", description="최근 로또 번호를 출력합니다", colour=0xffffff)
        embed.set_thumbnail(url="https://dhlottery.co.kr/images/layout/logo-header.png")
        # 데이터로부터 추첨날짜 확인
        embed.add_field(name="추첨날짜", value=self.lottery.lastGameDate, inline=True)
        # 데이터로부터 회차 확인
        embed.add_field(name="회차", value=self.lottery.lastGameCount+"회", inline=True)
        embed.add_field(name="추첨번호", value=self.lottery.lastGameNumbers, inline=False)
        await ctx.send(embed=embed)
 
    @commands.command(name="다운")
    async def download_list(self, ctx):
        msg = await ctx.send("다운로드 시작")
        self.lottery.download_total()
        await ctx.message.delete()
        await msg.delete()
        await ctx.send("다운로드 완료", delete_after=5)
 
 
async def setup(app):
    await app.add_cog(Lottery(app))
 
cs

새롭게 추가된 동작은 "다운" 명령어가 호출하는 함수입니다.

 


먼저 전체 회차 당첨 번호를 다운받는 동작을 하는 LotteryFunction 클래스의 download_total 함수먼저 설명드리겠습니다. 

self.listFilePath = f'./lottery{self.lastGameCount}.xls'

14 : 모든 로또 당첨 번호를 저장하기 위한 파일 경로를 멤버변수로 미리 저장해둡니다.

 

def download_total(self):

29 : 동행복권 홈페이지로부터 당첨번호를 다운로드 받는 동작을 구현할 함수를 정의합니다.

 

        if os.path.isfile(self.listFilePath):
            print("lottery list exist")

30~31 : 이미 당첨번호 리스트를 다운받았을 경우 아무동작하지 않는 if 문입니다.

 

        else:
            self.delete_list('*[0-9].xls')
            start_count = 1
            url = f'https://dhlottery.co.kr/gameResult.do?method=allWinExel&gubun=byWin&nowPage=1&' \
                  f'drwNoStart={start_count}&drwNoEnd={self.lastGameCount}'
            urllib.request.urlretrieve(url, self.listFilePath)

32 : 당첨번호 리스트가 없는경우(혹은 지난주인 경우) 동작하는 구문입니다.

 

self.delete_list('*[0-9].xls')

33 : 이전에 다운받았던 리스트가 있는경우 삭제합니다.

 

            start_count = 1
            url = f'https://dhlottery.co.kr/gameResult.do?method=allWinExel&gubun=byWin&nowPage=1&' \
                  f'drwNoStart={start_count}&drwNoEnd={self.lastGameCount}'

34~36 : 전체 당첨 숫자 리스트를 다운받는 url 을 세팅합니다. {start_count} 항목이 시작회차, {self.lastGameCount}가 마지막회차 입니다. 여기서 self.lastGameCount 값은 parse_newest 함수에서 파싱해서 저장하도록 되어있습니다.

 

urllib.request.urlretrieve(url, self.listFilePath)

37 : url 의 정보를 self.listFilePath 에 저장합니다.


다음은 새로 추가된 "다운" 명령어에 대한 동작설명입니다.

    @commands.command(name="다운")
    async def download_list(self, ctx):

57~58 : "다운" 명령어에 대한 동작 함수를 추가합니다.

 

msg = await ctx.send("다운로드 시작")

59 : 사용자에게 동작중이라는것을 알리기 위헤 "다운로드 시작" 메세지를 서버에 전송합니다.

 

self.lottery.download_total()

60 : 위에서 생성했던 download_total 함수를 호출합니다.

 

        await ctx.message.delete()
        await msg.delete()
        await ctx.send("다운로드 완료", delete_after=5)

61 : 사용자가 호출한 명령어 메세지 ("!다운") 을 삭제합니다.
62 : 이전에 보냈던 "다운로드 시작" 메세지를 삭제합니다.
63 : "다운로드 완료" 메세지를 서버에 전송 후, 5초뒤 삭제합니다.

 

이후 "!다운" 명령어를 사용하면 main.py 가 있는곳에 lottery****.xls 파일이 다운로드 된것을 확인하실 수 있습니다


포스팅에 사용된 모든 소스코드는 아래 Github에서 확인하실 수 있습니다.

https://github.com/aochfl/ChoRi_TestBot

 

GitHub - aochfl/ChoRi_TestBot

Contribute to aochfl/ChoRi_TestBot development by creating an account on GitHub.

github.com


참고자료

https://discord.com/developers/docs/reference - ( Discord Developer API )

https://discordpy.readthedocs.io/en/latest/index.html  -  ( discord.py library 문서 )

 

728x90
반응형