ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [python] 학교 급식 메뉴 출력 프로그램
    카테고리 없음 2022. 2. 2. 13:50

    학교에서 매일 급식을 보러 게시판을 보거나 학교 홈페이지에 들어가는 것이 너무 귀찮았다. 그리고 최근에 웹스크래핑에 대해 공부해보았다. 유튜브 영상이나 구글링이 내 선생님! 그래서 우리 학교 홈페이지에 접속하여 내게 필요한 정보인 식단표를 스크래핑 해올 것이다. 학교는 진산과학고~

    처음에는 beautifulsoup 모듈을 사용하여 만들었다. 하지만 그렇게 했을 때는 한 달의 조식과 중식, 석식 들의 사이트 URL이 같게 나타났다. 그래서 중식의 식단을 스크래핑 해오는 것은 간단했지만, 조식과 석식은 추출해오지 못하였다. 

    학교 홈페이지 식단안내 페이지

    그래서 selenium 모듈을 사용하여 직접 소프트웨어를 사용하여 원격으로 접속하여 조식/중식/석식의 버튼을 클릭하면서 필요한 자료를 스크래핑 해오도록 하였다. 

    식단안내의 URL은 다음과 같다. http://ijss.icehs.kr/foodlist.do?year=2021&month=12&m=02050101&s=ijss 

    URL의 year=뒤의 정보나 month=뒤의 정보를 바꾸어 사용하면 원하는 연도의 원하는 달의 중식 식단안내에 접속할 수 있다. 입력받은 값에 따라 URL에 접속한 뒤 알맞은 급식 시간의 식단 정보들을 스크래핑 할 것이다. 

    코드는 다음과 같다. 

    코드

    from selenium import webdriver
    
    def menuprint(t):
        try:
            global all_menu
    
            browser.find_element_by_id(t).click()
            menu = browser.find_element_by_xpath(f"//*[@title='{date}일 식단 상세보기 페이지로 새 창 이동']").text
    
            all_menu.append("[{}년 {}월 {}일의 {}]\n".format(year, month, date, time))
            all_menu.append(menu[:menu.index("\n* 에너지")])
        except:
            all_menu.append("[{}년 {}월 {}일의 {} 정보가 없습니다]\n".format(year, month, date, time))
    
    all_menu = ["\n"]
    year = input("연도 : ")
    if int(year) < 1: exit()
    month = input("월 : ").zfill(2)
    if int(month) > 12 or int(month) < 1: exit()
    date = input("일 : ")
    if int(date) > 31 or int(date) < 1: exit()
    time = input("조식/중식/석식 : ")
    
    url = "http://ijss.icehs.kr/foodlist.do?year=" + year + "&month=" + month + "&m=02050101&s=ijss"
    
    options = webdriver.ChromeOptions()
    options.headless = True
    options.add_argument("window-size=1920x1080")
    
    browser = webdriver.Chrome(options=options)
    browser.maximize_window()
    browser.get(url)
    
    if time == '조식':
        menuprint('B')
    elif time == '중식':
        menuprint('L')
    elif time == '석식':
        menuprint('D')
    else:
        time = '조식'
        menuprint('B')
        time = '중식'
        menuprint('L')
        time = '석식'
        menuprint('D')
    
    browser.quit()
    
    for line in all_menu:
        print(line)
    print()

    코드 설명 및 실행

    연, 월, 일, 급식 들을 입력받아 접속해야할 URL을 만들어 그 URL에 접속한다. 그리고 급식에 맞는 버튼을 눌러 필요한 정보를 스크래핑 해온다. 조식/중식/석식을 입력하지 않고 다른 것을 급식에 입력했을 경우, 그 날의 모든 식단이 출력되도록 하였다. 그리고 더 간단히 보이기 위해 menuprint라는 함수를 만들었다. 이 함수 내에서 위에서 말했던 버튼 누르기, 식단 정보 스크래핑 해오기 등의 웹사이트 관련 행동을 처리하였다. 식단 안내 자료의 HTML 문서를 분석해보니 버튼의 id가 각각 아침은 B, 점심은 L, 저녁은 D임을 이용하여 버튼을 눌렀고, 버튼을 누른 뒤에는 입력받은 날의 식단 정보를 받아왔다. 각 날마다 식단 정보가 있을 경우에는 식단 정보의 title이 "(  )일 식단 상세보기 페이지로 새 창 이동"이다. 그래서 XPATH를 사용하여 식단 정보의 위치를 파악하여 그 정보들을 받아왔다. 주말이거나 공휴일, 일찍 가는 금요일 등 때문에 급식이 없는 경우에는 당연하게도 식단 자료도 없다. 그렇게 되면 title이 "(  )일 식단 상세보기 페이지로 새 창 이동"인 element가 없기 때문에 오류가 발생한다. 그래서 try와 except를 사용하여, 오류가 발생할 경우 급식이 없는 것으로 판단하여 [(  )(  )(  )일의 (  ) 정보가 없습니다]라는 문구를 출력되도록 만들었다. 이 정보들을 함수 내에서 바로 출력하니 모든 식단을 출력할 때 동작(버튼 클릭 동작)할 때 자동으로 출력해주는 문구들 때문에 출력된 결과를 보기 불편했다. 그래서 받은 식단 자료들은 리스트 형태로 받아 마지막에 전체를 출력했다. 마지막으로 스크래핑 하는 과정에서 나에게는 안 보여도 되는 창이 뜨거나 이트 접속 과정이 보이는 것이 불편하여 options를 사용하여 창이 띄워지거나 접속 과정이 보이는 것을 막았다. 

    실행 화면[2021년 12월 2일의 조식 식단]
    실행 화면[2021년 12월 17일의 식단(석식 없는 날)]

    느낀점 및 개선방향

    스크래핑을 통해 내가 원하는 자료를 직접 받는 것이 신기했고, 재미있었다. 이것 외에 나 또는 다른 사람들에게 필요한 정보들을 스크래핑 해오는 프로그램들을 더 만들어보고 싶다는 생각이 들었다. 

    이 프로그램에서 좀 더 개선해보고 싶은 점이 있다. gui를 사용하여 출력하거나 좀 더 자료를 가공하여 출력해보고 싶다.

    아직 웹스크래핑은 어려운 것 같다. 좀 더 공부를 하여 더 다양한 정보를 손쉽게 받는 프로그램을 만들어보고 싶다. 그리고 웹스크래핑을 공부하면서 HTML도 아주 조금 공부했었는데 HTML, CSS, JS를 공부하여 직접 웹사이트도 만들어보고 싶다는 생각도 들었다. 

Designed by Tistory.