라벨이 SELENIUM인 게시물 표시

[Selenium] Selenium 을 이용하여 복권 구매 자동화 만들어보기 #6

Selenium 을 사용하여 복권 구매 자동화하기는 마무리 되었습니다. 1편  - selenium 사용할 수 있는 환경 구성하고 브라우저 열기 2편  - 불필요한 팝업 닫기 3편  - 로그인 하기 4편  - 복권 구매 하기 5편  - 코드 리펙토링 우선 복권 구매 자동화의 목적은 selenium 기초를 다루기 위함이였습니다. 다룬 개념을 보자면 find~ 를 통해 element 찾기,  클릭하기, handler 개념을 통해 팝업 닫기, iframe 환경에서 조작하기, js script 실행하기 등이 있습니다. 이 글은 selenium 기초를 다루었기 때문에 조금 더 코드를 구조적으로 리펙토링할 수 있지만 하지 않았고 로그, 예외 처리 등 중요한 내용을 다루지 않았습니다. 그러므로 해당 글은 개념으로 참고해주시면 감사하겠습니다. 총 5개의 글로 복권 구매 자동화가 마무리 되었습니다. 블로그에 처음 글을 쓴지는 꽤 되었지만 이렇게 비록 5개의 글이지만 시리즈로 글을 써본 것은 처음입니다. 글을 쓴다는 것이 간단한 내용이더라도 시간이 굉장히 많이 드는 작업이다보니 항상 미루고 하였습니다. 그렇지만 그 시간만큼 저에게 남는 것이라는 것이라고 생각이 되어 짧게나마 연재 형식으로 적어보았습니다. 점점 규모를 키워가며 연재를 해보도록 하겠습니다. 

[Selenium] Selenium 을 이용하여 복권 구매 자동화 만들어보기 #5

 이번 포스팅은 이전 글 에서 작성한 코드를 리펙토링해보려고 합니다. 리펙토링이라고 하기에는 사실 거창하기는 하지만 따라하시기 편하도록 한 개의 파일 안에서 코드 작성을 이어가고 있었습니다. 코드를 작성할 때는 당연히 이해가 가지만 조금만 시간이 지나도 이게 어떤 기능을 의미하는지 잊어버릴 때가 있습니다. 이를 방지하기 위해서는 함수로 만들어 함수 이름으로 유추하게 하던지 아니면 주석을 달면 됩니다. 때에 따라서 정답은 나뉘겠지만 오늘은 함수로 기능을 묶어 맨 하단에 함수 이름을 통해 어떠한 기능을 수행하는지 알 수 있게되면 성공입니다. 위에서 언급했듯이 아래 코드는 클릭을 하기는 하는데 저 xpath 가 무엇을 의미하는지 알기가 쉽지 않습니다. click(driver.find_element(By.XPATH, '/html/body/div[1]/header/div[2]/div[2]/form/div/ul/li[1]/a')) 그렇지만 함수로 묶어 아래로 표현하면 알 수가 있게 됩니다. def move_to_login_page():      click(driver.find_element(By.XPATH, '/html/body/div[1]/header/div[2]/div[2]/form/div/ul/li[1]/a')) 일단 로그인 관련 부분을 수정해보겠습니다. 기존의 코드는 아래와 같이 나열되어 있습니다. 이 경우 사실 어떤 행위를 하는지 나중에 봐도 알 수는 있겠지만 3줄이 연달아 있는 것이 불편합니다. 이를 함수로 묶어 두고 사용하면 훨씬 코드를 작성할 때 가독성이 좋게 될 것 입니다. 팝업 닫는 코드까지 추가하였습니다. 이는 로그인 단계에서 처리하는 것이 맞다고 생각하기 때문입니다.    기존 코드 send_keys(driver.find_element(By.ID, 'userId'), os.environ.get('ID')) send_keys(driver.find_element(By.NAME, 'pass...

[Selenium] Selenium 을 이용하여 복권 구매 자동화 만들어보기 #4

이미지
 이전 글 에서 로그인 기능을 만들어 보았습니다. 이번 글에서는 복권 구매까지 진행을 해보겠습니다. 다음글에서는 마지막 코드 리펙토링을 진행하도록 하겠습니다.  이 글을 끝에 구매 버튼이 있는데 진짜로 구매하시려면 예치금을 충전하시면 가능합니다. 복권 구매는 단계를 나누어 보면 아래와 같습니다. 1. 메인 페이지에서 복권 구매 버튼 클릭(클릭 시 팝업 열림) 2. 복권 구매 번호 랜덤으로 발행(자동번호 발행 기능이 이미 있지만 코드 예제를 위해 수동으로 진행) 3. 구매 버튼 클릭 단계를 나누어보면 새로 배울 개념이 없지만 여기서 문제라고하면 복권 구매 화면이 iframe 형식으로 구성이 되어있다는 것입니다. iframe 으로 되어있는 경우 selenium 을 통해 현재 frame 을 이동시켜줘야 원하는 element 등에 접근 가능합니다.  우선 몇 개의 함수를 먼저 작성하겠습니다. script 실행하기 def execute_script(script):      driver.execute_script(script) 윈도우 중에서 마지막에 열린 윈도우로 현재 윈도우 변경하기 def switch_to_last_opened_window():      driver.switch_to.window(driver.window_handles[-1]) iframe 으로 현재 프레임 변경하기 def switch_to_iframe(iframe):      WebDriverWait(driver, 10).until(           EC.presence_of_element_located((By.TAG_NAME, "iframe"))      )      driver.switch_to.frame(iframe) WebDriverWait(driver, 10).until(...

[Selenium] Selenium 을 이용하여 복권 구매 자동화 만들어보기 #3

이미지
 오늘은 동행복권 사이트 로그인 기능을 만들어 보려합니다. 로그인 과정에 필요한 기능은 간단하게 아래와 같습니다. 1. 버튼 클릭 기능 2. input 에 텍스트 입력 기능 이전 단계에서 팝업 닫고 메인 페이지로 돌아오도록 하였습니다. 로그인 단계를 selenium 단계로 보면 아래와 같습니다.  1. 메인페이지에서 로그인 버튼 찾기 2. 로그인 버튼 클릭 3. 아이디 input 찾기 4. 아이디 입력 5. 비밀번호 input 찾기 6. 비밀번호 입력 7. 엔터키 입력 위 작업은 간단하기 때문에 사전에 필요한 작업을 먼저 하겠습니다. python-dotenv 설치 pip install python-dotenv python-dotenv 의 역할은 .env 파일을 읽어올 수 있게 합니다. 클릭 함수 작성 def click(element):      element.click() 위 함수는 보이시는대로 element 를 넘겨주면 클릭하는 함수입니다. 문자 입력 함수 작성 def send_keys(element, text):      element.send_keys(text) 위 코드도 보이시는대로 문자를 입력하는 함수입니다. 처음 보면 생소할 수 있지만 selenium 에서는 send_keys 를 사용하여 문자를 입력합니다. 환경 변수 읽어오기 from dotenv import load_dotenv import os load_dotenv() 상단에 위 코드를 넣어줍니다. 그러면 아래 코드처럼 환경 변수 파일인 .env 파일을 불러올 수 있습니다. os.environ.get('ID')   .env 파일을 만들어서 관리하는 이유는 이 프로젝트가 private repository 이면 상관이 크게 없을 수 있지만 public 하면 .env 로 계정 정보를 나만 알 수 있도록 관리하는 것이 필요합니다. 또한 때에 따라 다를 수 있지만 .env 에 중요한 계정 정보나 키를 넣어 ...

[Selenium] Selenium 을 이용하여 복권 구매 자동화 만들어보기 #2

이미지
 오늘은 이전 글에 이어서 팝업 닫기를 해보려합니다. 이 기능을 만들 때는 상황에 따라서 여러 방법이 가능합니다.  1. 메인 URL 을 가지고 메인 페이지만 남기기 2. 팝업 URL 을 가지고 메인 페이지만 남기기 위 1, 2 번 뿐만 아니라 더 많은 접근 방법이 가능하지만 이번 글에서는 1 번에 해당하는 방식을 사용해보려 합니다. 동행복권 홈페이지 들어가보면 메인페이지와 팝업 창이 나타납니다. 이 팝업은 일시적이겠지만 꼭 팝업을 다뤄야하기 때문에 바로 다루어 보려고합니다. 설명절 관련 팝업이기 때문에 대부분의 경우는 팝업이 없을 것이라고 생각이 듭니다. 그런 경우는 어렵지 않으니 가볍게 아래 코드를 보고 넘어가도 될 것 같습니다. 1. 메인 페이지와 팝업 페이지의 핸들러 확인하기 핸들러라고 하면 각 페이지별로 고유한 ID 를 말한다고 볼 수 있습니다. 페이지별 ID 를 가지고 화면 전환 등을 할 수 있습니다. 설명이 와닿지 않을 수 있지만 오늘 예제와 나중에 다룰 부분에 다루기 때문에 금방 개념을 알 수 있을 것입니다. from selenium import webdriver from selenium.webdriver.chrome.service import Service def create_driver(): return webdriver.Chrome(service=Service('./driver/chromedriver_mac64_m1_97')) driver = create_driver() driver.get('https://dhlottery.co.kr/common.do?method=main') def get_main_handler(): for window_handle in driver.window_handles: driver.switch_to.window(window_handle) print(f'현재 핸들러 name : {driver.current_window_h...

[Selenium] Selenium 을 이용하여 복권 구매 자동화 만들어보기 #1

이미지
저는 복권을 하지는 않지만 개발하면서 꽤 중요한 순간과 연관이 되어있습니다. 처음으로 코딩을 배우며 스스로 만들어 본 프로젝트가 복권 번호를 랜덤으로 발행하여 해당 등수를 나타내주는 것이였습니다. 그리고 객체지향을 배우며 왜 상속을 해야하는지.. 다형성이 왜 중요한지 도저히 이해할 수 없는 기간에 한국 복권과 미국의 복권(파워볼) 이 비슷해보이지만 번호의 범위, 등수 선정 등 세세한 규칙들이 다른 것을 보고 Lotto Class 를 KoLotto 와 EnLotto 클래스가 상속 받고 세세한 규칙이 다른 부분은 Lotto 클래스에서 abstract 로 해놓으면 되겠구나 등이 떠오르며 객체지향의 달콤함을 맛보았던 기억이 있습니다. 이런 경험 덕분인지 Selenium 을 가지고 어떤 것을 만들어볼까 했을 때 복권이 떠올랐습니다. 이 복권 구매 자동화를 가지고 좋은 정보들을 나눌 수 있을지 살펴볼 때 꽤나 만족스러운 환경이여서 선정하였습니다.  필자 프로젝트 환경 구성 언어 - python3.9 라이브러리 - selenium 브라우저 - chrome 이번에 만들어볼 프로젝트는 다양한 라이브러리가 필요로 하지 않으니 conda 등을 사용하지 않겠습니다.  1. 드라이버 다운로드 selenium 을 사용하기 위해서는 브라우저 드라이버가 필요합니다. 다운로드 홈페이지는 아래와 같습니다. 크롬 , 엣지 , 파이어폭스 , 사파리 저의 경우는 크롬을 기준으로 말씀드리겠습니다. 다른 브라우저를 사용하셔도 대부분의 selenium 사용 방법은 똑같지만 브라우저 option 설정 등이 좀 다르다고 볼 수 있습니다. 로컬 PC 의 브라우저 버전에 맞게 드라이버를 다운로드 받아야하기 때문에 버전을 먼저 확인 해야합니다. 드라이버 다운로드 를 버전에 맞게 해줍니다. 2. 드라이버 프로젝트에 임포트 저의 경우는 dirver 디렉토리에 다운로드 받은 드라이버를 넣었습니다. 3. selenium 설치 pip install selenium 4. 테스트 코드 작성 from sele...