AWS Lambda에서 Cheerio 실행하기
로컬 환경에서는 npx crawlee create
명령어로 Crawlee 프로젝트를 쉽게 만들 수 있습니다. 하지만 이 프로젝트를 AWS Lambda에서 실행하려면 몇 가지 수정이 필요합니다.
코드 수정하기
크롤러를 생성할 때마다 고유한 Configuration
인스턴스를 전달해야 합니다. 기본적으로 모든 Crawlee 크롤러 인스턴스는 동일한 스토리지를 공유합니다. 이는 편리할 수 있지만 Lambda에서 상태 유지(statefulness)를 야기하여 디버깅하기 어려운 문제를 초래할 수 있습니다.
또한 Configuration 인스턴스를 생성할 때 persistStorage: false
옵션을 반드시 설정해야 합니다. 이는 Lambda의 파일 시스템이 읽기 전용이므로 Crawlee에게 메모리 내 스토리지를 사용하도록 지시하는 것입니다.
// 자세한 내용은 https://crawlee.dev/ 참조
import { CheerioCrawler, Configuration, ProxyConfiguration } from 'crawlee';
import { router } from './routes.js';
const startUrls = ['https://crawlee.dev'];
const crawler = new CheerioCrawler({
requestHandler: router,
}, new Configuration({
persistStorage: false,
}));
await crawler.run(startUrls);
이제 모든 로직을 handler
함수로 감싸줍니다. 이것이 AWS가 실제로 실행할 "Lambda" 함수입니다.
// 자세한 내용은 https://crawlee.dev/ 참조
import { CheerioCrawler, Configuration } from 'crawlee';
import { router } from './routes.js';
const startUrls = ['https://crawlee.dev'];
export const handler = async (event, context) => {
const crawler = new CheerioCrawler({
requestHandler: router,
}, new Configuration({
persistStorage: false,
}));
await crawler.run(startUrls);
};
Lambda 실행마다 새로운 크롤러 인스턴스를 생성해야 합니다. AWS는 콜드 스타트 시간을 줄이기 위해 첫 Lambda 실행 후 일정 시간 동안 환경을 유지합니다. 따라서 이후의 Lambda 호출은 이미 사용된 크롤러 인스턴스에 접근하게 됩니다.
요약: Lambda를 상태가 없도록(stateless) 유지하세요.
마지막으로, 크롤러 실행이 끝났을 때 수집된 데이터를 Lambda에서 반환하도록 합니다.
최종적으로 main.js
스크립트는 다음과 같이 구성됩니다:
// 자세한 내용은 https://crawlee.dev/ 참조
import { CheerioCrawler, Configuration } from 'crawlee';
import { router } from './routes.js';
const startUrls = ['https://crawlee.dev'];
export const handler = async (event, context) => {
const crawler = new CheerioCrawler({
requestHandler: router,
}, new Configuration({
persistStorage: false,
}));
await crawler.run(startUrls);
return {
statusCode: 200,
body: await crawler.getData(),
}
};
프로젝트 배포하기
이제 AWS에 스크립트를 배포할 차례입니다!
프로젝트 폴더에서 zip -r package.zip .
명령어를 실행하여 프로젝트(node_modules
폴더 포함)를 zip 파일로 압축합니다.
node_modules
폴더가 너무 큰가요?AWS는 직접 파일 업로드 시 50MB 제한이 있습니다. 일반적으로 Crawlee 프로젝트는 이 제한에 훨씬 못 미치지만, 의존성이 많으면 쉽게 초과할 수 있습니다.
프로젝트 의존성을 설치하는 더 나은 방법은 Lambda 계층(Layers)을 사용하는 것입니다. 계층을 사용하면 여러 Lambda 간에 파일을 공유할 수 있고, Lambda의 실제 "코드" 부분을 최대한 가볍게 유지할 수 있습니다.
Lambda 계층을 만들려면:
node_modules
폴더를 별도의 zip 파일로 압축합니다 (압축 파일에는node_modules
라는 이름의 폴더가 하나만 있어야 합니다).- 이 압축 파일로 새로운 Lambda 계층을 생성합니다. 보통 이 파일을 AWS S3 스토리지에 업로드한 후 Lambda 계층을 생성합니다.
- 생성 후, 새로운 Lambda 함수에서 이 계층을 사용하도록 설정하면 됩니다.
코드를 배포하려면 package.zip
압축 파일을 코드 소스로 업로드합니다.
Lambda 런타임 설정에서 handler
가 크롤러를 실행하는 메인 함수를 가리키도록 합니다. 디렉토리 구조는 슬래시(/)로 구분하고, 명명된 내보내기는 점(.)으로 표시합니다. 우리의 handler 함수는 src/main.js
파일에서 내보내진 handler
이므로, 핸들러 이름으로 src/main.handler
를 사용합니다.
이제 모든 설정이 완료되었습니다! 테스트 버튼을 클릭하여 새로운 Lambda에 테스트 이벤트를 보낼 수 있습니다. 이벤트의 실제 내용은 지금은 중요하지 않습니다. 나중에 handler에 전달되는 첫 번째 인자인 event
객체를 분석하여 크롤러 실행을 더 세밀하게 제어할 수 있습니다.
AWS Lambda 대시보드의 구성 탭에서 Lambda의 메모리 용량이나 임시 스토리지 크기를 설정할 수 있습니다.
메모리 크기는 Lambda의 실행 속도에 큰 영향을 미칠 수 있습니다.
메모리에 따른 성능과 비용 변화에 대해서는 공식 문서를 참조하세요.