카카오톡 인천대학교 학식봇 만들기(AWS Lambda) - 6
추가적인 배열 정리 (not_today_menu_list와 같이 따로 나눈것이 아닌, today_menu_list와 all_menu_list로 나눔) 및 배열 인덱싱, 슬라이싱을 모두 완료하였다.
추가적으로 AWS lambda 코딩도 완료했다.
추가적으로 bs4 라이브러리를 사용하기위해서, lambda에 zip파일을 업로드하는 형식으로 라이브러리를 적용시켰다.
코드들도 모두 대대적인 개선사항이 생겼다.
crawling_INUmenu.py
from bs4 import BeautifulSoup # 크롤링을 위해 bs4 라이브러리 사용
from urllib.request import urlopen
today_menu_list = [[[], [], [], [], []]]
all_menu_list = []
menuTime = []
day_list = ['월','화','수','목','금','토','일']
tday = ""
for i in range(6): # 첫번째 인덱스를 요일, 두번째 인덱스를 메뉴 시간, 세번째 인덱스를 메뉴 시간별 세부 메뉴를 가진 3차원 배열
line = []
all_menu_list.append(line)
for j in range(5):
line = []
all_menu_list[i].append(line)
def find_td(selected_menu, result_list,real_index):
index = 0
for menu_sub_list in selected_menu: # select는 상단의 코드에서 복수의 td들을 ResultSet(일종의 List형태)로 가져오므로, 반복문을 통해서 각각의 요소들을 get_text()로 처리해줘야함
oneday_menuplan = menu_sub_list.get_text().split('\n') # 한칸에 모든 메뉴가 \n으로 나누어져있음
for j in range(len(oneday_menuplan)):
if (oneday_menuplan[j] is '\r' or # 메뉴가 게재된칸에는 가격정보와 제공시간이 적혀있으므로, 메뉴만 얻기위해 예외처리
oneday_menuplan[j][0] is '*' or
oneday_menuplan[j][0] is '[' or
oneday_menuplan[j][0] is '(' or
oneday_menuplan[j][0] is '❝'
):
break
elif oneday_menuplan[j][0] is '<': # <즉석조리기기>칸의 라면 메뉴들을 가져오기위한 예외처리
continue
else:
if '국밥' in oneday_menuplan[j]: # 국밥칸에서 칼로리 정보를 제외하고 메뉴 이름만 가져오기위한 예외처리
result_list[index][real_index].append(oneday_menuplan[j][:4].strip())
else:
result_list[index][real_index].append(oneday_menuplan[j].strip())
index += 1
url = "https://www.uicoop.ac.kr/main.php?mkey=2&w=2&l=1"
html = urlopen(url)
soup = BeautifulSoup(html, "html.parser") # 원하는 태그 정보를 뽑아줄 bs4 인스턴스 생성
index = 0
index1 = 0
for tr_menu in soup.find(id='menuBox').find_all('tr'): # menuBox라는 이름을 가진 테이블에서 한줄씩 뽑아냄
not_today_menu = tr_menu.select('.din_list')
today_menu = tr_menu.select('.din_lists')
menutime_tr = tr_menu.find(class_ = 'corn_nm')
day = tr_menu.find(class_ = 'din_mns')
if day:
tday = day.get_text().strip()[:1]
short_date = int(day.get_text().strip()[3:8].replace('/',''))
if menutime_tr:
menuTime.append(menutime_tr.get_text())
if not_today_menu: # 찾은 내용이 있을 경우
find_td(not_today_menu, all_menu_list, index)
index += 1
if today_menu:
find_td(today_menu, today_menu_list, index1)
index1 += 1
for i in range(len(day_list)):
if tday == day_list[i]:
all_menu_list.insert(i,today_menu_list[0])
today_index = i
break
크롤링 해오는 부분은 거의 같지만, 요청한 날짜의 메뉴를 출력하기위해 오늘의 요일을 저장한 tday 변수, 오늘 날짜를 int형식으로 변환해 저장한 short_date와 같은 변수들을 만들었다.
import json
import time
import crawling_INUmenu as im
def lambda_handler(event, context):
# 메시지 내용은 request의 ["body"]에 들어 있음
request_body = json.loads(event["body"], encoding="utf-8")
action = request_body["action"]
# 날짜 출력
date_obj = json.loads(action["params"]["date"], encoding="utf-8")
date = date_obj["date"]
date = int(date[5:].replace('-',''))
diff_index = im.today_index + date - im.short_date
day = action["detailParams"]["date"]["origin"]
# 요청한 메뉴 출력
that_day_menu_str = ""
that_day_menu_str += "{} 메뉴\n\n".format(day)
for j in range(len(im.all_menu_list[diff_index])):
that_day_menu_str += "{}\n".format(im.menuTime[j])
for k in range(len(im.all_menu_list[diff_index][j])):
that_day_menu_str += "{}\n".format(im.all_menu_list[diff_index][j][k])
that_day_menu_str += "\n"
result = {
"version": "2.0",
"template":{
"outputs": [
{
"simpleText":{
"text": "{}".format(that_day_menu_str)
}
}
]
}
}
return {
"statusCode":200,
"body": json.dumps(result),
"headers": {
"Access-Control-Allow-Origin": "*",
}
}
요청한 날짜의 메뉴를 구하기위해 오늘 날짜와 요청한 날짜의 차이를 통한 배열 인덱싱을 통해 정상적으로 메뉴들을 출력했다.
ex: 내일(7월 6일)을 int형으로 변환 -> 707, 오늘 날짜를 int형으로 변환 706
-> 707-706 = 1
오늘 날짜 index에서 1을 더하는 형태로 내일 index를 구함
오늘도 수십번의 request로 인해 늘어난 로그 스트림을 보면서,, 여러 생각이 오고갔지만
그래도 잘 작동되니 다행이라는 생각이 들었다.
카카오톡 채널 @inu_food
아직 남아있는 문제점은, 크롤링 해오는 데이터가 이번주 메뉴이기 때문에, 저번주 메뉴를 질의한다고해도 이번주 메뉴로 출력되는 상황이다. 예외처리 부분이 남아있음