티스토리 뷰

 
수업 시간에 늘 시키는 일이 있다.
비전공자들이 많은 수업을 하다보니 많이 보는게 중요하다는 사실을 가르쳐 주는 일 
섹션별로 레퍼런스를 찾아 보는 연습을 시킨다.
예를 들어 앱 다운로드 영역이다 하면
사이트들을 일일히 찾으면서
탭을 스무 개쯤 열고 스크롤을 내리는 일... 
레퍼런스 사이트는 많다.
GDWEB이나 디비컷은 사이트를 통째로 보여주고,
uibowl은 앱 화면을 패턴별로 잘 정리해놨다. 

(유아이볼에서도 헤더, 푸터, 공지사항 따로 볼 수 있다고 한다)
그런데 PC 웹을, 그것도 국내 사이트를, 섹션 단위로 모아둔 곳은 없었다.
헤더만 쭉, 푸터만 쭉, 뉴스·공지 영역만 쭉 보고 싶은데.
그래서 만들기로 함
 
국내 웹사이트를 섹션별로 모아 보는 레퍼런스,
찐망고 레퍼런스.

찐망고 레퍼런스 배타버전화.

 
레퍼런스 사이트는 한 번 올리면 끝이라 금방 낡는다.
그래서 GDWEB에 새로 올라온 사이트는
들어온 날 바로 찍어서 정리하고,
이미 있는 사이트는 90일마다 다시 확인해서 리뉴얼됐을 때만 새 버전으로 바꾸게 했다
캡처마다 수집일을 남기고 원본 링크로 출처도 밝히고
1년에 1,000곳까지 키우는 게 목표라서 찍고,
자르고, 분류하는 건 전부 자동으로 하고, 나는 감수만 하기로 했다.
 
요즘은 AI 빌더로 몇 분 만에 그럴듯한 사이트가 나온다.
문제는 그런 사이트들이 다 비슷하게 생겼다는 거다.
그라데이션, 이모지 아이콘, 템플릿 그대로의 카드 나열… 레퍼런스로 참고할 이유가 없다.
여기는 사람이 고민해서 만든, 실제로 운영되는 국내 사이트만 모으는 곳이다.
그래서 수집 단계에서 두 번 거른다.

  1. 주소와 코드 흔적: lovable, bolt, v0 같은 AI 빌더 주소이거나, 페이지 코드에 생성 도구 흔적이 있으면 자동으로 제외한다.
  2. AI가 첫 화면 보고 판단: 첫 화면 캡처를 Claude(Haiku)에게 보여주고 "실제 운영되는 국내 사이트인가, AI가 찍어낸 템플릿인가"를 묻는다. 확실한 것만 자동으로 처리하고, 애매한 건 내가 직접 본다.

AI로 AI 사이트를 거르는 셈 ㅋㅋ
자세한 방법은 3편쯤에서..
 
이런 서비스를 만들 때 제일 무서운 게 이미지다.
보통은 이렇게 된다.

  • 이미지를 서버에 올리면 저장 용량 요금이 붙는다.
  • 방문자가 이미지를 볼 때마다 트래픽(전송량) 요금이 붙는다. 레퍼런스 사이트는 화면이 거의 다 이미지라서, 사람이 많이 올수록 돈이 더 나가는 구조가 된다.
  • 캡처하려면 브라우저를 띄울 서버가 필요하다.

1,000곳이면 섹션이 8,000개쯤 나온다.
무료로 서비스를 운영할건데 저장용량에 트래픽까지.. 감당못할거같아서
고민해보다 해결한 방법을 공유해본다.
 

1. 이미지는 Cloudflare R2에, 트래픽은 무료

이미지 저장소로 Cloudflare R2를 골랐다.
이유는 딱 하나, 전송 요금(egress)이 무료다.
저장 용량도 10GB까지 무료라서, 방문자가 아무리 많이 봐도 이미지 보는 비용이 안 붙는다.
설정은 이 정도다.

  1. Cloudflare 가입 → R2 → 버킷 만들기 (이름은 refs처럼 짧게)
  2. 버킷 Settings → Public access에서 r2.dev 주소 허용 (나중에 내 도메인 연결도 가능)
  3. R2 → Manage API tokens → Object Read & Write 토큰 만들기
  4. 받은 키를 GitHub Secrets에 넣기

R2는 S3와 호환돼서 파이썬에서는 boto3로 그대로 올리면 된다.

s3 = boto3.client("s3", endpoint_url=f"https://{ACCOUNT_ID}.r2.cloudflarestorage.com",
                  aws_access_key_id=KEY_ID, aws_secret_access_key=SECRET)
s3.upload_file("01.webp", "refs", "toss.im/v1/01.webp",
               ExtraArgs={"ContentType": "image/webp"})
# 공개 주소: https://pub-xxxx.r2.dev/toss.im/v1/01.webp

 

2. 이미지를 Vercel을 거치지 않고 바로 보여주기

웹 화면은 Vercel에 올렸는데, 이미지는 R2 주소를 <img>에 그대로 넣는다.
Next.js의 이미지 최적화(next/image)는 쓰지 않았다.
그걸 쓰면 이미지가 Vercel을 한 번 거치면서 무료 한도를 금방 먹는다.
크기 최적화는 저장할 때 미리 해두면 된다(아래 3번).
DB에도 이미지가 아니라 주소만 저장한다. 그래서 Supabase 무료 용량(500MB)으로 충분하다.

3. 저장할 때 미리 줄이기: WebP + 썸네일 따로

캡처 원본(PNG)을 그대로 올리면 한 장에 몇 MB씩 나온다. 그래서 세 가지로 나눠 저장한다.

목록 썸네일 WebP, 폭 480px 장당 20~40KB
크게 보기 WebP, 품질 78 장당 수백 KB
페이지 전체 개요 JPEG, 폭 960px 사이트당 1장
crop.save("01.webp", "WEBP", quality=78, method=6)        # 상세용
thumb = crop.resize((480, round(crop.height * 480 / crop.width)))
thumb.save("01_t.webp", "WEBP", quality=72, method=6)     # 목록용

 
목록 화면에서는 썸네일만 불러오고, 눌렀을 때만 원본을 연다. 그리고 loading="lazy"로 화면에 보일 때만 불러온다.

4. 바뀐 게 없으면 올리지 않기

매번 다시 찍은 걸 다 올리면 용량이 계속 쌓인다. 그래서 새로 찍은 섹션 구성을 지난번과 비교한다.

  • 배너 이미지나 뉴스 목록만 바뀌었으면 → 레이아웃 유지로 보고 업로드 안 함. "최종 확인일"만 갱신.
  • 섹션 순서나 구성이 크게 바뀌었으면 → 리뉴얼로 보고 새 버전 업로드. 이전 버전은 지우지 않고 보관.

같은 사이트 안에서 거의 똑같은 섹션(슬라이드 장면이 반복되는 것 등)도 이미지 지문(phash)으로 비교해서 하나만 남긴다.
이걸로 쓸데없는 용량이 꽤 줄었다.

5. 캡처 서버 대신 GitHub Actions

브라우저를 띄워서 캡처하려면 원래 서버가 필요하다. 대신 GitHub Actions를 썼다. 공개 저장소는 실행 시간이 무료라서, 매일 오전 10시에 자동으로 크롬을 띄워 캡처하고 끝나면 꺼진다. 서버를 계속 켜둘 필요가 없다.
단점은 미국 서버라는 것. 해외 접속을 막는 국내 사이트 몇 곳은 못 찍는데, 그런 곳은 과감히 패스하기로 했다.

6. AI 비용도 줄이기

섹션이 헤더인지 푸터인지 분류하는 건 Claude API(Haiku)에 맡겼다. 여기서도 아끼는 방법이 있다.

  • 규칙으로 먼저 거르기: "사업자등록번호"가 있으면 푸터, “App Store”가 있으면 앱 다운로드처럼 확실한 건 AI 없이 무료로 분류한다.
  • Batch API: 바로 답이 필요 없는 작업이라 배치로 보내면 50% 할인이다.
  • 이미지는 주소로 보내기: 이미지를 통째로 보내지 않고 R2 주소만 넘긴다.
  • 안 바뀐 섹션은 재사용: 리뉴얼 후에도 생김새가 같은 섹션(푸터 등)은 예전 분류를 그대로 쓴다

 
그래서 1년 비용은 총

캡처 실행 GitHub Actions (공개 저장소) 무료
DB Supabase 무료 플랜 무료
이미지 저장·전송 Cloudflare R2 (사이트 1,000곳 ≈ 2GB 안팎 예상) 무료
AI 분류·검수 Claude API Haiku + Batch 1,000곳당 $1~2
웹 화면 Vercel 무료 플랜 무료

1년에 몇천 원.  도메인값이 더 나온당 하하하

GDWEB 최신 작품 목록 (사이트 주소만 가져옴)
   ↓  AI 1차 검수 (AI로 찍어낸 사이트·해외 사이트 거르기)
수집 목록
   ↓  매일 오전 10시 GitHub Actions + Playwright로 캡처
섹션별로 자르기 → WebP 변환 → 중복 제거
   ↓  규칙 분류 → Claude Haiku 분류
Supabase(DB, 주소만) + R2(이미지)
   ↓
Vercel 웹 화면 + 관리자 화면

 
GDWEB에서는 목록의 사이트 주소만 가져온다. GDWEB의 이미지나 설명은 쓰지 않고, 캡처는 직접 한다.

매일 정해진 시간에 GitHub Actions가 알아서 캡처하고 끝나면 꺼진다. 수집 한 번에 1~30분.

 
사용한 기술 목록이다

개발 파트너 Claude (기획, 코드, 디버깅)
캡처 Python + Playwright (크롬, 1920×1080)
이미지 처리 Pillow, imagehash
자동 실행 GitHub Actions
DB Supabase (Postgres)
이미지 저장 Cloudflare R2 (직접 올린 이미지는 Supabase Storage)
AI Claude API: Haiku, Batch API
웹 화면 Next.js 14 + Vercel
폰트 SUIT
광고 구글애드센스나, 카카오에드핏 혹시 모르니 자리만...

다음 편은 진짜 고생한 이야기인데...
사이트를 섹션별로 자르는 일이 생각보다 훨씬 어려웠다. 흰 화면만 찍히고,
배민은 휠을 굴려야 화면이 넘어가고… 🙃
 
 
베타버전 링크공유- 아직 베타라 분류가 어색한 섹션이 있을 수 있다는 점
https://jjinmango-ref.vercel.app/
 

반응형