웹 크롤링으로 수집한 데이터를 어떻게 관리하고 활용할 수 있을까요? 오늘은 Supabase 같은 유료 데이터베이스 대신, 무료로 사용할 수 있는 구글 스프레드시트를 데이터베이스처럼 활용하는 방법을 소개합니다.
왜 구글 스프레드시트를 사용할까?
웹 서비스를 운영하다 보면 데이터베이스 비용 문제에 직면하게 됩니다. Supabase는 훌륭한 서비스지만 무료 플랜에는 명확한 제한이 있습니다.
Supabase 무료 플랜의 한계
- 데이터베이스 용량: 500MB
- 파일 스토리지: 1GB
- 월간 대역폭: 5GB
- 7일간 활동 없으면 프로젝트 일시정지
구글 스프레드시트의 장점
- 완전 무료 (최대 1,000만 개 셀 지원)
- 용량 걱정 없음 (구글 드라이브 15GB 공유)
- 별도 서버 불필요
- 엑셀처럼 직접 수정 가능
- 팀원과 실시간 협업 용이
구글 스프레드시트를 데이터베이스처럼 사용하는 방법
구글 스프레드시트는 단순히 데이터를 저장하는 것을 넘어, CRUD(생성, 읽기, 수정, 삭제) 작업이 모두 가능합니다. Python의 gspread 라이브러리를 사용하면 프로그래밍 방식으로 스프레드시트를 제어할 수 있습니다.
전체 작업 흐름
크롤링 → 구글 스프레드시트 저장 → 스프레드시트 데이터 읽기 → 웹페이지 생성
이 방식은 정적 사이트 생성(Static Site Generation)과 완벽하게 호환됩니다. 매일 자동으로 크롤링을 실행하고, 그 데이터를 스프레드시트에 저장한 뒤, 다시 읽어서 수천 개의 HTML 페이지를 생성하는 것이 가능합니다.
필요한 준비물
1. Python 라이브러리 설치
pip install gspread google-auth google-auth-oauthlib google-auth-httplib2
2. Google Cloud Console 설정
구글 스프레드시트를 프로그래밍 방식으로 사용하려면 Google Cloud Console에서 API를 활성화해야 합니다.
단계별 설정 방법
- Google Cloud Console 접속
- https://console.cloud.google.com/ 접속
- 새 프로젝트 생성 (예: "데이터관리프로젝트")
- API 활성화
- "API 및 서비스" → "라이브러리" 메뉴
- "Google Sheets API" 검색 후 활성화
- "Google Drive API" 검색 후 활성화
- 서비스 계정 생성
- "API 및 서비스" → "사용자 인증 정보"
- "사용자 인증 정보 만들기" → "서비스 계정" 선택
- 서비스 계정 이름 입력 후 "편집자" 역할 부여
- 생성된 서비스 계정의 "키" 탭에서 JSON 키 다운로드
- 다운로드한 파일을
credentials.json으로 저장
- 스프레드시트 공유
- 구글 스프레드시트에서 credentials.json의
client_email확인 - 해당 이메일과 스프레드시트를 "편집자" 권한으로 공유
- 구글 스프레드시트에서 credentials.json의
실전 예제: 카페 정보 데이터 업로드
실제 크롤링한 카페 데이터를 구글 스프레드시트에 업로드하는 Python 코드를 살펴보겠습니다.
1. 기본 인증 및 연결
import gspread
from google.oauth2.service_account import Credentials
import json
def setup_google_sheets():
"""구글 스프레드시트 인증"""
scopes = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive'
]
creds = Credentials.from_service_account_file('credentials.json', scopes=scopes)
client = gspread.authorize(creds)
return client
2. JSON 데이터를 스프레드시트 형식으로 변환
def prepare_data_for_sheets(json_file_path):
"""JSON 데이터를 2차원 리스트로 변환"""
with open(json_file_path, 'r', encoding='utf-8') as f:
cafes = json.load(f)
# 헤더 생성
headers = ['카페명', '도로명주소', '지번주소', '전화번호', '홈페이지',
'소개글', '리뷰개수', '리뷰내용', '크롤링일시']
# 데이터 행 생성
rows = [headers]
for cafe in cafes:
review_count = len(cafe.get('리뷰', []))
review_text = '\n---\n'.join(cafe.get('리뷰', []))
row = [
cafe.get('카페명', ''),
cafe.get('도로명 주소', ''),
cafe.get('지번 주소', ''),
cafe.get('전화번호', ''),
cafe.get('홈페이지', ''),
cafe.get('intro', ''),
review_count,
review_text,
cafe.get('크롤링일시', '')
]
rows.append(row)
return rows
3. 스프레드시트에 데이터 업로드
def upload_to_spreadsheet(client, spreadsheet_name, data):
"""데이터를 스프레드시트에 입력"""
try:
spreadsheet = client.open(spreadsheet_name)
print(f"기존 스프레드시트 열기: {spreadsheet_name}")
except gspread.SpreadsheetNotFound:
spreadsheet = client.create(spreadsheet_name)
print(f"새 스프레드시트 생성: {spreadsheet_name}")
sheet = spreadsheet.sheet1
sheet.update_title('카페데이터')
# 기존 데이터 삭제 후 새 데이터 입력
sheet.clear()
sheet.update('A1', data)
print(f"✅ {len(data)-1}개 데이터 업로드 완료!")
print(f"📊 스프레드시트 URL: {spreadsheet.url}")
return spreadsheet
데이터 수정 및 업데이트 방법
구글 스프레드시트는 단순히 데이터를 저장하는 것뿐만 아니라 수정과 업데이트도 자유롭게 할 수 있습니다.
특정 셀 수정하기
# A1 셀 수정
sheet.update('A1', '강남구')
# 범위 수정
sheet.update('A1:C1', [['지역', '카페명', '가격']])
조건에 맞는 데이터 찾아서 수정하기
# '투썸플레이스' 찾아서 전화번호 수정
cell = sheet.find('투썸플레이스')
sheet.update_cell(cell.row, 4, '032-123-4567')
매일 자동 업데이트 시나리오
def daily_update():
# 1. 최신 데이터 크롤링
new_data = crawl_cafes()
# 2. 스프레드시트 기존 데이터 가져오기
sheet = client.open('카페데이터').sheet1
existing = sheet.get_all_records()
# 3. 변경사항만 업데이트
for new_cafe in new_data:
for idx, old_cafe in enumerate(existing, start=2):
if old_cafe['카페명'] == new_cafe['카페명']:
if old_cafe['전화번호'] != new_cafe['전화번호']:
sheet.update_cell(idx, 4, new_cafe['전화번호'])
스프레드시트 ID 찾는 방법
프로그래밍으로 스프레드시트에 접근할 때는 스프레드시트 ID가 필요합니다. ID는 URL에서 쉽게 찾을 수 있습니다.
URL 구조
https://docs.google.com/spreadsheets/d/[이 부분이 ID]/edit#gid=0
실제 예시
URL: https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
스프레드시트 ID: 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms
코드에서 ID로 열기
# 이름으로 열기 (이름이 바뀌면 오류 발생)
spreadsheet = client.open('카페데이터')
# ID로 열기 (더 안정적)
spreadsheet = client.open_by_key('1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms')
# URL 전체로 열기
url = 'https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit'
spreadsheet = client.open_by_url(url)
스프레드시트에서 데이터 읽어서 웹페이지 만들기
저장된 데이터를 다시 불러와서 정적 HTML 페이지를 생성할 수 있습니다. 이 방식은 GitHub Pages 같은 무료 호스팅과 완벽하게 호환됩니다.
데이터 읽어오기
# 스프레드시트에서 데이터 가져오기
sheet = client.open('카페데이터').sheet1
all_data = sheet.get_all_records()
# 딕셔너리 리스트로 반환
# [{'카페명': '투썸플레이스', '주소': '...', ...}, ...]
HTML 페이지 생성하기
def generate_html(cafes):
"""카페 데이터로 HTML 생성"""
html = """
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>남동구청역 근처 카페</title>
</head>
<body>
<h1>남동구청역 근처 카페 추천</h1>
<div class="cafe-list">
"""
for cafe in cafes:
html += f"""
<div class="cafe-item">
<h2>{cafe['카페명']}</h2>
<p>주소: {cafe['도로명주소']}</p>
<p>전화: {cafe['전화번호']}</p>
<p>리뷰 {cafe['리뷰개수']}개</p>
</div>
"""
html += """
</div>
</body>
</html>
"""
with open('index.html', 'w', encoding='utf-8') as f:
f.write(html)
자동화 시나리오: 매일 업데이트되는 웹사이트
GitHub Actions를 활용하면 매일 자동으로 크롤링 → 스프레드시트 업데이트 → HTML 생성 → 배포까지 전 과정을 자동화할 수 있습니다.
전체 자동화 흐름
- 매일 오전 1시, GitHub Actions가 크롤링 스크립트 실행
- 크롤링한 데이터를 구글 스프레드시트에 저장
- 스프레드시트에서 데이터를 다시 읽어옴
- 데이터를 기반으로 정적 HTML 페이지 생성
- GitHub Pages에 자동 배포
GitHub Actions 설정 예시
name: Daily Update
on:
schedule:
- cron: '0 1 * * *' # 매일 오전 1시
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
- name: Install dependencies
run: pip install gspread google-auth playwright
- name: Run crawler
run: python crawler.py
- name: Upload to Sheets
run: python upload_to_sheets.py
- name: Generate HTML
run: python generate_html.py
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
주의사항 및 팁
1. API 호출 제한
Google Sheets API는 분당 60회 호출 제한이 있습니다. 대량 데이터를 처리할 때는 일괄 처리(batch update)를 사용하세요.
2. 보안 주의사항
credentials.json파일을 Git에 절대 업로드하지 마세요- .gitignore에 반드시 추가하세요
- 서비스 계정 이메일만 공유하고, JSON 키는 비공개로 유지하세요
3. 데이터 크기 제한
- 스프레드시트 최대 셀 개수: 1,000만 개
- 단일 셀 최대 글자 수: 50,000자
- 한글 인코딩은 반드시 UTF-8 사용
4. 성능 최적화
1,000건 이상의 데이터를 다룰 때는 개별 셀 업데이트보다 범위 업데이트를 사용하는 것이 훨씬 빠릅니다.
# 느림: 개별 셀 업데이트
for i, data in enumerate(dataset):
sheet.update_cell(i+1, 1, data)
# 빠름: 범위 일괄 업데이트
sheet.update('A1:A1000', [[data] for data in dataset])
실무 활용 사례
1. 부동산 매물 정보 사이트
매일 아파트 실거래가를 크롤링하여 스프레드시트에 저장하고, 지역별 HTML 페이지를 자동 생성합니다.
2. 교통 시간표 사이트
기차/버스 시간표를 API로 받아와 스프레드시트에 정리한 뒤, 역별 페이지를 생성합니다.
3. 병원/의료시설 검색 사이트
공공 API에서 병원 정보를 수집하여 스프레드시트에 저장하고, 지역별/진료과목별 페이지를 자동 생성합니다.
4. 팀 협업 도구
비개발자 동료가 스프레드시트에서 직접 데이터를 수정하면, 자동으로 웹사이트에 반영됩니다.
마치며
구글 스프레드시트를 데이터베이스처럼 활용하는 방법은 소규모 프로젝트나 개인 사이드 프로젝트에 매우 효과적입니다. 특히 다음과 같은 경우에 추천합니다:
- 데이터베이스 비용을 절약하고 싶을 때
- 비개발자와 협업이 필요할 때
- 정적 사이트 생성 방식을 사용할 때
- 데이터를 직접 확인하고 수정할 필요가 있을 때
물론 대규모 서비스나 실시간 데이터 처리가 필요한 경우에는 전문 데이터베이스를 사용하는 것이 좋습니다. 하지만 많은 경우, 구글 스프레드시트만으로도 충분히 훌륭한 웹 서비스를 만들 수 있습니다.
이 글이 데이터 관리에 고민하시는 분들께 도움이 되길 바랍니다. 궁금한 점이 있다면 언제든 댓글로 남겨주세요!
참고 자료
- gspread 공식 문서: https://docs.gspread.org/
- Google Sheets API 문서: https://developers.google.com/sheets/api
- Google Cloud Console: https://console.cloud.google.com