본문 바로가기
컴퓨터관련

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);

 

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

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
url = "https://www.dhlottery.co.kr/gameResult.do?method=byWin&drwNo="; 
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 = [] # 로또당첨번호정보
    
        driver.get("https://www.dhlottery.co.kr/gameResult.do?method=byWin&drwNo=%d" % i)
        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. 가져온 정보를 가지고 사이트를 하나 만들어봐야겠습니다.

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

 

 

 

반응형