[Python, Selenium] 파이썬, 셀레늄을 이용한 로또 자동 구매 프로그램
매주 사야지 사야지 하다가도 까먹고 안 사는 경우가 더 많아서
셀레늄으로 한번 만들어보았다.
구동을 위한 준비물로는
당연히 python (3.8 이상 버전을 권장)
셀레늄 버전 4 이상 (pip로 그냥 설치하면 되는듯)
크롬드라이버 자동 업데이트를 위해서 webdriver_manager 패키지도 필요하다.
크롬드라이버는 자동설치 기능을 이용하기 때문에 따로 설치안해주어도 된다.
주의점으로는 윈도우 환경에서만 작동한다. (테스트는 안해봤지만 맥에서도 될듯)
기능은 크게 세가지
1. 예치금 잔고 체크 기능 (check_deposit 함수)
현재 예치금을 확인해서 텔레그램 메시지로 보내준다.
2. 예치금 충전 (charge_deposit 함수)
예치금 충전 버튼을 눌러서 입금계좌를 텔레그램으로 보내준다.
충전 금액은 기본값인 2만 원으로 충전되게 설정
3. 로또 구매 (buy_lotto 함수)
모드 지정에 따라 자동, 수동, 일부 수동 방식으로 구매
나는 텔레그램 토큰 정보 같은걸 config파일로 만들어서 사용하고 있다.
재활용이 편하게 전에 만들어둔걸 이렇게 쓰는데 꼭 이렇게 할 필요는 없을 것 같다.
read_config 함수의 config_data 변수를 참조해서 해당 데이터를 코드에 바로 입력해서 사용해도 무방.
사용하지 않는 기능 정보는(셀레늄 리모트, 텔레그램 불필요할 경우 토큰 정보 등) 적당히 아무 값이나 넣으면 상관없음.
봇 초기화를(bot_init함수) 안 하면 텔레그램 사용 없이 화면 출력 모드로 구동된다.
config.ini파일의 형태는 다음과 같다.
[server]
host = 셀레늄 리모트 서버 주소
[user]
id = 동행복권사이트 아이디
pwd = 비밀번호
[telegram]
token = 텔레그램봇 토큰
chat_id = 수신받을 내 챗 아이디
아래 첨부된 코드는 그 자체로 직접 구동 시 예치금 잔고 체크 및 일정 금액 이하일 경우 충전하도록 되어 있다.
그대로 사용해도 되고, 필요에 따라 수정하면 된다.
나는 아래처럼 별도 구매 파일을 작성해서 사용 중이다.
import pylotto
conf = pylotto.read_config('config.ini')
driver_type = 'local'
lotto = pylotto.DhLottery()
lotto.driver_init(driver_type, conf['host'])
lotto.bot_init(conf['token'], conf['chat_id'])
lotto.login(conf['uid'], conf['passwd'])
lotto.buy_lotto('manual', 3, [1, 2, 3, 4, 5, 6])
lotto.buy_lotto('auto', 2)
lotto.driver.quit()
자동으로 구매할 경우
buy_lotto('auto', 수량)
수동은
buy_lotto('manual', 수량, 내가 원하는 번호 리스트)
혼합방식은
buy_lotto('mixed', 수량, 일부 번호 리스트)
메인코드는 아래와 같다.
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import configparser
import time
import telegram
class DhLottery:
def __init__(self):
self.driver = None
self.deposit = None
self.bot = None
self.chat_id = None
def driver_init(self, _mode='local', _host=None):
_driver = None
if _mode == 'local':
# 크롬드라이버 자동 설치
_driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
elif _mode == 'remote':
_driver = webdriver.Remote(_host, DesiredCapabilities.CHROME)
_driver.implicitly_wait(5)
self.driver = _driver
def bot_init(self, _token, _chat_id):
self.bot = telegram.Bot(token=_token)
self.chat_id = _chat_id
def login(self, _uid, _passwd):
# 로그인 페이지 이동
_url = 'https://dhlottery.co.kr/user.do?method=login&returnUrl='
_driver = self.driver
_driver.get(url=_url)
_driver.find_element(By.XPATH, '//input[@name="userId"]').send_keys(_uid) # 아이디 입력
_driver.find_element(By.XPATH, '//input[@name="password"]').send_keys(_passwd) # 비밀번호 입력
_driver.execute_script("javascript:check_if_Valid3();") # 로그인 실행
time.sleep(3)
self.remove_popup() # 팝업창 제거함수 호출
def check_deposit(self):
# 마이페이지로 이동
_driver = self.driver
_driver.get(url='https://dhlottery.co.kr/userSsl.do?method=myPage')
# 예치금 금액 읽음
_deposit = _driver.find_element(By.XPATH, '//p[@class="total_new"]/strong').text
if self.bot is not None:
self.send_telegram(f'잔고 : {_deposit}원')
_deposit = _deposit.replace(',', '') # 천단위 쉼표 제거
print(f'잔액: {_deposit}')
self.deposit = int(_deposit)
def remove_popup(self):
_driver = self.driver
# 생성된 팝업창을 모두 닫음
_tabs = _driver.window_handles
while len(_tabs) != 1:
_driver.switch_to.window(_tabs[1])
_driver.close()
_tabs = _driver.window_handles
# 첫 창으로 돌아간다
_driver.switch_to.window(_tabs[0])
def send_telegram(self, _msg):
_msg = '<로또>\n' + _msg
self.bot.sendMessage(chat_id=self.chat_id, text=_msg)
def send_result(self, _data):
_msg = '구매성공!!\n' + '=' * 15
for _d in _data:
_msg = _msg + '\n' + ','.join(_d)
print(_msg)
self.send_telegram(_msg)
def charge_deposit(self):
# 예치금 충전 페이지로 이동
_url = 'https://dhlottery.co.kr/payment.do?method=payment'
_driver = self.driver
_driver.get(url=_url)
time.sleep(1)
_driver.execute_script("nicepayStart();") # 충전버튼 클릭
time.sleep(1)
# 충전금액
_amount = _driver.find_element(By.XPATH, '//div[@class="contents_wrap contents_result_payment"]'
'/div/table/tbody/tr[2]/td').text
# 입금계좌
_account = _driver.find_element(By.XPATH, '//span[@class="pay_lt"]').text
# 충전 금액, 계좌정보 출력하거나 텔레그램 전송
_msg = f'예치금 충전\n{_account}\n{_amount}'
if self.bot is not None:
self.send_telegram(_msg)
else:
print(_msg)
def buy_lotto(self, _mode, _amount, _nums=None):
# 메인 페이지로 이동
_url = 'https://dhlottery.co.kr/common.do?method=main'
_driver = self.driver
_driver.get(url=_url)
# 팝업창 닫음
time.sleep(3)
self.remove_popup()
# 로또 구매 페이지로 이동
_driver.execute_script('javascript:goLottoBuy(2);')
# 생성된 구매 페이지로 전환
time.sleep(3)
_tabs = _driver.window_handles
_driver.switch_to.window(_tabs[1])
# 내부 iframe으로 전환
_content = _driver.find_element(By.TAG_NAME, "iframe")
_driver.switch_to.frame(_content)
if _mode == 'manual': # 수동모드
for _n in _nums:
_driver.find_element(By.XPATH, f'//label[@for="check645num{str(_n)}"]').click()
elif _mode == 'auto': # 자동모드
_driver.find_element(By.XPATH, '//label[@for="checkAutoSelect"]').click()
elif _mode == 'mixed': # 혼합모드 (숫자 일부 지정, 나머지 자동)
for _n in _nums:
_driver.find_element(By.XPATH, f'//label[@for="check645num{str(_n)}"]').click()
_driver.find_element(By.XPATH, '//label[@for="checkAutoSelect"]').click()
# 수량 변경
_select = Select(_driver.find_element(By.XPATH, '//select[@id="amoundApply"]'))
_select.select_by_value(str(_amount))
# 수량 입력 확인
_driver.find_element(By.XPATH, '//input[@id="btnSelectNum"]').click()
# 구매하기 버튼
_driver.find_element(By.XPATH, '//input[@id="btnBuy"]').click()
# 최종 구매 확인
_driver.execute_script("javascript:closepopupLayerConfirm(true);")
# 구매 번호 불러옴
time.sleep(3)
_res1 = _driver.find_elements(By.XPATH, '//ul[@id="reportRow"]/li')
# 구매된 번호들을 인식
_result = list()
for _r1 in _res1:
_selected = list()
_res2 = _r1.find_elements(By.XPATH, 'div[@class="nums"]/span')
for _r2 in _res2:
_selected.append(_r2.text)
_result.append(_selected)
# 인식된 번호 텔레그램 전송
if self.bot is not None:
self.send_result(_result)
else:
print(_result)
# iframe에서 기본 창으로 다시 변경
_driver.switch_to.default_content()
def read_config(_conf_file):
_config = configparser.ConfigParser()
_config.read(_conf_file)
_config_data = {
'host': _config['server']['host'], # Selenium Remote 주소
'uid': _config['user']['id'], # 동행복권 아이디
'passwd': _config['user']['pwd'], # 동행복권 비밀번호
'token': _config['telegram']['token'], # 텔레그램봇 토큰
'chat_id': _config['telegram']['chat_id'] # 텔레그램 전송받을 챗아이디
}
return _config_data
if __name__ == '__main__':
conf = read_config('config.ini')
driver_type = 'local'
lotto = DhLottery()
lotto.driver_init(driver_type, conf['host'])
lotto.bot_init(conf['token'], conf['chat_id']) # 텔레그램 불필요시 비활성화
lotto.login(conf['uid'], conf['passwd'])
time.sleep(1)
lotto.check_deposit()
if lotto.deposit <= 10000:
lotto.charge_deposit()
lotto.driver.quit()