ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • engoo 수업 selenium으로 자동 예약 만들기 시행착오들
    컴퓨럴/후로그람스 2017. 4. 11. 17:37

     engoo 자동예약 프로그램은 http://dizwe.tistory.com/21에 자세히 적어두었다. 아래 글은 과정 중에 겪었던 시행착오들을 기록한 글이다.

     일상생활에 불편한 점들이 있으면 프로그램으로 해결책을 찾아보려고 노력한다. engoo 화상영어(www.engoo.co.kr)는 매일 아침 7시 30분에 알람이자 영어공부 용도로 사용하고 있다.  engoo는 보통 회사와 달리 매일 직접 수업 예약을 해줘야한다. 회사 입장에서는 좋은 선생님을 한 학생이 선점하고 있다면 공정한 기회를 줄 수 없다고 생각했겠지만 매일 사이트에 들어가서 예약을 해야하는건 정말 귀찮은 일이다. 예약을 까먹어서 수업을 놓친 것도 한두번이 아니다.

     크롤링처럼 수업신청을 POST 해주면 될것 같다는 막연한 생각에 코드를 짜기 시작했다. 막연한 생각은 시간과 정신노동을 요구한다는 건 얼마 되지않아 느꼈다. 아래는 내가 시도해봤던 여러 시행착오들이다. 결국 해결하지 못한 것들도 있다.


    1. requests를 이용해 로그인하는 문제 - 실패
     일반 사이트들을 크롤링 할때에는 headers와 form-data들만 잘 조정하면 문제 없이 로그인 되었다. 하지만 engoo는 이리저리 조정해보아도 해결되지 않았다. 로그인을 유지하기 위해 session을 사용해도 로그인이 되는듯 했다가도 403에러를 내뿜었다. 단지 일시적으로 생성되는 cookie로만 로그인이 되었다. 페이스북 커뮤니티에 질문을 해보니 이런 사이트들은 되도록이면 selenium을 사용하는 것이 좋을거라는 조언을 들었다. 며칠 이리저리 시도해보다가 굳이 이 프로그램의 속도가 중요하지 않은데 Selenium을 배제 할 필요가 없다는 생각이 들었고 깔끔하게 requests 로그인을 포기하기로 했다. 


    2. Selenium에서 modal popup창 안 버튼 클릭하기 - 성공
     Selenium 사용법은 
    https://beomi.github.io/2017/02/27/HowToMakeWebCrawler-With-Selenium/ 를 참고했다 
     Selenium을 사용하니 로그인문제는 속시원하게 바로 해결되었다(이럴때면 내가 이러려고 며칠 고생했나 싶다). 하지만 예약하는 버튼을 누르는 부분에서 문제가 생겼다. 계속 
    Message: element not visible 오류가 나고 버튼이 눌러지지 않았다. google에 검색하려고 해도 도대체 어떻게 검색해야할지 알 수가 있나... popup/fade in popup 등 여러 검색을 해보다가(말이 쉽지 이것저것 다 시도해보면 한참 걸린다) javascript 실행 함수도 찾아보고 했지만 계속 오류만 나왔다. 

    빌어먹을 modal

     그러다 HTML source를 보니 modal이라는 창 안에 버튼이 들어있었고 해결책을 찾았다. 

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="modal-book-lesson modal modal-middle modal-effect-scale fade in" id="teacher_booked_modal" role="dialog" tabindex="-1" style="display: block;">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header modal-book-lesson-header">
            <button aria-label="Close" class="close" data-dismiss="modal" type="button">...</button>
              ...
            <input class="btn button button-primary btn-book" data-disable-with="수업 예약하기" id="reserve_id" name="commit" ...>
     
    cs

    https://goo.gl/XB1X9E에서 jquery로 실행되는 modal은 켜지는데 시간이 좀 걸리는데 Selenium은 그걸 기다리지 않고 element를 찾으려고 하니 없다고 뜬다. 때문에 modal창이 뜨기전에 time.sleep(3)를 실행해야 한다.


    3. PhatomJs는 time.sleep(3)이 되지 않는다. - 실패

     Chrome selenium으로 예약을 만들고 PhantomJs로 headless하게 실행하려고 하니 또 Element is not currently interactable and may not be manipulated라는 오류가 떴다. 구글링 결과 PhantomJS는 기본적으로 time.sleep(3)을 한다고 기다려주지 않는다고 한다. 때문에 윈도우 사이즈를 조정하거나 다른 요소를 찾는 행위를 반복해서 사이트가 뜨기를 기다리거하 하는 방법을 추천했는데 다 실패했다..

    방법1. 사이즈 늘리기

    driver.set_window_size(1440, 900) # change size of window
    driver.maximize_window()

    방법2. 시간차두기

    driver.execute_script('setTimeout(function(){"scroll(0, 300);"}, 3600);')
    driver.set_page_load_timeout(10)
    driver.set_script_timeout(3)
    driver.implicitly_wait(10)
    방법3. 조건두기

    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "book_img")))

     에이 어차피 컴퓨터로 돌릴거... 하면서 일단 보류하기로 했다.

    4. python코드 자동 실행하기
     이 프로그램의 핵심이다. python코드가 자동으로 실행되지 않으면 만든게 무슨 의미가 있겠는가. 처음에 서버사이드로 돌려서 프로그램을 자동실행하게 해볼까 했지만 원하는 기능을 구현하기 위해 너무 많은 시간을 잡아먹을 듯했다. 그러다 윈도우 자동 스케줄러를 발견했다(http://fnmj.tistory.com/19 참조)! 시간이나 조건만 잘 조정하면 프로그램이 자동으로 실행된다. 나는 매일 7시 53분, 로그인할 때마다 실행되도록 트리거를 주었다.

     더하기. 만들면서 역시 글로 배우는거랑 직접 해보는 거랑 천지차이라는게 느껴진다. 금방 해결될 것 같았던 문제들이 여러가지 이슈들로 막힌다. 그럴 때 '이 기능을 실현하기 위해 이 방법밖에 없을까?'하는 질문을 해야겠다는 생각이 들었다. 또 html 코드도 자세히 살펴보지 않고 구글 검색만 주구장창 했던 것을 생각하면 나와 다른 상황인 구글 질문 답변들만 찾아다니지 말고 지금 내가 해결해나가야 할 문제 자체를 debugging 해 볼 필요가 있다.


Designed by Tistory.