🔥알림🔥
① 테디노트 유튜브 - 구경하러 가기!
② LangChain 한국어 튜토리얼 바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs) 바로가기 🙌

4 분 소요

본 내용은 로또 사이트(동행복권) 에서 로또의 1회차 부터 최신회차까지 당첨번호, 보너스번호,당첨일자등의 정보를 크롤링 하여 데이터프레임으로 변환하고 CSV 파일형식으로 저장하는 튜토리얼입니다.

실습파일


🔥 정보 크롤링

  • 날짜

  • 당첨번호

  • 보너스번호

  • 1~5등 인당 당첨금액

  • 각 등수별 당첨자 수

import requests
from bs4 import BeautifulSoup


## 동행복권 사이트 N회차 크롤링

# 예시) 10회차 데이터 크롤링
count = 10

# url에 회차 {count} 를 실어 페이지 조회
url = f'https://dhlottery.co.kr/gameResult.do?method=byWin&drwNo={count}'
html = requests.get(url).text
soup = BeautifulSoup(html, 'lxml')

- 날짜

# 날짜 조회
soup.find('p', class_='desc')
<p class="desc">(2003년 02월 08일 추첨)</p>
# 날짜만 추출
soup.find('p', class_='desc').text
'(2003년 02월 08일 추첨)'

datetime으로 변경

from datetime import datetime

# 날짜 클린징
date = datetime.strptime(soup.find('p', class_='desc').text, '(%Y년 %m월 %d일 추첨)')
date
datetime.datetime(2003, 2, 8, 0, 0)

- 당첨번호

soup.find('div', class_='num win')
<div class="num win">
<strong>당첨번호</strong>
<p>
<span class="ball_645 lrg ball1">9</span>
<span class="ball_645 lrg ball3">25</span>
<span class="ball_645 lrg ball3">30</span>
<span class="ball_645 lrg ball4">33</span>
<span class="ball_645 lrg ball5">41</span>
<span class="ball_645 lrg ball5">44</span>
</p>
</div>
# 당첨번호 TEXT화
soup.find('div', class_='num win').find('p').text
'\n9\n25\n30\n33\n41\n44\n'
# 당첨번호 추출
soup.find('div', class_='num win').find('p').text.strip().split('\n')
['9', '25', '30', '33', '41', '44']
# int로 변경
[int(i) for i in soup.find('div', class_='num win').find('p').text.strip().split('\n')]
[9, 25, 30, 33, 41, 44]

- 보너스 번호

soup.find('div', class_='num bonus')
<div class="num bonus">
<strong>보너스</strong>
<p><span class="ball_645 lrg ball1">6</span></p>
</div>
int(soup.find('div', class_='num bonus').find('p').text.strip())
6

- 1~5등 정보 추출

soup.find('table', class_='tbl_data')
<table class="tbl_data tbl_data_col">
<caption>10회  순위별 등위별 총 당첨금액, 당첨게임 수, 1게임당 당첨금액, 당첨기준, 비고 안내</caption>
<colgroup>
<col style="width:85px"/>
<col style="width:180px"/>
<col style="width:145px"/>
<col style="width:180px"/>
<col/>
<col style="width:110px"/>
</colgroup>
<thead>
<tr>
<th scope="col">순위</th>
<th scope="col">등위별 총 당첨금액</th>
<th scope="col">당첨게임 수</th>
<th scope="col">1게임당 당첨금액</th>
<th scope="col">당첨기준</th>
<th scope="col">비고</th>
</tr>
</thead>
<tbody>
<tr>
<td>1등</td>
<td class="tar"><strong class="color_key1">83,595,692,700원</strong></td>
<td>13</td>
<td class="tar">6,430,437,900원</td>
<td>당첨번호 <strong class="length">6개</strong> 숫자일치</td>
<td rowspan="5">
</td>
</tr>
<tr>
<td>2등</td>
<td class="tar"><strong class="color_key1">9,631,962,400원</strong></td>
<td>236</td>
<td class="tar">40,813,400원</td>
<td class="nobd_right">당첨번호 <strong class="length">5개</strong> 숫자일치<br/>+<strong class="length">보너스</strong> 숫자일치</td>
</tr>
<tr>
<td>3등</td>
<td class="tar"><strong class="color_key1">9,631,930,800원</strong></td>
<td>11,247</td>
<td class="tar">856,400원</td>
<td class="nobd_right">당첨번호 <strong class="length">5개</strong> 숫자일치</td>
</tr>
<tr>
<td>4등</td>
<td class="tar"><strong class="color_key1">19,198,288,200원</strong></td>
<td>703,234</td>
<td class="tar">27,300원</td>
<td class="nobd_right">당첨번호 <strong class="length">4개</strong> 숫자일치</td>
</tr>
<tr>
<td>5등</td>
<td class="tar"><strong class="color_key1">34,108,460,000원</strong></td>
<td>3,410,846</td>
<td class="tar">10,000원</td>
<td class="nobd_right">당첨번호 <strong class="length">3개</strong> 숫자일치</td>
</tr>
</tbody>
</table>
import pandas as pd

df = pd.read_html(str(soup.find('table', class_='tbl_data')))[0]
df
순위 등위별 총 당첨금액 당첨게임 수 1게임당 당첨금액 당첨기준 비고
0 1등 83,595,692,700원 13 6,430,437,900원 당첨번호 6개 숫자일치 NaN
1 2등 9,631,962,400원 236 40,813,400원 당첨번호 5개 숫자일치 +보너스 숫자일치 NaN
2 3등 9,631,930,800원 11247 856,400원 당첨번호 5개 숫자일치 NaN
3 4등 19,198,288,200원 703234 27,300원 당첨번호 4개 숫자일치 NaN
4 5등 34,108,460,000원 3410846 10,000원 당첨번호 3개 숫자일치 NaN

- 1회차부터 N회차 정보 일괄 크롤링

def crawling_lotto(count):
    # url에 회차를 실어 페이지 조회
    url = f'https://dhlottery.co.kr/gameResult.do?method=byWin&drwNo={count}'
    html = requests.get(url).text
    soup = BeautifulSoup(html, 'lxml')
    
    date = datetime.strptime(soup.find('p', class_='desc').text, '(%Y년 %m월 %d일 추첨)')
    win_number = [int(i) for i in soup.find('div', class_='num win').find('p').text.strip().split('\n')]
    bonus_number = int(soup.find('div', class_='num bonus').find('p').text.strip())
    
    return {
        'date': date, 
        'win_number': win_number, 
        'bonus_number': bonus_number
    }
# 2회차 샘플 크롤링
result = crawling_lotto(2)
# 데이터프레임 출력
data = pd.DataFrame()
data = data.append({'date': result['date'],
                    'num1': result['win_number'][0],
                    'num2': result['win_number'][1],
                    'num3': result['win_number'][2],
                    'num4': result['win_number'][3],
                    'num5': result['win_number'][4],
                    'num6': result['win_number'][5],
                    'bonus': result['bonus_number'],
                   }, ignore_index=True)
data
date num1 num2 num3 num4 num5 num6 bonus
0 2002-12-14 9 13 21 25 32 42 2

🔥 최신 회차 가져오기

url = 'https://dhlottery.co.kr/common.do?method=main'
html = requests.get(url).text
soup = BeautifulSoup(html, 'lxml')
# 최신 회차 출력
max_count = int(soup.find('strong', id='lottoDrwNo').text)
max_count
1052

🔥 [최종코드] 1회 ~ 최신회차 크롤링

import warnings
import requests
from datetime import datetime
from tqdm.notebook import tqdm
import pandas as pd
from bs4 import BeautifulSoup


# wanring 메시지 출력 안함
warnings.filterwarnings('ignore')

# 최신 회차 크롤링 함수
def get_max_count():
    url = 'https://dhlottery.co.kr/common.do?method=main'
    html = requests.get(url).text
    soup = BeautifulSoup(html, 'lxml')
    max_count = int(soup.find('strong', id='lottoDrwNo').text)
    return max_count

# 로또 당첨번호 정보 조회 함수
def crawling_lotto(count):
    # url에 회차를 실어 페이지 조회
    url = f'https://dhlottery.co.kr/gameResult.do?method=byWin&drwNo={count}'
    html = requests.get(url).text
    soup = BeautifulSoup(html, 'lxml')
    
    date = datetime.strptime(soup.find('p', class_='desc').text, '(%Y년 %m월 %d일 추첨)')
    win_number = [int(i) for i in soup.find('div', class_='num win').find('p').text.strip().split('\n')]
    bonus_number = int(soup.find('div', class_='num bonus').find('p').text.strip())
    
    return {
        'date': date, 
        'win_number': win_number, 
        'bonus_number': bonus_number
    }

# 최신 회차 가져오기
max_count = get_max_count()
# 전체 회차 크롤링
data = pd.DataFrame()
for i in tqdm(range(1, max_count+1)):
    result = crawling_lotto(i)
    data = data.append({'date': result['date'],
                        'num1': result['win_number'][0],
                        'num2': result['win_number'][1],
                        'num3': result['win_number'][2],
                        'num4': result['win_number'][3],
                        'num5': result['win_number'][4],
                        'num6': result['win_number'][5],
                        'bonus': result['bonus_number'],
                       }, ignore_index=True)
data
  0%|          | 0/1052 [00:00<?, ?it/s]
date num1 num2 num3 num4 num5 num6 bonus
0 2002-12-07 10 23 29 33 37 40 16
1 2002-12-14 9 13 21 25 32 42 2
2 2002-12-21 11 16 19 21 27 31 30
3 2002-12-28 14 27 30 31 40 42 2
4 2003-01-04 16 24 29 40 41 42 3
... ... ... ... ... ... ... ... ...
1047 2022-12-31 6 12 17 21 32 39 30
1048 2023-01-07 3 5 13 20 21 37 17
1049 2023-01-14 6 12 31 35 38 43 17
1050 2023-01-21 21 26 30 32 33 35 44
1051 2023-01-28 5 17 26 27 35 38 1

1052 rows × 8 columns

CSV로 저장

data.to_csv('lotto-1052.csv', index=False)

댓글남기기