이번 프로젝트에서는 PWA(Progressive Web App) 스토어 플랫폼을 개발하며,
자동화된 크롤링 시스템을 통해 수많은 웹사이트에서 manifest.json 및 PWA 관련 정보를 수집하고 있습니다.
PWA 크롤링 로직을 구성하면서 언어와 라이브러리를 선택과정에서 겪은 시행착오를 공유합니다.

1. 크롤링 기능의 필요성
PWAndora의 핵심 기능 중 하나는 PWA 앱의 자동 수집입니다.
이를 위해 크롤링 시스템은 다음과 같은 역할을 수행합니다.
- 수집 대상 사이트를 순차적으로 탐색합니다.
- 각 사이트에서 manifest.json 파일을 찾고 파싱합니다.
- 앱 이름, 아이콘, 시작 URL, 설명 등을 추출하여 저장합니다.
단순한 정보 수집을 넘어, 추출된 정보를 기반으로 앱을 자동 분류하고 소개하는 기능까지 고려하다 보니,
기술 선택에 있어서 고민할 점이 많았습니다.
2. 초기 접근 방식 - Python 기반의 Selenium
초기에는 Python과 Selenium, Flask를 조합하여 크롤링 시스템을 구현하였습니다.
Python은 크롤링과 데이터 분석에 강력한 생태계를 가지고 있었으며 함께 하는 팀원에게 익숙한 언어라 선택하였습니다.
그러나 문제는 성능이었습니다.

- 50개의 사이트의 PWA 여부를 검사하는 데 15분 이상이 소요되었습니다.
- 현재 수집한 약 37만 개의 사이트를 크롤링하는 데 2주 이상이 소요되는 속도입니다.
- Selenium의 브라우저 기반 렌더링은 신뢰성은 높았지만, 속도 면에서는 큰 병목이 발생했습니다.
이러한 문제로 인해 보다 빠르고 효율적인 대안이 필요했습니다.
3. 대안 탐색 - Go, Puppeteer, Playwright
성능 개선을 위해 여러 가지 대안을 검토하였습니다.
- Go 언어: 고성능 처리에 적합하지만, 크롤링 생태계가 다소 협소했습니다. 팀원들에게 익숙한 언어도 아니었습니다.
- Node.js + Puppeteer: Chrome 브라우저 기반의 헤드리스 크롤링이 가능하며, 동적 콘텐츠 처리에 강점이 있었습니다.
- Node.js + Playwright: Puppeteer와 유사하지만, 더 다양한 브라우저 지원과 안정적인 API 제공이 장점이었습니다.
병렬 처리에는 Go 언어의 성능이 가장 높았어나 비교적 안정성이 떨어져 고민하던 찰나,
멘토님께서 추천해주신 Playwright와 기존에 고민하던 Puppeteer를 비교해보았습니다.
- Puppeteer: Chrome/Chromium 기반 크롤링과 자동화에 최적. 빠르고 가벼운 도구가 필요할 때 적합.
- Playwright: 멀티 브라우저 지원, 자동 대기, 네트워크 조작, 병렬 실행 등 더 강력한 기능을 제공.


두 방식 사이에 드라마틱한 시간 차이가 존재하지는 않았지만 병렬 처리를 고려해야 한다고 생각했습니다.
최종적으로 Node.js + Playwright 조합을 선택했습니다.
4. Playwright를 선택한 이유
Playwright는 Chromium뿐 아니라 Firefox, WebKit까지 다양한 브라우저를 지원하며,
페이지가 완전히 로드될 때까지 기다리는 설정, 네트워크 상태 제어 등의 기능이 강력합니다.
또한 다음과 같은 이유로 Playwright를 선택하였습니다.
- 성능: 병렬 처리 및 빠른 실행 속도
- 안정성: 비동기 구조를 잘 지원하며, 오류 핸들링이 명확함
- 유연성: 크롤링 중 필요한 데이터를 정확히 추출 가능
- 표준화된 결과: 동일한 방식으로 다양한 사이트에 접근 가능
현재는 Express 서버에서 Playwright 워커 풀을 관리하며, 크롤링 요청을 분산 처리하는 구조로 구성하였습니다.
5. 회고
처음에는 익숙한 도구로 빠르게 MVP를 만들고자 했지만, 실제 운영 단계에서는 성능과 확장성이 더 중요하다는 것을 깨달았습니다.
Flask + Selenium의 조합으로 약 일주일 정도 개발을 하다가 다시 Express + Playwright로 코드를 옮기는 과정에서
다소 시간이 소모되었고 그로 인해 백엔드나 프론트엔드 팀원들이 크롤링 팀을 기다리는 상황이 발생했습니다.
그나마 다행인 점은 언어가 달라졌을 뿐 로직에 큰 변경은 없었다는 점입니다.
Python은 여전히 강력한 도구이지만, 크롤링 규모가 커지거나 동적 렌더링이 필요한 상황에서는 Node.js 기반 도구가 더 나은 선택이 될 수 있음을 알았습니다.
이번 경험을 통해 상황에 따라 언어와 기술 스택을 유연하게 선택해야 한다는 교훈도 얻었습니다.
이후에는 프로젝트를 할 때 익숙한 언어나 기술 스택이라고 해서 먼저 선택을 내리기 보다는 더 신중하게 고민해야겠습니다.
'Programming > Project' 카테고리의 다른 글
[Project / Collabit] WebSocket + STOMP + Redis로 채팅 구현하기 (0) | 2025.02.23 |
---|---|
[Project / Collabit] 우리 프로젝트에 Redis를 적용해야 하는 이유 (0) | 2025.01.19 |
[Frontend Mentor] FAQ Accordion main 아코디언 페이지 (0) | 2024.06.03 |
[Frontend Mentor] Social Links Profile 소셜 링크 프로필 완성 (0) | 2024.05.31 |
[Frontend Mentor] Recipe-Page-Main 레시피 페이지 완성 (0) | 2024.05.30 |