본문 바로가기
컴퓨터관련

python 이용하여 로또 사이트 크롤링 - 당첨정보 가져오기 및 분석

by 기록이답이다 2019. 3. 6.
반응형

이전에 작성한 공공데이터포털 api 목록 저장하기 에서 파이썬을 사용 후 빠르고 간편하게
작성할 수 있어 파이썬을 다시 보고 있는 중입니다.

[컴퓨터관련] - python 이용하여 공공DataPortal 제공서비스 목록 파일로 저장하기(beautifulsoup, selenium 이용)

 

 

이번에 해볼것은 Lotto사이트의 Lotto 정보 크롤링입니다.

Lotto 정보를 가져와서 통계를 내고 데이터를 추출하고 하면 재미있을것 같습니다.

 

우선 테이블을 만듭니다

/** 로또정보 테이블 **/
create table lotto (
	lotto_no int primary key comment '회차',
	tot_money bigint comment '총판매금',
	wintp_auto int comment '당첨유형-자동', 
	wintp_semiauto int comment '당첨유형-반자동',
	wintp_manual int comment '당첨유형-수동',
                pick_date varchar(8) comment '추첨일자',
	wdate datetime comment '등록일시'
)
; 

/** 로또당첨번호 테이블 **/
create table lotto_win_number (
  lotto_no int comment '회차',
  win_no int comment '당첨번호',
  is_bonus enum('Y', 'N') default 'N' comment '보너스번호 여부',
  wdate datetime comment '등록일시'
)
;

/** 로또 당첨금액 정보 테이블 **/
create table lotto_money (
	lotto_no int comment '회차',
	rank int comment '등',
	rank_tot_money bigint comment  '등수별 당첨금',
	win_cnt int comment '당첨자수',
	money bigint comment '당첨금액',
	wdate datetime comment '등록일시'
)
;

alter table lotto_money add primary key (lotto_no, rank);

 

아래는 데이터를 가져오는 소스입니다.

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import pymysql
import re
 
from selenium import webdriver
from bs4 import BeautifulSoup
 
#문자열에서 숫자을 찾아 return
def getNumberFrom(str):
    return int("".join(re.findall("\\d+", str)))
 
coptions = webdriver.ChromeOptions()
coptions.add_argument('headless')
coptions.add_argument('window-size=1920x1080')
coptions.add_argument("disable-gpu")
coptions.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36")
 
driver = webdriver.Chrome('c:\\dev\\chromedriver.exe', options=coptions)
 
# 동행복권url
driver.get(url)
html = driver.page_source
 
soup = BeautifulSoup(html, 'html.parser')
 
# 현재회차 lotto 번호
lastLottoNo = getNumberFrom(soup.select("div.win_result > h4 > strong")[0].get_text())
 
# db 접속
conn = pymysql.connect(host="localhost", user="lotto", password="lotto", db="lotto", charset="utf8")
 
curs = conn.cursor()
 
try :
    # 1회차부터 마지막회차까지 정보 가져오기
    for i in range(1, lastLottoNo+1):
        lottoData=[] # 로또정보
        lottoMoneyDatas = [] # 로또당첨금정보
        lottoWinNumbers = [] # 로또당첨번호정보
     
        html = driver.page_source
     
        soup = BeautifulSoup(html, 'html.parser')
     
        lottoNo = getNumberFrom(soup.select("div.win_result > h4 > strong")[0].get_text())
        lottoData.append( lottoNo )
     
        #총판매금액
        totMoney = soup.select("ul.list_text_common > li > strong")[0].get_text()
        nos = soup.select("span.ball_645")
        winNo = ""
        bonus= ""
        idx = 0
     
        for no in nos:
            lottoWinNumber = []
            isBonus = "N"
            if idx == len(nos)-1:
                winNo = no.get_text()
                isBonus = "Y"
            else :
                winNo = no.get_text()
     
            lottoWinNumber.append(lottoNo)
            lottoWinNumber.append(getNumberFrom(winNo))
            lottoWinNumber.append(isBonus)
            lottoWinNumbers.append(lottoWinNumber)       
     
            idx = idx+1          
     
        ranks = soup.select("table.tbl_data > tbody > tr")
        for rank in ranks:
            lottoMoneyData = []
            lottoMoneyData.append( lottoNo )
            lottoMoneyData.append(getNumberFrom(rank.select("td:nth-of-type(1)")[0].get_text())) # 등수
            lottoMoneyData.append(getNumberFrom(rank.select("td:nth-of-type(2)")[0].get_text())) # 등수별 총 당첨금
            lottoMoneyData.append(getNumberFrom(rank.select("td:nth-of-type(3)")[0].get_text())) # 당첨자수
            lottoMoneyData.append(getNumberFrom(rank.select("td:nth-of-type(4)")[0].get_text())) # 개별당첨금액
     
            if(len(rank.select("td")) == 6):
                gameInfo = re.sub("\\s+", "", re.sub("\\n", "^", rank.select("td:nth-of-type(6)")[0].text)) # 당첨유형
                winAuto = 0
                winSemiAuto = 0
                winManual = 0
     
                infos = gameInfo.split("^")
                for info in infos:
                    if info == "":
                        continue
                    elif info.startswith("자동"):
                        winAuto = getNumberFrom(info)
                    elif info.startswith("반자동"):
                        winSemiAuto = getNumberFrom(info)   
                    elif info.startswith("수동"):
                        winManual = getNumberFrom(info)
     
            lottoMoneyDatas.append(lottoMoneyData)
     
        pickDate = getNumberFrom(soup.select("div.win_result > p.desc")[0].get_text())
        lottoData.extend( [getNumberFrom(totMoney), winAuto, winSemiAuto, winManual, pickDate] )
          
        sql = """insert into lotto ( lotto_no, tot_money, wintp_auto, wintp_semiauto, wintp_manual, pick_date, wdate )
        values (%s, %s, %s, %s, %s, %s, now())"""
        curs.execute(sql, lottoData)
     
        lottoWinNumberSql = """insert into lotto_win_number ( lotto_no, win_no, is_bonus, wdate)
        values (%s, %s, %s, now())"""
        curs.executemany(lottoWinNumberSql, lottoWinNumbers)
     
        lottoMoneySql = """insert into lotto_money ( lotto_no, rank, rank_tot_money, win_cnt, money, wdate)
        values (%s, %s, %s, %s, %s, now())"""
        curs.executemany(lottoMoneySql, lottoMoneyDatas)
     
        print("%d회 정보 입력완료\n" % lottoNo)
        if lottoNo % 50 == 0:
            conn.commit()       
 
finally:   
    conn.commit()
    curs.close()
    conn.close()  

 

위 데이터로 확인해본 결과 가장 많이 나온 숫자는 43입니다.

아래 이미지는 가장 많이 나온 숫자들입니다.

 

 

 

 

ps. 가져온 정보를 가지고 사이트를 하나 만들어봐야겠습니다.

로또 분석법 말이 많던데.. 한번 비슷하게 만들어볼까봐요 ( 할 수 있으려나... )

 

 

 

반응형