3편까지는 코드 얘기만 했다. 이번 편은 돈 얘기다.
블로그에 글을 쓰면 방문자가 읽고 나간다. 체류 시간 1~2분. 공공데이터 API를 연동한 도구 페이지를 만들면? 사용자가 이것저것 조회하면서 3~5분을 머문다. 이 차이가 구글 애드센스 수익에 직접 영향을 준다. 실제 운영 경험을 바탕으로 수익화 전략과 운영 노하우를 정리한다.
도구 페이지가 글보다 수익화에 유리한 이유
구글 애드센스 수익은 노출 수와 클릭률에 비례한다. 둘 다 체류 시간과 관련이 있다.
체류 시간 비교
- 일반 글: 평균 체류 시간 1~2분. 읽고 나간다.
- 도구 페이지: 평균 3~5분. 지역 바꿔보고, 다른 키워드 검색하고, 결과를 비교한다.
미세먼지 페이지를 예로 들면, 서울을 보다가 부산으로 바꿔보고, 경기도 확인하고, 자기 동네 측정소 수치를 찾아본다. 한 번 방문에 3~4번의 상호작용이 일어난다. 상호작용이 많을수록 페이지에 머무르는 시간이 길어지고, 광고 노출 기회도 늘어난다.
재방문율
글은 한 번 읽으면 다시 안 온다. 하지만 미세먼지 조회, 사업자등록 확인 같은 도구는 필요할 때마다 다시 찾아온다. 특히 사업자등록 상태조회는 거래처를 확인할 때마다 쓰니까 반복 방문이 생긴다.
구글 평가
구글은 체류 시간이 긴 페이지, 재방문이 많은 페이지를 높이 평가한다. 유용한 도구를 제공하면 검색 순위에서도 유리해진다. “미세먼지 실시간”으로 검색했을 때 단순 정보 나열 글보다 직접 조회할 수 있는 도구 페이지가 상위에 노출될 가능성이 높다.
“뾰족한 가공”이 중요하다
네이버가 이미 미세먼지 정보를 보여준다. 카카오도 한다. 그런데 왜 우리 사이트에 와야 할까?
핵심은 가공이다. 네이버는 범용 서비스라 모든 사람에게 같은 형태로 보여준다. 우리는 특정 니즈에 맞춰 가공할 수 있다:
- 미세먼지: 측정소별 상세 데이터 + 시도 평균 비교 (네이버는 도시 단위만)
- 약국 찾기: 영업시간까지 한눈에 (네이버 지도는 클릭해서 들어가야 보임)
- 기업정보: 상장/비상장 구분 + 중복 법인 필터링 + 주요 재무 지표
- 사업자 확인: 복수 번호 동시 조회 (국세청 홈택스는 1건씩만)
“같은 데이터를 다르게 가공”하는 것이다. 데이터 자체는 공공이지만, 가공 방식이 차별점이 된다.
SEO: 도구 페이지에 텍스트가 필수인 이유
처음에 도구 페이지를 만들 때, 검색 폼과 결과만 달랑 넣었다. HTML에 텍스트 콘텐츠가 거의 없었다. 결과는? 구글 인덱싱은 됐는데 검색 순위가 바닥이었다.
구글 봇은 JavaScript를 실행하지 않고 HTML만 본다. AJAX로 결과를 로드하면 봇에게는 빈 페이지나 마찬가지다. 해결책:
- 도구 위에 해당 서비스를 설명하는 텍스트 400~800자를 추가
- 도구 아래에 사용법, FAQ 등을 추가
- 초기 렌더링 시 서버사이드에서 기본 데이터(서울 미세먼지 등)를 HTML에 포함
3번이 특히 중요하다. 미세먼지 페이지는 서울 데이터를 PHP에서 바로 렌더링하고, 다른 시도는 AJAX로 전환한다. 봇이 크롤링할 때 서울 데이터가 HTML에 포함되어 있으니 “이 페이지는 미세먼지 정보를 제공한다”고 인식할 수 있다.
캐싱 전략 총정리
wp-config.php에서 모든 API의 캐시 시간을 중앙 관리한다. 현재 설정:
// wp-config.php
define( 'NALKKUL_CACHE_AIR', 1800 ); // 미세먼지: 30분
define( 'NALKKUL_CACHE_PHARMACY', 3600 ); // 약국: 1시간
define( 'NALKKUL_CACHE_COMPANY', 3600 ); // 기업정보: 1시간
define( 'NALKKUL_CACHE_BIZ', 3600 ); // 사업자조회: 1시간
define( 'NALKKUL_CACHE_WEATHER', 1800 ); // 날씨: 30분
define( 'NALKKUL_CACHE_STOCK', 600 ); // 증시: 10분 (장중)
define( 'NALKKUL_CACHE_HOLIDAYS', 86400 ); // 공휴일: 24시간
define( 'NALKKUL_CACHE_REALESTATE', 3600 ); // 부동산: 1시간
define( 'NALKKUL_CACHE_NUTRITION', 3600 ); // 영양정보: 1시간
define( 'NALKKUL_CACHE_WHOIS', 3600 ); // 도메인조회: 1시간
define( 'NALKKUL_CACHE_HOSPITAL', 3600 ); // 병원: 1시간
define( 'NALKKUL_CACHE_CARRECALL', 3600 ); // 자동차 리콜: 1시간
define( 'NALKKUL_CACHE_MEDICINE', 3600 ); // 의약품: 1시간
원칙은 간단하다:
- 실시간성이 중요한 데이터(미세먼지, 증시): 10~30분
- 하루에 한 번 바뀌는 데이터(공휴일): 24시간
- 변동이 적은 데이터(기업정보, 약국): 1시간
캐시 시간을 상수로 분리한 이유는, 배포 후 조정이 필요할 때 코드를 건드리지 않고 wp-config.php만 수정하면 되기 때문이다.
API 호출 한도 관리
공공데이터포털 API는 기본 하루 1,000회 호출 한도가 있다. 추가 신청하면 늘릴 수 있지만, 캐싱을 잘 하면 1,000회로도 충분하다.
계산해보자. 미세먼지 API: 17개 시도 x (1800초 캐시 = 하루 48회 갱신) = 최대 816회/일. 실제로는 모든 시도를 매번 조회하는 게 아니니 200~300회 수준이다. 여기에 약국, 기업정보 등을 합쳐도 1,000회 안에서 해결된다.
추가로 IP 기반 rate limiting을 넣어서 한 사용자가 시간당 30회 이상 API를 호출하지 못하게 막는다. 이건 2~3편에서 다뤘다.
에러 처리와 폴백
공공데이터 API는 가끔 점검하고, 간혹 장애가 난다. 서비스 안정성을 위해 두 가지 폴백 전략을 쓴다.
1. 마지막 성공 데이터 저장
미세먼지 서비스에서 쓰는 방식이다. API 호출 성공 시 wp_options에 데이터를 저장하고, 실패 시 거기서 가져온다. 데이터가 30분 전 것이라도 빈 화면보다 낫다.
2. 대체 엔드포인트
약국 찾기에서 쓰는 방식이다. 첫 번째 엔드포인트가 실패하면 두 번째 엔드포인트로 시도한다. 같은 데이터를 다른 경로로 제공하는 API가 있으면 이 전략이 효과적이다.
다크모드 대응
모든 서비스에 다크모드를 지원한다. 패턴은 동일하다: body.dark-mode 클래스를 감지해서 배경/텍스트/테두리 색상을 오버라이드.
다크모드에서 주의할 점:
- 순수 흰색(#fff) → #1f2937 또는 #1e293b (어둡지만 완전 검정은 아님)
- 순수 검정 텍스트(#000) → #e4e4e7 (밝지만 완전 흰색은 아님)
- 등급 색상(좋음 파랑, 나쁨 빨강)은 유지하되 opacity를 살짝 낮춤
- 그라데이션 배경은 채도를 낮춘 버전 사용
- box-shadow 강도를 높임 (어두운 배경에서는 그림자가 잘 안 보이므로)
모바일 반응형
접속자의 70% 이상이 모바일이다. 모든 서비스에 3단계 반응형을 적용한다:
- 데스크톱 (900px+): 3열 또는 2열 그리드
- 태블릿 (600~900px): 2열 그리드
- 모바일 (600px-): 1열, 풀 너비
모바일에서 특히 신경 쓸 점:
- 드롭다운과 입력 필드를 세로 배치 (가로로 넣으면 너무 좁음)
- 터치 영역 최소 44px 확보 (애플 HIG 기준)
- 전화번호에 tel: 링크 (모바일 탭으로 바로 통화)
- 카드 사이 간격 넓히기 (손가락 오탭 방지)
법적 주의사항
공공데이터는 원칙적으로 자유롭게 활용할 수 있다. 하지만 지켜야 할 것들이 있다:
- 출처 표기 필수: “데이터 출처: 공공데이터포털(data.go.kr)” 문구를 페이지에 명시
- 이용 약관 준수: 각 API의 이용 약관에 명시된 금지 사항 확인 (예: 대량 크롤링 금지)
- 개인정보: 사업자등록 상태조회로 알게 된 정보를 수집/저장하면 안 된다 (우리 서비스도 조회만 하고 저장하지 않음)
- API 키 노출 금지: 클라이언트 측 코드에 API 키를 직접 넣지 않는다. 서버(PHP)에서만 호출
현재 운영 중인 공공데이터 서비스 목록
현재 이 사이트에서 운영 중인 공공데이터 API 서비스들이다. 각각의 mu-plugin 파일명과 함께 정리한다.
| # | 서비스 | 파일 | API 출처 |
|---|---|---|---|
| 1 | 미세먼지 실시간 | air-quality.php | 에어코리아 |
| 2 | 약국 찾기 | pharmacy-finder.php | 건강보험심사평가원 |
| 3 | 병원 찾기 | hospital-finder.php | 건강보험심사평가원 |
| 4 | 기업정보 조회 | company-info.php | 금융위원회 |
| 5 | 사업자등록 확인 | biz-check.php | 국세청 |
| 6 | 부동산 실거래가 | real-estate.php | 국토교통부 |
| 7 | 식품 영양정보 | food-nutrition.php | 식품의약품안전처 |
| 8 | 공휴일 정보 | holidays.php | 천문연구원 |
| 9 | 자동차 리콜 | car-recall.php | 국토교통부 |
| 10 | 의약품 정보 | medicine-info.php | 식품의약품안전처 |
| 11 | 출입국 통계 | immigration-stats.php | 법무부 |
11개 서비스를 만들면서 얻은 교훈:
- API마다 응답 형식이 다르다. 공통 파서를 만들려는 시도는 포기했다. 각 API에 맞는 전용 파서를 만드는 게 결국 빠르다.
- 캐시 시간은 처음에 짧게 잡고 서서히 늘려라. 1시간이면 충분한 걸 10분으로 잡으면 API 한도만 소진된다.
- 에러 메시지를 사용자 친화적으로 쓰자. “HTTP 403” 대신 “API 인증키가 유효하지 않습니다. data.go.kr에서 확인해주세요.”
- 모든 서비스에 폴백을 넣어라. API 장애는 우리가 통제할 수 없다.
- serviceKey 인코딩 실수는 여전히 새 API를 붙일 때마다 한 번씩 한다.
mu-plugin 파일 하나의 구조
시리즈를 통해 반복된 패턴을 정리하면, 공공데이터 서비스 mu-plugin의 표준 구조는 이렇다:
- 상수 & 헬퍼 함수 (등급 판정, 포맷팅, rate limiting)
- API 호출 함수 (캐싱 + 폴백 포함)
- AJAX 핸들러 (wp_ajax + wp_ajax_nopriv)
- 렌더 함수 (HTML 생성)
- CSS (인라인, 다크모드 포함)
- 숏코드 등록 (shortcode → 렌더 + JS)
이 구조를 따르면 새로운 공공데이터 API를 추가할 때 빠르게 개발할 수 있다. 실제로 처음 미세먼지 서비스를 만드는 데 이틀 걸렸지만, 이후 서비스들은 반나절이면 충분했다.
시리즈를 마치며
4편에 걸쳐 워드프레스에서 공공데이터 API를 활용하는 방법을 다뤘다. 핵심을 한 줄로 요약하면:
공공데이터는 무료이고, 가공 방식이 차별화 포인트이며, 도구 페이지는 블로그 글보다 수익화에 유리하다.
data.go.kr에는 수천 개의 API가 있다. 이 중에서 자기 블로그 주제와 맞는 것을 골라 서비스를 만들면, 다른 블로그와 확실히 다른 가치를 제공할 수 있다. 코드는 공개된 패턴을 따르면 되고, 진짜 중요한 건 “어떤 데이터를 어떻게 가공할 것인가”다.
시리즈 전체 목차
- 1편: 미세먼지 실시간 조회 서비스
- 2편: 약국/병원 찾기 서비스
- 3편: 기업정보 조회와 사업자등록 확인
- [현재 글] 4편: 수익화 전략과 운영 노하우
데이터 출처: 공공데이터포털(data.go.kr)