-
[Python, Selenium] 파이썬, 셀레늄을 이용한 로또 자동 구매 프로그램코딩/Python 2022. 7. 1. 14:37반응형
매주 사야지 사야지 하다가도 까먹고 안 사는 경우가 더 많아서
셀레늄으로 한번 만들어보았다.
구동을 위한 준비물로는
당연히 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()
반응형