본문으로 건너뛰기
취준생을 위한 n8n 실전 워크플로우 레시피 · 15/44시리즈 보기 →

수집·정제·분석 한 바퀴 — 포켓몬 API로 배우는 n8n 데이터 분석

· 약 10분
Datapopcorn CEO / AI automation educator
이 글과 연결된 글 보기
7편 · 20개 연결
100%
수집·정제·분석 한 바퀴 — 포켓몬 API로 배우는 n8n 데이터 분석n8n Data Table 처음 써보기 — 트렌드 3개를 합쳐 매일 아침 분석 주제 뽑는 워크플로우n8n으로 정적 웹서버 운영하기 — 수료증 발급부터 진위 확인까지, 멱등 처리로 안전하게벡터DB 없이 실시간으로 사이트를 읽는 챗봇 — 경복대학교 안내 챗봇 해부n8n으로 반복업무 자동화 포트폴리오 만들기구글시트에 쌓인 데이터를 인스타그램 카드뉴스로 — n8n 시트 인스타그램 자동발행서브워크플로우를 Tool로 감싸 AI Agent에게 서버 점검시키기 — 그리고 시스템 프롬프트만으로는 부족한 이유

드래그로 이동 · 휠/두 손가락으로 확대 · 방향키로 글 선택 · 0으로 맞춤. 실선: 본문 링크, 점선: 시리즈·주제의 대표 연결.

표시된 글 7편 목록
전체 글 연결 탐색

포켓몬 API 하나로 데이터 수집, 정제, AI 분석, 정리까지 데이터 분석의 네 단계를 전부 n8n 노드로 만들어볼 수 있습니다. 인증키 발급 절차가 아예 없는 무료 API라 계정 신청 없이 바로 시작할 수 있고, 완성하고 나면 "데이터 분석에 n8n을 써봤다"는 말을 노드 하나하나로 증명할 수 있습니다.

이 워크플로우 하나로 보여줄 수 있는 것​

이 시리즈에서 지금까지는 공공데이터 API를 시트에 쌓는 법과, 받아온 데이터를 다루기 좋게 다듬는 법을 각각 다뤘습니다. 이 편은 그 둘을 한 워크플로우 안에서 잇고 AI 분석까지 붙여, "자동화"가 아니라 "분석" 역량을 보여주고 싶은 사람에게 맞습니다.

  • 반복 API 호출로 대량 수집 — 목록 API가 돌려준 상세 URL을 그대로 다시 호출해 20건을 순서대로 모으는 경험
  • 중첩 JSON 정제 — 배열 안에 배열이 들어 있는 응답에서 숫자 하나만 뽑아내는 경험
  • 여러 아이템을 하나로 묶어 AI에 넘기기 — LLM에게 원본 데이터를 통째로 던지지 않고, 집계된 숫자만 정리해서 넘기는 경험
  • 분석 결과를 리포트로 정리 — 차트 이미지와 AI의 텍스트 설명을 이메일 한 통으로 합치는 경험

배경 — 왜 하필 포켓몬 API인가​

원본 캔버스의 첫 번째 스티키 노트에는 노드를 만들기 전에 먼저 적어둔 기획이 남아 있습니다.

0. 분석 목적 기획 포켓몬 데이터로 뭐를 보면 좋을까? Q. 속성별로 포켓몬 수는 얼마나 될까. 물, 풀, 불, 전기, 에스퍼, 비행, 독, 바위, 곤충

노드를 배우기 전에 "무엇을 볼지"부터 정하는 이 순서가 데이터 분석의 첫 단계이고, 이 흐름은 "속성별 포켓몬 수"라는 질문 하나에 답하는 것으로 범위를 좁혀 만들어졌습니다.

포켓몬 API를 고른 이유는 노드 파라미터를 보면 바로 드러납니다. 이 워크플로우의 HTTP Request 노드 어디에도 인증 설정이 없습니다. 대부분의 공공데이터 API는 서비스키를 먼저 발급받아야 하는데, 포켓몬 API는 그 절차가 통째로 생략됩니다. 실제로 원본 캔버스에는 국립박물관 공공데이터포털 API를 호출해본 노드도 하나 떠 있는데, 그쪽은 URL에 serviceKey={API_KEY} 파라미터가 꼭 필요합니다. 대신 응답 구조는 꽤 복잡합니다. 포켓몬 하나의 정보 안에 타입, 능력치, 특성이 전부 배열로 중첩되어 있어서, "필요한 것만 골라내는" 정제 연습으로는 오히려 적당한 난이도입니다.

n8n 설치와 기본 노드 사용법은 n8n으로 반복업무 자동화 포트폴리오 만들기에 정리돼 있으니, 이 글에서는 이 워크플로우 자체만 다룹니다.

구조 — Trigger / Task / Target​

  • Trigger — 수동 실행. 정기적으로 도는 자동화가 아니라 필요할 때 한 번 돌려 리포트를 받는 용도입니다
  • Task — 타입 목록 수집 → 타입별 상세 재조회 → 타입명·개체수만 정제 → 한 덩어리로 모아 AI 분석 + 차트 URL 조립
  • Target — 슬랙에 차트 링크, Gmail에 차트 이미지와 AI 설명을 합친 리포트

만들기​

1. HTTP Request — 타입 전체 목록 가져오기 (수집 1)​

https://pokeapi.co/api/v2/type?limit=100을 호출하면 물, 풀, 불처럼 포켓몬 타입 약 20종의 이름과 상세 조회 URL이 배열로 돌아옵니다. 인증 헤더도 쿼리 파라미터도 필요 없이 URL만 넣으면 됩니다.

2. Split Out + HTTP Request — 타입별 상세 조회 (수집 2)​

Split Out 노드에서 Field To Split Out을 results로 두면, 배열 하나였던 응답이 타입 하나당 아이템 하나로 쪼개집니다. 다음 HTTP Request의 URL 칸에는 {{ $json.url }}을 그대로 넣습니다. 앞 단계 응답에 각 타입의 상세 URL이 이미 들어 있어서, 그 값을 그대로 다시 호출하는 구조입니다. 이렇게 타입 20종을 20번 호출하면, 각 응답 안의 pokemon 배열 길이가 곧 그 타입에 속한 포켓몬 수가 됩니다.

여기서 눈여겨볼 점이 있습니다. 스티키 노트 하나에는 "약 1300종의 포켓몬별 속성을 구해야 합니다"라는 메모가 남아 있어서, 얼핏 보면 포켓몬 1300여 마리를 한 마리씩 불러야 할 것 같습니다. 하지만 실제 흐름은 타입 API를 20번만 부릅니다. 타입 상세 응답 안에 이미 그 타입에 속한 포켓몬 목록이 다 들어 있기 때문입니다. 처음 세운 계획(1300번 호출)과 실제 구현(20번 호출) 사이의 이 차이는, API 응답 구조를 한 번 살펴보는 것만으로 호출 횟수를 크게 줄일 수 있다는 흔적입니다.

3. Set — 타입명과 개체수만 남기기 (정제)​

Edit Fields(Set) 노드에서 두 필드만 남깁니다.

  • type_name: {{ $json.name }}
  • poke_count: {{ $json.pokemon.length }}

타입 상세 응답에는 포켓몬 각각의 이름·도감 번호까지 배열로 딸려 오지만, 지금 필요한 건 "몇 마리인가"라는 숫자 하나뿐입니다. 배열 전체를 넘기지 않고 .length로 개수만 뽑아내는 순간이 정제가 일어나는 지점입니다.

4. Aggregate — 20개를 하나로 모으기 (분석 준비)​

Aggregate 노드를 Aggregate All Item Data로 설정하면, 타입 20개짜리 아이템이 data라는 필드 하나에 배열로 담긴 아이템 1개가 됩니다. 다음 AI Agent 노드에 데이터를 20번 나눠 보내지 않고 한 번에 통째로 넘기기 위한 준비 단계입니다.

5. AI Agent — Gemini에게 분포를 설명시키기 (분석)​

AI Agent 노드의 Prompt Type을 Define으로 두고 Text에 {{ $json.data }}를 넣습니다. Chat Model에는 Google Gemini Chat Model 노드를 연결합니다. System Message는 이렇게 되어 있습니다.

# 역할
너는 포켓몬 세계의 오박사야. 초보 트레이너에게 포켓몬 타입 분포를 친절하게 설명해줘.

# 분석 항목
1. 극값 분석: 가장 많은/적은 타입 + 그 이유 추측
2. 특이점: 예상 밖의 패턴이나 불균형
3. 근본 타입 비교: 물/풀/불 vs 나머지 타입 비율

# 출력 형식
- 말투: "~란다", "~하는구나" 등 오박사 어투
- 길이: 각 항목당 2-3문장

숫자만 나열하는 대신 "가장 많은 타입은 왜 많을까"까지 추측해서 설명하라고 시킨 부분이 핵심입니다. 단순 집계와 AI 분석의 차이가 여기서 갈립니다.

원본은 {{ $json.data }}를 텍스트 칸에 그대로 넣었습니다. 배열이나 객체를 텍스트 필드에 그대로 물리면 노드마다 보이는 방식이 다를 수 있어서, 직접 만든다면 {{ $json.data.toJsonString() }}처럼 n8n의 확장 메서드로 명시적으로 문자열화해두는 편이 안전합니다.

6. Set — 차트 URL 조립, Limit — 하나만 남기기​

Edit Fields와 나란히 붙은 또 다른 Set 노드는 quickchart.io로 막대그래프 이미지를 만드는 URL을 조립합니다.

=https://quickchart.io/chart?c={{ encodeURIComponent(JSON.stringify({
type: "bar",
data: {
labels: $("Edit Fields").all().map(item => item.json.type_name),
datasets: [{
label: "Pokemon Count",
data: $("Edit Fields").all().map(item => parseInt(item.json.poke_count))
}]
}
})) }}

$("Edit Fields").all()은 $json과 다릅니다. $json은 지금 이 노드로 들어온 아이템 하나만 가리키지만, $("노드이름").all()은 그 노드가 지금까지 출력한 아이템 전체를 가져옵니다. 이 노드는 타입 아이템마다(20번) 실행되는데, 매번 20개 전체 목록을 다시 끌어와 같은 차트 URL을 반복 생성합니다. 그래서 바로 뒤에 Limit 노드를 두어 1개만 남기고 나머지는 버립니다.

이 필드는 이름을 비워둔 채 저장되어 있어서, 뒤에서 참조할 때 {{ $json[''] }}처럼 빈 문자열 키로 불러야 합니다. Set 노드에서 필드 이름을 실수로 비워두면 이렇게 되니, 직접 만들 때는 chart_url처럼 이름을 붙여두는 편이 나중에 읽기 편합니다.

7. Slack과 Gmail — 정리해서 보내기​

Limit을 통과한 차트 URL은 두 갈래로 갑니다. 하나는 Slack의 Send a message 노드로 가서 채널 하나를 골라 차트 링크를 올립니다. 다른 하나는 Merge 노드(Combine, Combine All)에서 AI Agent의 분석 텍스트와 합쳐집니다.

Merge를 거치면 아이템 하나에 차트 URL과 output(AI 분석 텍스트)이 함께 들어 있습니다. Gmail 노드는 이 둘로 HTML 이메일을 조립합니다. 차트 URL은 이미지 태그의 src 값으로, {{ $json.output }}은 본문 텍스트로 각각 끼워 넣는 구조입니다. 보내는 대상은 회사 Gmail 계정 하나로 고정되어 있습니다.

원본 캔버스에 남아 있는 흔적​

본 흐름과 연결되지 않은 노드가 두 개 더 떠 있습니다. 둘 다 만들면서 남긴 연습 흔적입니다.

첫 번째는 "pikachu"라는 이름의 HTTP Request 노드인데, 실제 요청 URL은 https://pokeapi.co/api/v2/pokemon/oddish로 뚜벅쵸(oddish)를 부릅니다. 이름과 실제 대상이 다른 채로 남아 있는, 만들다 보면 흔히 생기는 흔적입니다. 이 노드는 "detail"이라는 Set 노드로 이어지고, 여기서 포켓몬 한 마리의 중첩 JSON을 아홉 개 필드로 평탄화합니다.

id, name, type(= types.map(타입명)), height(m)(= height / 10),
weight(kg)(= weight / 10), abilities(= abilities.map(특성명)),
cries, sprites, stat(= stats를 {통계명: 수치} 객체로 변환)

stat 필드의 변환식이 특히 실용적입니다.

{{ Object.fromEntries($json.stats.map(item => [item.stat.name, item.base_stat])) }}

stats는 원래 [{ stat: { name: "hp" }, base_stat: 45 }, …] 형태로 이름과 값이 각자 다른 객체에 흩어져 있습니다. Object.fromEntries와 .map을 조합하면 이 배열을 { hp: 45, attack: 49, … } 같은 평평한 객체로 바꿀 수 있고, 다른 API의 중첩 배열-객체 구조에도 그대로 옮겨 쓸 수 있습니다. 이 필드 목록은 스티키 노트 "각 포켓몬의 정보를 표로 표현해보기: id, name, type, stat, sprite, weight, height"와 정확히 일치해서, 본 흐름 전에 포켓몬 한 마리로 정제 방법부터 연습해본 흔적으로 보입니다.

두 번째는 국립박물관 공공데이터포털 API(emuseum.go.kr)를 호출해본 HTTP Request 노드입니다. 실행 결과가 pin되어 남아 있는데, 응답 안의 이미지 URL마다 서비스키가 그대로 노출돼 있어 이 글에는 옮기지 않습니다. 요청 URL 형태만 보면 serviceKey={API_KEY} 파라미터가 필수인 구조로, 앞서 말한 것처럼 포켓몬 API와 대조되는 지점입니다.

이 워크플로우는 active: false 상태로, 수동으로 한 번 돌려 리포트를 받는 흐름으로 남아 있습니다. AI Agent 노드에는 실행 결과도 pin되어 있는데, "물 타입이 가장 많고, 얼음 타입이 가장 적다"는 식으로 실제 숫자를 인용해 설명한 사례가 남아 있어 시스템 프롬프트가 의도한 오박사 말투대로 나온다는 걸 확인할 수 있습니다.

한계​

  1. 수동 실행 전제 — Manual Trigger만 있어서 매일 자동으로 리포트를 받으려면 Schedule Trigger로 바꿔야 합니다.
  2. 중복 생성 후 자르는 구조 — 차트 URL을 20번 반복 생성하고 Limit으로 1개만 남기는 방식은 비효율적입니다. Aggregate 쪽에서 바로 차트를 만들면 Limit 없이도 됩니다.
  3. 이름 없는 필드 — $json['']로만 참조할 수 있는 필드가 두 곳에 남아 있어, 나중에 워크플로우를 고칠 사람이 헷갈리기 쉽습니다.
  4. 수신자 고정 — Gmail 발송 대상이 노드 안에 하나로 고정돼 있어서, 여러 사람에게 보내려면 반복 구조나 배포 대상 관리가 따로 필요합니다.

포트폴리오·면접 포인트​

이 워크플로우는 "카테고리별로 모아서 세고, AI에게 설명시킨다"는 뼈대만 유지하면 다른 공개 API로 옮겨갈 수 있습니다. 지역별 평균 기온, 대여소별 이용 건수, 통화별 환율 변동처럼 "집계 가능한 숫자 + AI 설명"이 되는 데이터라면 이 구조가 대부분 들어맞습니다.

면접에서 "왜 AI에게 포켓몬 1300여 마리 데이터를 통째로 넘기지 않았나요?"라는 질문이 올 수 있습니다. 답은 이 워크플로우 구조에 그대로 있습니다. 원본 스티키 노트에는 포켓몬 전체를 하나씩 조회하려던 계획이 남아 있지만, 실제로는 타입 API가 이미 타입별 목록을 갖고 있다는 걸 발견하고 호출을 20번으로 줄였고, 그 20개조차 AI에게는 원본 배열이 아니라 Aggregate로 정제한 숫자만 넘겼습니다. 응답 구조를 먼저 살펴보고 필요한 만큼만 요청과 데이터를 줄이는 판단이 정제의 핵심이라고 설명하면, 노드 사용법이 아니라 데이터를 다루는 감각을 보여줄 수 있습니다.

다음 액션​

다음 편에서는 같은 수집→정제→분석 뼈대를 경제지표 API에 적용해, 매일 아침 투자 리포트를 만드는 흐름으로 넘어갑니다. 입력은 포켓몬 타입 대신 환율·금리 같은 숫자로 바뀌지만, 여러 값을 모아 AI에게 설명을 맡기는 구조는 이 편과 같습니다.