고흐의 연구실/Python

[Selenium + Python] 초간단 잔여좌석 알림 시스템 제작(대저해운)

전고흐 2022. 4. 28. 16:09
728x90

0. 개요

울릉도 배편 잔여석을 가져오기 위해 제작함.

 

1. 주요 기능

잔여석이 나오면, 메일로 바로 알림을 받을 수 있음.

 

2. 개발환경

서버 - NCloud(Ubuntu 18.04 - nano)

언어 - Python3

IDE - Pycharm

 

3. 저자 수준

파이썬 초보 + 웹에 무지함

 

4. 제작 프로세스

0)

서버에서 계속 잔여석을 확인하고 싶어서, 클라우드를 이용했습니다.

NCloud를 잘 사용하지 못해서 그런지, 리눅스 쉘 환경 너무 불편해서 Windows에서 Pycharm을 이용하여 기능 구현을 완료하였습니다.

이후, 리눅스로 옮기면서 OS 변경하면서 수정할 부분 수정하고 에러 처리 및 지속적으로 동작하게끔 cron처리하였습니다.

평소 하던 분야가 아니라 천천히 서칭 하면서 오류 해결해가는 과정 풀어내려 합니다.

순서는 제가 개발한 순으로 작성했으니 참고 바랍니다.

 

1) 크롤링 가능 여부 확인하기

크롤링이 무엇인지만 대충 알고, 작성된 코드만 돌려본 것이 전부였기에, 정확하게 맞는지는 모릅니다.(의견 주세요)

그러나 페이지에 떠있는 값을 가져올 수 있는지 정도는 확인해야 한다고 생각했습니다.

크롬 개발자 도구를 이용하여 제가 원하는 값이 코드에 들어있는지 확인했습니다.

html 페이지에 반영이 되어있다면? 긁어와서 문자열 처리를 할까도 했지만, CSS?를 써서 그런지 셀레니움을 사용해서 가져오는게 최선의 선택이라 생각했습니다.

일단, 크롬에서 값이 보이기에 개발에 착수했습니다.

내가 필요한 값(지금은 잔여석이 있지만 0이었음!)
크롬 F12를 눌러 그 값이 나오는지를 확인한다

 

2) 파이썬/크롬 개발환경 구성

파이썬을 쓰지 않다 보니, 개발환경을 우선 구축했습니다.

파이참을 설치했으며, pip과 selenium 익스텐션을 추가했다.

그리고 chromediriver 다운로드.

(경로 : https://chromedriver.chromium.org/downloads)

본인 컴퓨터에 사용하고 있는 크롬의 버전을 보고 맞는 버전을 받아야 한다.

chrome 버전 확인!

 

3) 셀레니움과 크롬이 잘 되는지 확인

테스트 코드를 실행시켜서 크롬이 잘 뜨나 보자.

from selenium import webdriver

def selenium_driver():
    options = webdriver.ChromeOptions()
    options.add_argument('window-size=1920x1080')
    options.add_argument('disable-gpu')
    options.add_experimental_option('excludeSwitches', ['enable-logging'])
    driver = webdriver.Chrome('C:/Users/real1/Desktop/test/gogo/chromedriver.exe', options=options)
    driver.implicitly_wait(10)

    return driver

if __name__ == "__main__":

        url = 'https://www.daezer.com/reserve/index.html?Kind=sun'
        driver = selenium_driver()
        driver.get(url)

위 코드를 실행하면 위와 같은 창이 뜰 것이다

잘 된다면 테스트 끝.

 

4) 코드 작성 (데이터 GET 하기)

내가 원하는 기능을 하도록 코드를 작성했다.

위 페이지에서 해야 할 것을 먼저 순서대로 정리를 한다.

 

(1) 가는 날 달력을 클릭

(2) 달력에서 월 이동

(3) 가는날 선택

(4) 오는 날 선택

(5) 선택 완료 클릭

(6) 승선인원 선택

 

위 방법대로 클릭을 하면 내가 원하는 잔여석 데이터가 나온다.

그러면 위의 프로세스대로 코드를 짜야한다.

 

난 웹알못이라.. 어려웠다.

셀레니움의 동작 원리를 보면, 엘리먼트를 찾아서 class나 id, xpath와 같이 찾고자 하는 것을 지정한 후 클릭이나 값을 가져오는 등의 행위를 하는 것 같다.

나는 간단한 클릭으로 일단 진행을 쭉 했다.

 

코드를 확인하면서 보자, 개발자 도구에서 확인한 코드와 파이썬 코드를 같이 보면 더 쉽게 이해가 될 것이다.

(1) 가는 날 달력을 클릭

driver.find_element(By.XPATH, "//*[@id='Start_Cal1']").click()

 

(2) 달력에서 월 이동

driver.find_element(By.CLASS_NAME, "ml10").click()

 

(3) 가는날 선택

driver.find_element(By.XPATH, "//*[@id='v7']").click()

 

(4) 오는 날 선택

driver.find_element(By.XPATH, "//*[@id='x13']").click()

 

(5) 선택 완료 클릭

driver.find_element(By.XPATH, "//*[@id='calenda_clo02']/img").click()

 

(6) 승선인원 선택

driver.find_element(By.ID, 'Adult').send_keys(1)

 

위 과정을 마쳤으면, 원하는 출발/도착 일자와 인원에 맞게 배편이 조회된다.

 

배편이 조회되는 과정이 시간이 걸리는 경우가 있어,

time.sleep(10) 값을 넣어주었다.

 

이후, 테이블 값을 추출하였다.

table = driver.find_element(By.XPATH, "//*[@id='schedule2']/table/tbody")
tr = table.find_elements(By.TAG_NAME, "tr")
seat = driver.find_element(By.XPATH, f"//*[@id='schedule2_list{chk+1}']/td[5]").text

 

나는 시간대 별 잔여석보다는, 해당 일자의 잔여석이 중요했기에 컬럼 수 대로 반복문을 돌려 위에서 추출된 seat값을 더해주었다.

 

그리고 그 값이 0이 아닌 경우, 내 메일로 안내를 해주도록 설계를 했다.

(smtp 사용하여 메일 전송)

 

또한, 종종 에러가 났는데 에러가 나게 되면 해당 프로세스가 exit 되어서, 오류처리를 해야 했는데 시간이 없어서 에러인 경우에 에러코드와 함께 에러라고 메일을 발송했다. 그리고 오류가 나면 접속해서 재실행해주는 노가다를 했다!

하하 다행히도 에러가 자주 나지는 않았다.

 

전체 코드는 깃헙에 그대로 올려놓아서 링크 첨부하겠습니다.

https://github.com/0silver00/GoToUlleungdo

 

GitHub - 0silver00/GoToUlleungdo: Check the remaining seats on the Ulleungdo ferry (daezer)

Check the remaining seats on the Ulleungdo ferry (daezer) - GitHub - 0silver00/GoToUlleungdo: Check the remaining seats on the Ulleungdo ferry (daezer)

github.com

 

열심히 작성하다 여러 가지 일로 인해 이제야 포스팅을 완료했습니다.

윈도우에서 테스트 작업을 하고 서버는 리눅스로 돌렸고,

리눅스로 옮기는 과정에 크롬 드라이브 사용과 다른 점이 있어 위 깃헙에는 리눅스 버전 윈도우 버전 따로 체크인해두었습니다.

많이 변경되는 것은 아니라 참조하시면 됩니다.

 

 

 

글을 작성하다가 셀레니움 사용법에 대해 잘 설명된 블로그를 발견했습니다.

그냥 따라 하는 게 아닌 어느 정도 셀레니움이 어떻게 동작하는지 알고 보면 좋을 것 같네요.

https://pythondocs.net/selenium/%EC%85%80%EB%A0%88%EB%8B%88%EC%9B%80-%ED%81%AC%EB%A1%A4%EB%9F%AC-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95/

 

 

 

728x90

'고흐의 연구실 > Python' 카테고리의 다른 글

[Selenium + Python] Tor browser(proxy)사용 ip 변경  (0) 2022.07.31