개선한 크롤링 코드를 AWS에 올리는 작업을 시작했다. (크롤러 개선 과정은 https://kyumcoding.tistory.com/36)
AWS에 올리는 이유는 크게 2가지이다
1) 온프레미스의 비효율성 제거
- 크롤링 코드의 경우 하루에 한 번 30분 정도의 런타임만으로 돌아가는데, 이를 위해서 노트북 혹은 데스크탑을 하루종일 켜놔야 한다는 것은 매우매우 비효율적이고, 사실 불가능하다. (누구 노트북 하나 24시간 매일 켜놓거나, 아니면 크롤러 돌아갈 때 켜줘야 하는데 가능?)
2) 클라우드 서비스를 활용해서 크롤링 프로세스 자동화 & 파이프라인화
- 크롤링한 결과물을 데이터베이스에 넣는 과정으로 기획된 상태였다. 크롤러가 돌아가서 문서를 산출 -> 데이터베이스에 넣기 과정이 자동화되고 안정적으로 운영될 수 있기 위해 AWS에 있는 서비스들을 이용하기로 하였다.
사용하기로 한 AWS 구조는 다음과 같았다
1) Lambda를 통해 서버리스로 크롤링 코드를 돌린다. 이때 Lambda 위에 올라가는 크롤링 코드의 최종 결과물은 json 파일로 저장한다
2) 이 Lambda는 Amazon EventBridge를 통해 트리거되며 매일 1번씩 돌아가게 된다
3) Lambda에서 만들어진 json 파일은 S3에 자동으로 업로드 된다
<참고> AWS 아키텍쳐 다이어그램 그리기 팁? 글을 작성하다가 알게 되었는데, AWS에서 직접 아키텍쳐 그리는 방법과 거기에 사용할 수 있는 로고 파일을 정리한 문서가 있었다. 그림 그릴 일 있는 분들은 홈페이지에 접속하여 PowerPoint용 도구 키트를 다운로드 받자. |
각각 서비스에 대한 소개를 AWS에 코드를 올리는 과정과 곁들여 설명하도록 하겠다 (따로따로 정제된 글로 정리하기가 좀 그런게 진짜 아아아아무것도 모르는 상태로 일단 해보자고 부딪히면서 깨지면서 배웠기 때문이다 ^^)
Step 1: Lambda 함수 세팅하고 사용법 익히기
AWS Lambda 서비스로 들어가게 되면 함수 생성이라는 버튼이 있고, 이를 누르면 아래와 같은 페이지가 나온다
새로 작성을 누를 경우 lambda 위에서 직접 코드를 적는 방식, 컨테이너 이미지를 누르면 코드를 직접 입력하는게 아니라 도커 이미지와 같은 컨테이너 이미지를 lambda 위에 올릴 수 있다. 나의 경우 이번에는 직접 lambda 위에 코드를 작성하기 위해 '새로 작성'으로 선택했다.
'새로 작성' 버튼을 누를 경우 함수를 작성하는 데 사용할 수 있는 기반 언어를 제공해주는데 Node.js, Python, Ruby, Java, Go 등을 지원해준다. 각자 환경에 알맞은 것으로 선택하고, 나는 python으로 코드를 짰기 때문에 python을 선택해주었다.
아키텍쳐는 x86_64, arm64가 있는데, 코드가 돌아갈 환경을 우분투 환경을 기본으로 생각하고 짜기로 했으므로 x86_64를 선택해주었다.
설정이 끝났으면 우측 하단에 함수 생성 버튼을 눌러주자. 그러면 아래와 같은 화면이 나온다
우선 가장 눈에 띄는 람다 로고가 그려져 있는 가운데 부분. 저 부분은 어떤 이벤트를 처리하는 함수를 작성하는 부분이다. 쉽게 말해 우리가 앞으로 작성하고 실행시킬 하나의 프로그램을 함수 형태로 작성하는데, 이를 나타낸다고 생각하면 된다. 함수의 경우 아래 '코드 소스' 부분에서 직접 편집할 수 있다. 이번 케이스의 경우 크롤링 코드가 될 것이다. Layers 부분도 있는데, 이는 람다에 올라가는 코드가 사용할 패키지 또는 라이브러리를 압축하여 업로드 하는 공간이다. 파이썬 크롤링을 사용하는 예시의 경우 BeautifulSoup 등의 도구들을 압축하여 올려두는 것이다.
트리거를 통해 lambda 함수를 언제 실행시키도록 할 것(trigger)인지를 정할 수 있다. 이벤트가 발행하게 되면 아래 lambda_handler에 event 파라미터에 값이 들어오게 된다.
그말은 즉, lambda_handler 함수를 중심으로 모든 것이 돌아갈 수 있게끔 코드를 수정하는 것이 필요하다는 것이다. 음... 정말 단순화해서 말하자면 대충 if __name__ == "__main__"과 비슷한 역할을 한다고도 볼 수 있을 것이다. 뭐 여튼 lambda_handler를 중심으로 코드를 다시 수정해주자. (이 과정이 매우매우매우 귀찮고 힘들었다. 제대로 프로젝트 코드를 짜본게 처음이었던 요소 하나하나를 다시 함수화 하는 것이 익숙하지 않았다. 그렇기 때문에 나는 쭉쭉 코드를 적었고... 이것이 나를 고통의 길로 들게 하였다)
람다에 맞게 수정한 코드는 아래와 같다
#bs4와 같은 코드는 zip 파일로 저장해서 layer에 넣었음
import requests
from bs4 import BeautifulSoup
import json
import boto3
import os
# 네이버 시간표 복사하는 find_code 함수
def find_code():
INFO = {}
for naver_code in range(100, 20000):
base_query = "https://pts.map.naver.com/end-subway/ends/web/{naver_code}/home".format(naver_code=naver_code)
page = requests.get(base_query)
soup = BeautifulSoup(page.text, "html.parser")
try:
line_num = soup.select_one('body > div.app > div > div > div > div.place_info_box > div > div.p19g2ytg > div > button > strong.line_no').get_text()
station_nm = soup.select_one('body > div.app > div > div > div > div.place_info_box > div > div.p19g2ytg > div > button > strong.place_name').get_text()
except:
continue
# 호선 자체가 새로 생기는 경우가 있을 것 같아 호선을 미리 정의하지 않고, 크롤링 결과에 의해 정의되게 함
if line_num not in INFO:
INFO[line_num] = []
block = {"station_nm": station_nm, "naver_code": naver_code}
INFO[line_num].append(block)
return INFO
# handler
def lambda_handler(event, context):
# 크롤링 후 json 파일 생성
file = '/tmp/subway_information.json'
with open(f, 'w', encoding='utf-8') as f:
json.dump(find_code(), f, ensure_ascii=False, indent=4)
함수를 람다에서 직접 작성하는 경우 deploy 버튼을 눌러 수정사항을 배포해줘야 한다
코드 수정이 완료된 이후에는 코드가 람다 위에서 잘 돌아가는지 테스트 해봐야 할 것이다. 직접 람다에서 함수를 작성한 경우 deploy 옆에 test 버튼을 눌러 확인해볼 수 있다.
테스트 이벤트를 조금 더 세밀하게 구성해야 하거나, 도커 이미지 등으로 코드를 작성하여 올리는 경우 아래 '테스트'를 눌러서 진행해야 한다.
이벤트 json 칸에서 어떻게 lambda_handler에 event를 발생시킬 것인지 설정해줄 수 있다. 다 작성한 이후에 우측 상단에 '테스트' 버튼을 누르면 테스트가 진행된다.
함수를 테스트해서 성공한다면 초록창이
실패한다면 빨간창이 나온다. 세부 정보 토글을 눌러 에러 메시지와 함수가 돌아간 시간, 메모리 구성 등을 확인할 수 있다. 이 기록들을 바탕으로 코드 혹은 람다의 구성을 수정해주자.
구성이 나와서 하는 말인데, 이 구성이 모르면 피 보는 그런게 있다.
우선 가장 기본적인 것이 제한 시간. 이 제한 시간은 기본이 3초다. 즉, 람다가 돌아갈 수 있는 시간이 3초인 것이다. 람다는 코드가 돌아가는 시간을 기다려주지 않는데, 이로 인해서 함수가 실행되는 도중에 람다가 죽어버리는 사태가 발생할 수 있다. 따라서 최대 제한 시간인 15분으로 우선 설정하는 것이 정신건강에 이롭다. (이거 몰라서 한 2시간은 날렸던 것 같다...)
사용할 수 있는 메모리도 늘릴 수 있는데, 메모리를 올리면 인스턴스의 사양이 올라가 처리 속도가 빨라진다고 한다. 람다의 가격 정책(람다 가격 정책은 링크에서 확인)은 꽤나 혜자로운 편이니 엄청 무겁거나 많은 처리량을 가진 코드가 아니라면 메모리를 팍팍 늘려서 쓰자. 나도 크롤링 코드를 128MB로 돌리다가 1024MB로 올려서 쓰니 확실히 동일한 코드도 빨리 처리되었던 경험이 있었다.
Step 2: AWS IAM 설정하기 & 로컬에서 AWS SDK 사용하기
이 스텝이 진짜 복병이었다. 그냥 lambda에 코드 올리고 S3 연결해주면 되는거 아닌가 룰루~ 하면서 쉽게 생각했는데, 막상 그걸 하기 위해 설정해줘야 하는 것들이 있었다 하하... 이 글을 쓰고 있는 지금 시점에 와서야 이런게 있었지 허허허 하고 있지만 이거 처음 마주쳤을 때는 상당히 당황스러웠다. (사실 SDK라는 것을 본격적으로 사용해본게 처음이라서 그랬을 수도)
(1) Boto3 설치하기
아무생각이 이제 S3에 업로드할 수 있는 코드를 짜볼까~~ 하면서 검색을 해보니 파이썬에서 S3를 이용하려면 boto3라는 것을 사용해야 한다는 것을 알게 되었다. 쓰라니까 우선 설치했다 (공식문서 링크는 여기)
$ pip3 install boto3
(2) AWS CLI 설치하기
CLI로 AWS를 조작하기 위해선 boto3와 별개로 또 설치를 해줘야 한다. 맥의 경우 Homebrew를 사용하여 간단하게 설치 가능하다. (맥 이외에 윈도우나 리눅스 설치 관련은 여기 글 참고)
$ brew install awscli
(3) AWS IAM 설정하기 & Access Key 발급받기
이 다음에 바로 Configure 부분으로 넘어가게 되는데, 사실 이 부분에서 좀 헷갈렸다. 우선 터미널에 아래 명령을 내려본다
$ aws configure
지금까지 AWS 서비스를 사용하기 위해서 그냥 아이디와 비밀번호만 입력하고 로그인했는데 갑자기 화면에 aws_access_key_id와 aws_secret_access_key를 입력하라는 것이 아닌가?
처음보는 용어에 어처구니가 없었다.
aws_access_key_id와 aws_secret_access_key가 무엇인고... 찾아보니 우리의 AWS는 친절히도 공식문서를 적어두셨다 (link)
1) AWS IAM 콘솔을 연다
AWS IAM이란 AWS의 여러 리소스에 접근할 수 있는 권한 제어하는 서비스이다. 예를 들어 누가 내 AWS Lambda 함수에 접속할 수 있을지, 그리고 접속해서 어떤 것들을 할 수 있을지에 대한 권한을 설정할 수 있다. AWS를 처음 들어가서 사용하게 되는 계정은 루트 계정으로 모든 리소스에 대한 접근이 가능하다. 하지만 루트 계정으로 개발할 경우 보안이나 운영의 측면에서 좋지 않은 측면이 있다. 루트 계정을 사용하다가 유출되면 바로 그 계정 정보를 얻은 사람이 뭐든 다 할 수 있으니까 (이후에도 얘기하겠지만 aws_access_key_id와 aws_secret_access_key를 깃허브에 그대로 올리면 절대 안 된다. 바로 해킹 당해서 엄청난 요금이 부과될 수 있다 ㅎㅎ)
따라서 꼭 필요한 정도의 권한을 가진 IAM 사용자를 만들어서 그것으로 운영하는 것이 좋다.
IAM과 관련해서 여러가지 내용들이 있지만 우선 당장 필요한 내용들만 컴팩트하게 알아보자. IAM 콘솔을 열면 아래와 같은 메뉴를 확인할 수 있다.
2) 탐색 메뉴에서 사용자를 선택한다
빨간색 영역 둘 중 하나를 클릭합니다.
처음 들어갔을 경우 사용자가 없을 것이다. 우측 상단에 '사용자 추가' 버튼을 눌러 사용자를 추가해보자
사용자 생성하는 절차를 진행해준다 (나는 management console에 대해 엑세스 권한을 제공하고 싶어서 선택했다)
이후에는 권한 설정을 해줄 수 있다. '그룹에 사용자 추가'는 미리 생성된 그룹에 사용자를 추가하는 것이다. IAM에서는 그룹을 만들어 권한을 관리할 수 있는데, 예를 들어 개발 그룹에는 A와 B에 대한 권한, 운영 그룹에는 B에 대한 권한만 부여할 수 있는 것이다. 처음만들면 그룹이 없을터이니 직접 정책 연결을 클릭한다.
권한 정책을 직접 검색해서 찾을 수 있는데, 이번 프로젝트의 경우 S3, Lambda를 이용하여 개발하기 때문에 이 두 서비스에 대한 권한만 선택해서 부여한다 (나는 각 서비스에 대해 full access 권한으로 부여했다)
다음 페이지에서 사용자 생성을 클릭하면, 오른쪽 그림과 같이 콘솔 로그인 URL과 사용자 이름, 콘솔 암호를 확인할 수 있다. 이 정보들은
이렇게 생겨먹은 AWS 로그인 페이지에서 사용하여 접속할 때 필요하다. 로그인 URL로 페이지에 접속하고, 사용자 이름과 암호를 적어 로그인 하면 된다. 지금은 우선 루트 계정으로 돌아오자
3) IAM 사용자 이름(확인란이 아님)을 선택합니다 & Security credentials(보안 자격 증명) 탭을 연 다음 Create access key(액세스 키 생성)를 선택합니다.
사용자 이름을 클릭하고 '보안 자격 증명'으로 들어가자. 스크롤을 내리다보면 '엑세스 키' 항목이 있다. 엑세스 키 만들기를 클릭하여
5) 새 액세스 키를 보려면 [Show]를 선택합니다. & 6) 키 페어 파일을 다운로드하려면 [Download .csv file]을 선택합니다. 안전한 위치에 키와 함께 .csv 파일을 저장합니다.
자신의 상황에 맞는 엑세스 키를 만들자. 나는 CLI에서 사용할 엑세스 키를 발급받고 싶은 것이기 때문에 아래와 같은 옵션으로 발급하였다. 엑세스 키를 발급받으면 바로 텍스트를 복사해서 사용할 수도 있고, csv 파일로도 사용할 수 있다. (절대 외부에 노출되지 않도록 한다)
여기까지가 IAM 관련된 설정이었다. 이게 한 번 해보면 별거 아닌 일이지만, 처음하는 사람 입장에서는 너무 헷갈린다. 로그인을 위한 ID와 CLI 접속을 위한 Access key가 나뉜다는 개념도 익숙하지 않으니... 그리고 위의 프로세스는 정말 간략한 버전이고, 역할, 정책 등등 다양한 용어와 기능 그리고 전략이 존재한다 (처음에 가이드가 없어서 이것저것 다 찾아보다가 멘탈이 터졌었다... SDK 사용은 커녕 그 전 단계에서 삽질하고 있는게 멘탈이 터져서 하하) 지금까지 읽어 본 자료들 중에는 아래 자료가 가장 깔끔하게 잘 설명되어 있는 것 같아 첨부한다
https://musma.github.io/2019/11/05/about-aws-iam-policy.html
여튼 여기에서 발급받은 Access Key와 Secret Access Key는 아주 많은 곳에서 쓰이니 잘 보관해두자
$ aws configure
이제 access key와 secret access key를 발급받았으니 복수해줄 차례다
하나하나 정보를 입력해주자. 한 번 입력하면 컴퓨터가 기억하고 있어서 엔터만 쭉쭉 치고 설정을 할 수도 있다.
Step 4: S3 버킷 만들기
솔직히 람다보다는 S3를 사용해본다는 것에 조금 더 큰 기대가 있었다. AWS 서비스를 사용한다고 하면 거의 모든 경우 S3를 포함해서 프로젝트를 진행하기 때문에, 그 실체가 궁금했다고 해야 하나.
S3는 AWS에서 제공하는 Simple Storage Service, 즉 온라인 스토리지 서비스이다. (S가 3개라 S3라고 한다... 정말 괴랄한 네이밍 방식) 스토리지는 데이터를 저장하는 저장소라고 한다면,데이터베이스는 스토리지에 있는 데이터를 조금 더 체계적으로 정리하여 저장하는 것을 말한다. 스토리지는 텍스트 파일, 이미지, 영상 등 다양한 형태의 데이터를 다 때려 넣을 수 있음.
본격적으로 들어가기 전에 우선 용어 먼저 살펴보면
- 객체 (Object): 데이터와 메타데이터를 구성하고 있는 저장 단위 (S3에 저장되는 모든 데이터는 객체임)
- 버킷 (Bucket): 파일 시스템에서 디렉토리나 폴더 비스무리한 걸로 생각하면 된다. (S3에 저장된 객체에 대한 컨테이너)
- 키 (key): 버킷 내 객체를 식별할 수 있게 하는 것. 버킷 내 모든 객체는 하나의 키를 가짐. bmt/subway_information.json 같은 형태임
즉, 하나의 버킷 안에 객체들이 키를 가지고 저장되어 있는 형태라고 생각하면 된다. 폴더, 파일만 사용하다가 S3를 썼을 때 가장 헷갈리는 지점은 익숙한 폴더 안에 폴더 구조가 아니라(like 마트료시카), 버킷 안에 키라는 구조로 생각해야 한다 즉, mybucket 버킷 안에 'bmt/subway_information.json'키를 지닌 객체를 저장하는 것. 키의 형태가 / 를 사용해서 좀 더 헷갈리는 측면이 있는 것 같다.
S3 서비스로 들어가서 버킷 만들기를 클릭하자
그 다음 버킷 이름과 여러 설정을 만져준다. (버킷 이름이 전역에서 고유해야 하기 때문에,,, 네이밍하는데 살짝 어려움을 겪을 수 있다. 그냥 대충 지으면 이미 있는 이름이더라고요...)
이름과 리전 설정 외에도 퍼블릭 엑세스 설정이나 버킷 버전 관리, 기본 암호화 등의 옵션이 있다. 이것들은 각자의 사정에 맞게 잘 설정하기 (요것들만의 아주 넓고 깊은 세계가 있는 것 같다 - 이분의 블로그 글 참고해보면 좋을듯) 여튼 잘 설정해주면 버킷이 잘 생성된다.
추가: 파일을 업로드 하다가 Access Denied 에러가 발생한 경우
나는 분명히 모든 것들을 잘 설정했는데, 갑자기 Access Denied 에러가 나는 경우가 있다. 나의 경우 lambda에서 함수를 돌려 생성한 코드를 S3에 업로드 하는 과정에서 이러한 에러가 발생했다
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
Access Denied가 발생한 경우
1) 버킷의 공개 액세스 차단(버킷 설정) 부분 만지기
해당 S3 버킷으로 들어가서 권한 탭을 클릭, 퍼블릭 엑세스 차단에서 편집 버튼을 눌러준다
모든 퍼블릭 엑세스 차단을 해제하고 저장한다
2) (만약 1번 방법으로 해결이 안 된 경우) 버킷 정책 만지기
버킷의 권한 탭에서 버킷 정책에 아래 정책을 추가한다
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1405592139000",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::버킷이름/*",
"arn:aws:s3:::버킷이름"
]
}
]
}
3) (만약 또 안 된다면) settings.py 세팅 바꿔주기
사실 이 여기까지 오지는 않았고 2번에서 해결되었다. 하지만 종종 안 되는 경우도 있는 것 같음. settings.py로 들어가서
AWS_DEFAULT_ACL = None
설정을 해준다. 출처는 스택오버플로우
Step 4: boto3를 이용해서 코드 짜기
아기다리고기다리 코딩이다. 환경설정하다가 진이 빠졌으니 이제 즐?거운? 코딩 타임. 가장 좋은 것은 공식 도큐먼트에 있는 예제들을 보면서 코딩하는 것이고 (공식 도큐먼트 링크) 현실 버전은 블로그 드리븐 디벨롭먼트와 chatgpt 드리븐 디벨롭먼트다.
사실 내 코드에서는 업로드만 필요하지만, 나중을 위해 download와 delete도 정의해뒀다. 이렇게 정의해두고 필요할 때 쓰면 좋은 것 같다. 유의할 점은 나의 경우 같은 aws 계정의 lambda에서 S3로 데이터가 가는 것이기 때문에 따로 계정 설정이나 리전 설정이 필요하지 않았다는 점이다. 만약 다른 계정의 리소스를 사용하는 경우나 로컬에서 S3에 접속하는 경우에는 엑세스 키, 리전 설정 등이 필요하다.
import json
import boto3
# upload
def upload_file_to_s3(bucket_name, key, file_path):
s3 = boto3.resource('s3')
s3.meta.client.upload_file(file_path, bucket_name, key)
return True
# download
def download_data_from_s3(bucket_name, key, download_path):
s3 = boto3.resource('s3')
# 다운로드 후에 어디에다가 위치시킬 것인지 경로
bucket = s3.Bucket(bucket_name)
objects = list(bucket.objects.filter(Prefix=key))
if objects and objects[0].key == key:
bucket.download_file(objects[0].key, download_path)
return True
return False
# delete
def delete_file_in_s3(bucket_name, key):
s3 = boto3.resource('s3')
s3.meta.client.delete_object(Bucket=bucket_name, Key=key)
return True
<람다의 파일 저장 위치> 람다를 이용해서 작성한 파일을 조작해야 하는 경우 유의할 점! 1) 람다가 작업을 위해 참고하는 파일들의 경우 /var/task 폴더 안에 있어야 한다. (후에 다른 포스트에서 얘기하겠지만) 람다 위에 컨테이너를 띄워서 작업하는 경우 파일들을 /var/task/ 경로 안에 복사하게 설정해야 한다. 2) 람다가 작동하고 있는 동안 작성한 파일은 파일을 /tmp/ 경로 안에 저장하게 된다. 따라서, 람다에서 작성한 파일을 S3에 업로드 하기 위해서는 local path와 download path를 설정할 때 /tmp/를 붙여서 설정해줘야 한다. |
위 함수들을 사용하여 작성한 최종 코드는 아래와 같다. 한 번 해봤다면 생각보다 별개 아니지만, 처음하면 시행착오가 참 많은 과정인 것 같다. 다른 분들은 그리고 미래의 내가 이 블로그 글을 보고 수월하고 더 깔끔한 코드를 작성하셨으면 한다.
#bs4와 같은 코드는 zip 파일로 저장해서 layer에 넣었음
import requests
from bs4 import BeautifulSoup
import json
import boto3
import os
# 네이버 시간표 복사하는 find_code 함수
def find_code():
INFO = {}
for naver_code in range(100, 20000):
base_query = "https://pts.map.naver.com/end-subway/ends/web/{naver_code}/home".format(naver_code=naver_code)
page = requests.get(base_query)
soup = BeautifulSoup(page.text, "html.parser")
try:
line_num = soup.select_one('body > div.app > div > div > div > div.place_info_box > div > div.p19g2ytg > div > button > strong.line_no').get_text()
station_nm = soup.select_one('body > div.app > div > div > div > div.place_info_box > div > div.p19g2ytg > div > button > strong.place_name').get_text()
except:
continue
# 호선 자체가 새로 생기는 경우가 있을 것 같아 호선을 미리 정의하지 않고, 크롤링 결과에 의해 정의되게 함
if line_num not in INFO:
INFO[line_num] = []
block = {"station_nm": station_nm, "naver_code": naver_code}
INFO[line_num].append(block)
return INFO
def upload_file_to_s3(bucket_name, key, file_path):
s3 = boto3.resource('s3')
s3.meta.client.upload_file(file_path, bucket_name, key)
return True
def download_data_from_s3(bucket_name, key, download_path):
s3 = boto3.resource('s3')
# 다운로드 후에 어디에다가 위치시킬 것인지 경로
bucket = s3.Bucket(bucket_name)
objects = list(bucket.objects.filter(Prefix=key))
if objects and objects[0].key == key:
bucket.download_file(objects[0].key, download_path)
return True
return False
def delete_file_in_s3(bucket_name, key):
s3 = boto3.resource('s3')
s3.meta.client.delete_object(Bucket=bucket_name, Key=key)
return True
# handler
def lambda_handler(event, context):
# 크롤링 후 json 파일 생성
file = '/tmp/subway_information.json'
with open(f, 'w', encoding='utf-8') as f:
json.dump(find_code(), f, ensure_ascii=False, indent=4)
# 버킷에 저장 준비
bucket_name = "버킷이름"
key = "bmt/subway_information.json"
file_path = "/tmp/subway_information.json" # lambda에서는 파일을 /tmp/에 저장
s3 = boto3.client('s3')
result = upload_file_to_s3(bucket_name, key, file_path)
if result:
return {
'statusCode': 200,
'body': json.dumps("upload success")
}
else:
return {
'statusCode': 400,
'body': json.dumps("upload fail")
}
Step 5: 짠 코드 lambda에 올리고 무한 디버깅하기
이제는 디버깅 타임이다. 위에서 작성한 코드를 람다에 올리고, 필요한 라이브러리를 압축해서 레이어에 저장하고 테스트를 해보자.
꼴보기 싫은 저 빨간 색 화면과 로그를 보면서 코드를 하나하나 고치다보면
이 초록색 화면을 볼 수 있다. 저 화면이 보일 때까지 화이팅...
물론 나는 람다의 제한시간인 15분 안에 코드가 다 안 돌아가는 바람에 계속 Fail 했다...
이를 해결하려고 꽤 많은 노력을 했었는데,,, 그 과정은 아래에서 to be continue...
https://kyumcoding.tistory.com/40