본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 05. 16. 22:19

note의 PV를 Notion에 자동으로 저장하는 워크플로우를 만들어 보았다

요약

본 글은 note 기사의 주차별 PV(Page View) 데이터를 Notion에 자동으로 저장하는 워크플로우 구축 과정을 다루고 있습니다. 공식 API가 없는 note의 비공식 API를 활용하고, reCAPTCHA 인증 장벽과 n8n을 이용한 자동화 과정에서 겪는 기술적 난관들을 극복한 경험을 공유합니다. 최종적으로 매주 데이터를 스냅샷 형태로 Notion에 기록하여 기사의 시계열적인 성장 추이를 분석할 수 있게 하는 시스템을 완성했습니다.

핵심 포인트

  • note의 공식 API 부재로 인해 비공식 API 엔드포인트(`/api/v1/stats/pv`)를 활용해야 했습니다.
  • 자동화 과정에서 reCAPTCHA 인증 장벽에 직면했으며, 이를 우회하기 위해 수동으로 Cookie를 취득하여 n8n Credential에 등록하는 방식을 채택했습니다.
  • 전체 기간(all)과 이번 주(week)의 PV 데이터를 각각 가져와 Code 노드에서 병합함으로써 정확한 시계열 분석이 가능하도록 설계했습니다.
  • 데이터는 덮어쓰기 방식 대신 매주 새로운 레코드를 추가하는 스냅샷 형태로 Notion에 저장하여 기사의 성장 추이를 효과적으로 추적할 수 있습니다.

서론

note에 기사를 쓰면서 「어떤 기사가 어느 주에 인기가 있었는지」를 나중에 되돌아보는 것이 어렵다고 느꼈습니다.

note의 대시보드에서 임프레션 (PV)은 확인할 수 있지만, 누계치밖에 볼 수 없기 때문에 주차별 성장세를 추적하는 것은 수동으로 해야 합니다. 이상적으로는 Notion에 집어넣고 Notion AI 등을 사용하여 그래프화하고 싶다는 생각을 했습니다.

그래서, 주차별 PV를 스냅샷으로서 Notion에 자동으로 저장하는 메커니즘을 만들었습니다.

과제: note에는 공식 API가 없다

가장 먼저 부딪힌 벽. note는 공식 API를 제공하지 않습니다.

그렇다면 어떻게 하느냐 하면, 브라우저가 백그라운드에서 호출하고 있는 비공식 API를 사용하는 수밖에 없습니다. DevTools의 Network 탭을 살펴보니, /api/v1/stats/pv라는 엔드포인트에서 PV 데이터를 가져오고 있다는 것을 알 수 있었습니다.

시험 삼아 curl로 호출해 보니...

curl -s 'https://note.com/api/v1/stats/pv?filter=all&page=1&sort=pv' \
-H 'Cookie: _note_session_v5=xxxx' \
| jq '.data.note_stats[0]'
{
"id": 122955291,
"name": "初海外ベトナム旅行記⑦ | ダナン🌴",
...

제대로 가져왔습니다. filter=week로 설정하면 이번 주의 PV만 가져올 수도 있습니다.

인증의 벽: reCAPTCHA와의 싸움

API 인증에는 세션 Cookie가 필요합니다. 자동화를 위해 로그인 API를 호출하려고 했더니...

curl -X POST 'https://note.com/api/v1/sessions/sign_in' \
-H 'Content-Type: application/json' \
-d '{"login":"email","password":"pass"}'
{
"error": {
"code": "required_recaptcha",
...

reCAPTCHA에 의해 차단되었습니다. 🥲

터미널에서 직접 curl을 호출할 때는 통과하지만, n8n의 워크플로우에서 HTTP Request로 호출하면 차단됩니다. Cloud Run의 IP가 의심스럽다고 판정되고 있는 것일지도 모릅니다.

시행착오 끝에, curl로 Cookie를 수동으로 취득하여 n8n의 Credential에 등록하는 방식으로 결정했습니다.

# Cookie를 취득하여 저장
curl -s -X POST 'https://note.com/api/v1/sessions/sign_in' \
-H 'Content-Type: application/json' \
...

이 값을 n8n의 Credentials (Header Auth)에 등록해 두면 워크플로우에서 사용할 수 있습니다.

완전 자동화는 아니지만, Cookie가 만료되었을 때만 이 명령어를 실행하여 Credential을 갱신하면 됩니다. 그렇다고 해도 운영 비용 측면에서는 미묘하긴 하네요...

참고로 이 외에 생각나는 방법이라면, Claude Code Routine에 Notion MCP를 사용하여 시키는 것이겠지만, 인증 정보를 Claude에게 전달하는 것은 피할 수 없으므로 미묘하다고 생각하고 있었습니다... (음, 완전 자동화를 할 수 없다면 차라리 이쪽이 더 나을지도?)

워크플로우 설계

n8n을 사용하여 다음과 같은 플로우를 구성했습니다.

플로우차트로 만들어 보겠습니다.

왜 API를 두 번 호출하는가

note의 PV API는 filter 파라미터로 집계 범위를 전환할 수 있습니다.

  • filter=all → 전 기간의 누계 PV
  • filter=week → 이번 주 (일~토)의 PV

이 두 가지를 모두 가져와서 Code 노드에서 noteId를 키로 하여 병합(merge)합니다.

const allStats = $('累計PV取得').first().json.data.note_stats;
const weekStats = $input.first().json.data.note_stats;
const weekStart = $input.first().json.data.start_date;
...

filter=week는 0 PV인 기사가 반환되지 않으므로, ?? 0

를 사용하여 기본값 0을 보완하고 있습니다.

실행 타이밍

filter=week의 집계 기간은 **일요일 00:00 ~ 토요일 23:59 (JST)**입니다. 토요일 23:30에 실행함으로써 해당 주의 거의 모든 데이터를 가져올 수 있습니다.

n8n의 Schedule Trigger에서 Weeks / Saturday / 23:30으로 설정했습니다.

데이터 설계

스냅샷(Snapshot)형 채택

"현재 PV로 덮어쓰기"가 아니라, 매주 새로운 레코드를 추가하는 스냅샷형으로 구성했습니다.

기사 제목기록일누적 PV이번 주 PV
기사A2026-05-08278
...

이를 통해 "언제·어떤 기사가 성장했는지"를 시계열로 추적할 수 있습니다.

Notion의 뷰(View) 설정

  • 이번 주 급상승: 최신 기록일로 필터링 → 이번 주 PV로 내림차순 정렬
  • 누적 PV 랭킹: 최신 기록일로 필터링 → 누적 PV로 내림차순 정렬
  • 특정 기사의 추이: note 기사 ID로 필터링 → 기록일로 오름차순 정렬

주의할 점(ハマりポイント) 정리

DevTools에 API 요청이 표시되지 않음

note의 대시보드는 SSR (Server Side Rendering, 서버 사이드 렌더링)로 반환하기 때문에, 브라우저의 Network 탭을 열어도 stats/pv 요청이 표시되지 않습니다.

대신 「주/월/년/전체 기간」 탭을 전환하면 동적으로 API가 호출되므로, 그곳에서 확인할 수 있습니다.

reCAPTCHA 차단

앞서 언급한 바와 같이, 워크플로우 내부에서의 로그인 API는 reCAPTCHA에 의해 차단됩니다. curl을 사용하면 통과되므로 그 방식으로 대응했습니다.

Notion 노드의 0건 문제

처음에는 Notion의 「Get Many」 노드로 이전 스냅샷을 검색하여 차이(diff)를 계산하려고 했으나, 데이터가 0건일 때 n8n이 후속 노드를 실행하지 않는 사양 때문에 어려움을 겪었습니다.

최종적으로 API에 filter=week가 있다는 것을 발견하여, Notion을 검색할 필요 자체가 없어졌고 심플하게 해결되었습니다.

요약

  • note에 공식 API는 없지만, 비공식 API로 충분히 가져올 수 있음
  • reCAPTCHA가 장벽이었으나, 수동 curl로 Cookie를 획득하는 운용 방식으로 대응
  • filter=week를 사용하면 차이(diff) 계산이 불필요하여 워크플로우가 단순해짐
  • 스냅샷형으로 Notion에 축적함으로써 시계열 분석이 가능함

완전 자동화는 할 수 없었지만, Cookie가 만료되었을 때만 명령어를 한 번 실행하는 수준의 운용 비용으로 줄었습니다. 음, 하는 느낌이지만, 조금 더 해보고 돌아보도록 하겠습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0