# Blueocean

> 네이버 API로 키워드의 수요·공급·상업성·추세를 실측해 "검색은 많은데 제대로 답한 글이 없는" 블루오션 주제를 찾는다. 블로그·사이트 주제 선정, 콘텐츠 백로그 우선순위, 니치 평가, SEO 키워드 조사에 쓴다. 트리거 — "블루오션 주제", "키워드 찾아줘", "이 주제 경쟁 어때", "검색량 얼마나 되나", "니치 평가", "무슨 글 써야 하나", "블로그 주제 정하기", "키워드 수요 조사", "포화도", "레드오션인지 확인", "blueocean", "keyword research". 검색량만 보고 주제를 고르려 할 때도 먼저 이걸 돌린다.

- Skill: `formars0309-cloud/blueocean` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add formars0309-cloud/blueocean`
- Raw SKILL.md: https://api.skillmd.com/api/skills/formars0309-cloud/blueocean/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: formars0309-cloud (https://skillmd.com/u/formars0309-cloud)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/formars0309-cloud/blueocean

---


# 블루오션 키워드 판정

검색량만 보고 주제를 고르면 레드오션에 들어간다. 검색량 1만짜리 키워드에 이미 좋은 글이
10만 개 있으면 그건 기회가 아니다. 반대로 검색량 3천에 제대로 답한 글이 없으면 그게 빈 자리다.

**수요와 공급을 함께 재기 전에는 주제를 확정하지 않는다.**

## 도구

```bash
node ~/.claude/skills/blueocean/scripts/blueocean.mjs --seeds 요양병원 요양원 장기요양등급
node ~/.claude/skills/blueocean/scripts/blueocean.mjs --exact 욕창 섬망 본인부담상한제
node ~/.claude/skills/blueocean/scripts/blueocean.mjs --seeds 명조 명조공략 --hot 30
```

| 옵션 | 뜻 |
|---|---|
| `--seeds <k...>` | 시드 키워드. 연관키워드로 확장한 뒤 판정한다 |
| `--exact <k...>` | 확장 없이 이 키워드만 잰다 |
| `--hot <n>` | 기회점수 순 상위 n개. 열기 축을 함께 잰다. 아래 참고 |
| `--revenue <n>` | 수익점수 순 상위 n개. 광고 단가 축으로 줄을 세운다 |
| `--min <n>` | 확장 결과 중 이 검색량 이상만 (기본 500) |
| `--top <n>` | 판정할 개수 (기본 80). 키워드당 검색 API 2회 |
| `--exclude <re>` | 제외 정규식. 아래 '오염 키워드' 참고 |
| `--out <path>` | JSON 저장 경로 (기본 `blueocean.json`) |
| `--json` | 표 대신 JSON 을 표준출력으로 |
| `--no-trend` | 추세 생략. 빠르게 볼 때 |

시드 5개면 연관키워드가 최대 1,000개까지 딸려 나온다. 니치 하나에 시드 3~5개면 충분하다.

## —— 트래픽으로 줄을 세울 때는 `--hot`

기본 정렬(실질포화도)은 **못 쓸 1위를 만든다.** 수요 10에 글 0편인 키워드는 포화 0 으로
A등급 최상위에 오르지만 그 글은 월 10회 노출된다. 실제로 명조 니치를 재 보니 A등급 1~4위가
전부 수요 10~40짜리(`명조음골`, `명조성흔`, `명조성휘광석`)였고, 진짜 자리인 `명조청초`
(수요 3,920 · 글 684편)는 8위에 있었다.

`--hot`은 수요와 공백을 곱해 **트래픽 기회의 상대 순위**를 매긴다. 점수는 실제 월 방문자 예측값이 아니다.

```
reach = 1 / (1 + 실질포화/3)      공백이 클수록 상위에 붙을 확률이 높다
scale = 1 / (1 + 문서수/20000)    포화가 같아도 절대 문서량이 크면 신규 블로그가 못 뚫는다
점수  = 수요 × 0.3 × reach × scale
```

`scale` 이 없으면 헤드 키워드가 무조건 1위가 된다. `명조`(수요 41,100 · 글 12.6만)는
reach 만으로 6,100점이지만 개인 블로그가 12.6만 편을 제칠 확률은 그렇지 않다.
scale 을 곱하면 838점으로 내려가 `명조청초`(1,076점) 아래에 놓인다. 뚫리는 쪽이 위로 온다.

점수의 **절대값은 의미가 없다.** 같은 실행 안에서 키워드끼리 비교하는 용도다.

### 다섯 번째 축 — 열기

`--hot` 일 때만 키워드당 1회를 더 써서 `sort=date` 로 최신 100편을 받는다.
같은 '글 1,000편'이라도 2년에 걸쳐 쌓인 것과 지난주에 쏟아진 것은 완전히 다른데
포화도는 이 둘을 구분하지 못한다.

| 칼럼 | 읽는 법 |
|---|---|
| 신규글/일 | 최신 표본의 절반이 쌓인 속도. 높으면 지금 터지는 이슈이자 남들도 달려드는 중 |
| 30일 | 최신 100편 중 30일 이내 비율. 100%면 살아 있는 주제, 0%면 아무도 안 쓴다 |
| 최근글 | 마지막 글이 며칠 전인가. **수요가 있는데 이 값이 크면 방치된 자리다** |

속도는 양날이라 점수에 넣지 않고 칼럼으로만 보여준다. 해석은 사람이 한다.
`명조청초`는 4.3편/일에 30일 비율 71% — 지금 터지는 중이라 빨리 써야 하고,
`명조용량`은 0.1편/일에 최근글 11일 전인데 YoY 2.46 — 수요는 느는데 아무도 안 쓰는 자리다.

속도는 **최신 절반**으로만 잰다. 표본 전체를 쓰면 꼬리가 결과를 뒤집는다. `명조청초`는
출시 11일차인데 표본 100편 중 29편이 30일보다 오래됐다(네이버가 '청초'를 따로 매칭해
옛 글을 물어온다). 그 29편이 span 을 늘리면 4.3편/일짜리가 0 으로 찍힌다.

## —— 트래픽이 곧 수익은 아니다: `--revenue`

애드포스트 수익은 **노출 × 단가**인데 앞의 축들은 전부 노출만 잰다. 그래서 트래픽이
크고 돈이 안 되는 주제를 1위로 올린다. 실측한 값이 이렇다.

| 키워드 | 월검색 | 광고깊이 | 경쟁 | 광고CTR | 단가배율 |
|---|---|---|---|---|---|
| 손흥민 | 413,400 | **0** | 낮음 | **0.00** | 0.03 |
| 이강인 | 622,800 | **0** | 낮음 | **0.00** | 0.03 |
| KBO순위 | 612,000 | **0** | 낮음 | **0.00** | 0.03 |
| 명조 | 41,100 | 4 | 중간 | 0.42 | 0.33 |
| 실손보험 | 18,480 | 10 | 높음 | 2.88 | 1.15 |

위 표의 조회 당시 연예인·운동선수 키워드는 검색광고 깊이가 0이었다. 검색광고 지표만으로 콘텐츠 광고의 광고주 유무나 애드포스트 수익을 단정할 수는 없다.
검색량 22분의 1인 실손보험이 단가배율 38배다. 트래픽만 보고 연예·스포츠로 가면 안 된다.

```
단가배율 = 경쟁도(낮음 0.2 · 중간 0.6 · 높음 1.0) × (0.15 + 광고깊이/10)
수익점수 = 기회점수 × 단가배율
```

`0.15` 는 바닥값이다. 광고 슬롯이 0 이어도 콘텐츠 광고로 소액은 붙으므로 0 으로 죽이지 않는다.
검색광고 API 같은 응답에 이미 들어 있어 **추가 호출이 없다**.

`--hot` 과 순위가 뒤집히는 일이 흔하다. `발로란트전적검색`은 기회점수 4,716 으로 1위였지만
광고깊이 0 이라 수익점수 141 로 밀리고, 기회점수 2,094 인 `발로란트조준점`(광고깊이 1)이
314 로 올라선다. **트래픽을 원하면 `--hot`, 수익을 원하면 `--revenue` 를 쓴다.**

### 이 도구가 못 재는 것 — SERP 구조

포화도는 '블로그 글 수 ÷ 검색량'이지 **네이버 검색 결과에서 블로그 영역이 실제로 보이는지는
재지 못한다.** 연예·스포츠·시사 쿼리는 네이버가 뉴스·스포츠 전용 영역을 최상단에 박아
블로그가 비집을 자리가 구조적으로 없다. `오늘의운세`(검색 523만, 포화 0, 광고깊이 9)가
수익점수 1위로 찍히지만 실제로는 네이버 자체 운세 서비스가 상단을 차지한다.

**A등급 + 고단가인데 유독 비어 있으면 의심한다.** 왜 아무도 안 썼는지 SERP 를 직접 본다.

## 네 축

| 축 | 출처 | 뜻 |
|---|---|---|
| 수요 | 검색광고 키워드도구 | 월간검색수(PC+모바일) |
| 공급 | API HUB 검색>블로그 | 이미 존재하는 글 수 |
| 상업성 | 같은 검색 결과 상위 10건 | 파는 글의 비율 |
| 추세 | DataLab 검색어트렌드 | 전년 동기 대비 + 성수기 달 |

```
포화도     = 블로그 글 수 / 월간검색수
실질포화도 = 포화도 × (1 − 광고비율 × 0.5)
등급       = A 블루오션(<3) · B 양호(<10) · C 경쟁(<40) · D 레드오션
```

**세 번째 축이 핵심이다.** 문서가 많아도 전부 광고면 정보 공백은 그대로 남는다.
상위 10건이 전부 업체 글인 키워드는 포화도가 40이어도 실제로는 쓸 자리가 있다.

## 결과를 읽을 때 — 반드시 확인할 세 가지

### 1. A등급인데 `성수기 N월!` 이 붙어 있으면 그 등급은 한 달짜리다

`말복`은 검색량 213만, 포화 0.22 로 A등급 1위로 올라온다. 그런데 말복은 8월의 하루다.
월간검색수가 며칠에 몰려 있어서 포화도가 좋아 보일 뿐, 연중 대부분은 아무도 안 찾는다.

**`!` 가 붙은 키워드는 순위가 아니라 발행 시점을 알려주는 신호로 읽는다.**
쓸 가치가 있는 계절 키워드도 있다 — 본인부담상한제는 성수기 8월이지만 평시에도 꾸준히 검색된다.
구분하려면 24개월 곡선을 직접 본다(`--json` 으로 받아서 확인).

### 2. 오염 키워드를 걸러라

연관키워드 확장은 우리 독자가 아닌 것을 잔뜩 물어온다. 실제로 겪은 것들:

| 종류 | 예 | 왜 문제인가 |
|---|---|---|
| 구직자 | `요양보호사`(36,420), `병원동행매니저`(28,350) | 서비스를 받는 사람이 아니라 하려는 사람 |
| 브랜드 | `페넬로페기저귀`, `나비잠기저귀` | 특정 상품. 정보 글로 못 이긴다 |
| 인접 오독 | `기저귀`(33,840) 중 대부분이 신생아용 | 성인용은 9,700 뿐이다 |
| 지역·내비게이션 | `아산병원근처암요양병원`, `강남역` | 글이 아니라 위치를 찾는 검색 |

`--exclude '채용|자격증|학원|중고|근처|가격비교'` 처럼 정규식으로 잘라낸다.
**합산 검색량을 보고하기 전에 무엇이 섞였는지 반드시 뜯어본다.**

### 3. 포화도는 네이버 블로그 생태계의 것이다

구글·AI 검색을 노리는 사이트라면 절대값이 아니라 **키워드 사이의 상대 비교**로만 읽는다.
제도·행정 키워드는 네이버가 과대평가되는 경향이 있다.

## 자격증명

다음 순서로 찾는다. 하나만 있으면 된다.

1. 환경변수
2. `./.env` — 프로젝트 로컬
3. `~/.claude/.naver-api.env` — 전역 (사용자별 설정 필요)

| 키 | 무엇 | 발급 |
|---|---|---|
| `NAVER_AD_API_KEY`<br>`NAVER_AD_SECRET_KEY`<br>`NAVER_AD_CUSTOMER_ID` | 수요. 월간검색수의 유일한 출처 | searchad.naver.com → 도구 → API 사용 관리. 무료, 결제정보 불필요 |
| `NAVER_CLIENT_ID`<br>`NAVER_CLIENT_SECRET` | 공급·추세 | ncloud.com → NAVER API HUB → Application 등록 → 검색(블로그·뉴스)과 Data Lab 체크 |

한도는 넉넉하다. 블로그 검색 25,000회/일, 트렌드 50,000회/월. 후보 80개 판정에 약 170회를 쓴다.

## API 규격이 2026년에 바뀌었다

신규 신청은 **NAVER API HUB**(네이버 클라우드 플랫폼)를 사용한다. 기존 개발자센터에서 2026년 7월 31일 이전 신청한 검색·검색어 트렌드 API는 공식 공지상 2027년 6월 30일까지 지원된다. 이 스크립트는 API HUB 규격을 사용하므로 구형 인증정보를 혼용하지 않는다.

공식 공지: https://developers.naver.com/notice/article/32530

| | 기존 개발자센터 | 현행 |
|---|---|---|
| 헤더 | `X-Naver-Client-Id` / `-Secret` | `X-NCP-APIGW-API-KEY-ID` / `X-NCP-APIGW-API-KEY` |
| 검색 | `openapi.naver.com/v1/search/blog.json` | `naverapihub.apigw.ntruss.com/search/v1/blog` |
| 트렌드 | `openapi.naver.com/v1/datalab/search` | `naverapihub.apigw.ntruss.com/search-trend/v1/search` |

트렌드 경로는 **하이픈이 들어간 `search-trend`** 다. `datalab/*` 계열은 전부 404 다.
검색광고 API(`api.searchad.naver.com`)는 이관 대상이 아니라 HMAC 방식 그대로다.

응답 코드로 원인을 구분한다.

- `404` — 그런 경로가 없다. 오타이거나 규격이 다르다
- `401` — 인증정보와 신청 API를 확인한다. 원인을 상태 코드만으로 단정하지 않는다
- `429` — 한도 초과. 호출 간격을 늘린다

## 추세 지표를 짧은 창으로 내지 마라

12개월치의 '최근 3개월 / 첫 3개월' 비교는 **계절 키워드에서 거짓 하락을 만든다.**
본인부담상한제는 매년 8~9월에 환급 안내문이 나가 그때만 5배로 뛴다.
12개월 창의 앞쪽에 그 스파이크가 걸리면 0.24, 급락으로 찍힌다.
24개월을 받아 같은 달끼리 비교하면 1.74, 성장 중이다.

스크립트는 한국 시간 기준 완료된 월 24개를 조회해 이전 12개월 평균과 최근 12개월 평균을 비교한다. 24개 월의 누락·중복이 있으면 원자료만 보존하고 전년 대비 계산을 생략한다. 직접 계산할 일이 있어도 이 방식을 쓴다.

## 판정 후

블루오션이라고 다 쓸 수 있는 건 아니다. 등급은 **쓸 수 있는 주제인지의 필요조건이지 충분조건이 아니다.**
그 주제로 원천보다 나은 글을 쓸 수 있는지는 따로 판단한다.
프로젝트에 원고 헌장이 있으면 그 기준(원천 우위 테스트 등)을 함께 적용한다.

## 구현 보완 — 2026-09-20

- 광고성은 상위 10건의 거친 추정이다. 일반 제목·요약의 `병원`, `센터`, `상담`만으로는 광고로 판정하지 않는다. 의료기관명으로 끝나는 블로그 이름, 상담 신청·무료 상담·협찬 등 명시적인 신호를 사용한다. 기관 계정도 정보 글을 쓸 수 있으므로 오판 가능성은 남는다.
- JSON의 각 행에 `monthly`(월별 상대 검색 지수), `trendWindow`, `trendComplete`를 보존한다. 월별 지수는 절대 검색량이 아니다.
- JSON의 `warnings`에 조회 실패·추세 누락을 기록하고, 포화도 측정 불가 키워드는 `unmeasured`에 보존한다. `measuredCount`는 순위 산출에 성공한 개수다. 뉴스·추세 등 보조 지표까지 모두 성공했다는 뜻은 아니다.
- 통신 오류·HTTP 429·5xx는 최대 3회 시도하고, 요청마다 30초 제한을 둔다. 인증·경로 오류는 재시도하지 않는다.
- 수익점수는 검색광고 경쟁도·깊이에 기반한 비교용 휴리스틱이다. 실제 CPC·애드포스트 수익을 측정하지 않는다. 광고 CTR은 표시만 하며 점수에는 쓰지 않는다.
- 추세·열기는 정렬 점수에 들어가지 않는 참고 정보다. `--hot`과 `--revenue`를 함께 쓰면 수익 정렬이 우선하고 열기는 조회하지 않는다.
- 검증: `node --test scripts/blueocean.test.mjs` (외부 API 호출 없음).

## 다른 에이전트에서 시작하기

[설치 안내](README.md)를 읽는다. 파일·명령 실행이 가능한 에이전트와 Node.js가 필요하다. API 키가 없으면 설정·테스트까지만 완료하고 사용자에게 발급 경로를 안내한다. 조회하지 않은 수치를 만들지 않는다.

