Scraper Hub API

네이버 카페(윈도우 수집기)

플레이그라운드에서 수집 →

채널 코드 naver_cafe_win · 수집 환경 windows

사무실 윈도우 PC 에서 도는 네이버 카페 수집기(NaverCafeScraper)로 회원 전용 카페를 수집합니다. 계정(Chrome 프로필)마다 사람이 한 번 로그인해 두면 그 세션을 계속 재사용하므로 아이디/비밀번호를 API 로 보내지 않습니다. 요청은 수집 서버 이름(server)·계정 이름(account)·숫자 카페 ID(cafe_id)·키워드 목록(keywords)을 지정하며, 유효한 조합은 GET /api/v1/cafe-servers 로 조회합니다. 서버가 오프라인이거나 계정이 로그아웃 상태면 요청이 409 로 거절되고, 계정에 연결되지 않은 카페는 422 로 거절됩니다. 키워드마다 카페 내 검색 → 글 상세(본문·댓글)를 사람처럼(human 모드) 읽어 글 단위로 합쳐 돌려줍니다. ⚠️ 무인 운영 중 로그인이 끊기면 기다리지 않고 즉시 failed 로 끝납니다(재시도 없음 — 수집 서버에서 로그인 후 다시 요청).

요청 파라미터

아래 값들을 POST /api/v1/collect 의 params 객체에 담아 보냅니다.

키타입필수기본설명
server text 예 — 허브에 등록된 윈도우 수집 서버 ID(WORKER_ID, 예: win-office-01). GET /cafe-servers 로 조회
account text 예 — 그 서버의 수집기 앱에 등록된 계정(Chrome 프로필) 이름(예: 기본). 네이버 아이디가 아님
cafe_id text 예 — 그 계정이 가입한 카페의 숫자 ID(예: 10258021). 인벤토리에 없는 카페는 422 cafe_not_linked
keywords text 예 — 배열(["a","b"]) 또는 쉼표/줄바꿈 구분 문자열. 최대 20개. 키워드마다 카페 내 검색 후 글 단위로 합침
exclude_keywords text — — 이 단어가 제목이나 본문에 들어간 글은 제외. 배열 또는 쉼표/줄바꿈 구분 문자열(항목 안 띄어쓰기 허용, 대소문자 무시, 부분일치), 최대 50개. 제목은 목록 단계에서 상세를 열지 않고 거르고, 본문은 상세를 읽은 뒤 한 번 더 거름. 제외분은 키워드당 상한에 세지 않음(summary.excluded)
start_date date (YYYY-MM-DD) — — 비우면 최근 7일. 카페 검색의 기간 필터로 전달
end_date date (YYYY-MM-DD) — — 당일 포함. 비우면 오늘까지
max_pages number — 10 검색 결과 페이지 탐색 한도(키워드당)
limit number — 200 키워드당 최대 글 수. 여러 키워드에 걸린 글은 1건으로 합쳐짐
collect_comments bool — true 글 상세의 댓글까지 수집(각 글 extra.comments[])
mode enum — human human=목록 클릭·스크롤·휴식으로 사람처럼(권장) · normal=글 사이 1~4초 · fast=테스트용(차단 위험 큼)
refresh enum — incremental incremental=수집 PC 의 로컬 캐시(또는 known_posts)와 검색 목록의 댓글수·제목을 비교해 새 글·변동 글만 상세를 읽고 나머지는 캐시 본문에 최신 조회수·댓글수만 얹음(결과는 기간 전체) · full=모든 글의 상세를 다시 읽음(본문 수정까지 확실히 반영해야 할 때만)
refresh_days number — 7 증분일 때 캐시가 이 일수를 넘은 글은 본문 수정 안전망으로 한 번 다시 읽음. 0=안 함. 비우면 수집 PC 설정값
known_posts text — — 요청자 DB 를 기준으로 증분하려면 배열 [{"post_id":"카페ID/글번호","comment_count":N,"title":"선택"}] (최대 5,000). 보내면 수집 PC 캐시보다 우선하며, 변동 없는 글은 items 에서 빠지고 unchanged 로 최신 조회수·댓글수만 돌아옴. 조회수는 판정에 안 씀
수집 기간(start_date ~ end_date)
검색은 최신순이라 위에서부터 훑어 내려갑니다.
  • 둘 다 비우면 → 가장 최신 글부터 limit 개수까지 수집합니다.
  • start_date만 → 그 날짜 이후 글만 (그보다 오래된 글을 만나면 수집 종료).
  • end_date만 → 그 날짜까지(당일 포함). 그보다 최신 글은 건너뜁니다.
  • 둘 다 → 두 날짜 사이 구간만 수집.
제외 키워드(exclude_keywords)
이 단어가 들어간 글은 수집 단계에서 걸러집니다. 쉼표(,)로 여러 개를 넣고, 한 단어 안에 띄어쓰기도 쓸 수 있습니다(예: "무료 나눔, 광고" → 무료 나눔·광고 두 개). 대소문자는 구분하지 않고 부분 일치로 판정합니다.
  • 기본은 제목 기준 — 상세 요청을 보내기 전에 걸러서 빠르고, 수집 상한(limit)도 차감하지 않습니다.
  • 비우면 → 제외 없이 전부 수집.
댓글 수집(collect_comments: true)
기본은 제목·본문만 HTTP로 빠르게 수집합니다. 댓글까지 받으려면 이 값을 켜세요. 댓글은 JS로 로드되어 글마다 Chrome으로 접속하므로 시간이 더 걸립니다(댓글 0개 글은 건너뜀). 수집된 댓글은 각 글의 extra.comments[] 배열에 담깁니다.

요청 예시

curl -X POST https://scraper.conbus.co.kr/api/v1/collect \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "naver_cafe_win", "params": { "server": "win-office-01", "account": "기본", "cafe_id": "10258021", "keywords": [ "로얄캐닌", "사료 추천" ], "exclude_keywords": "광고, 협찬", "start_date": "2026-06-01", "end_date": "2026-06-15", "max_pages": 10, "limit": 200, "collect_comments": true, "mode": "human", "refresh": "incremental", "refresh_days": 7 } }'

응답 (202 Accepted)

요청은 즉시 큐에 적재되고 request_id 를 돌려줍니다. 실제 수집은 워커가 비동기로 처리합니다.

{ "success": true, "data": { "request_id": 42, "channel": "naver_cafe_win", "status": "pending", "status_url": "https://scraper.conbus.co.kr/api/v1/requests/42" } }

결과 조회 — GET /requests/{id}

같은 API 키로 request_id 를 조회합니다. 상태에 따라 응답이 달라집니다. 결과(items)는 요청별로 보관되므로 같은 글이 다른 요청(다른 키워드·재수집)에 겹쳐도 이 요청의 결과는 그대로입니다 — 여러 요청에 걸친 중복 정리는 post_id로 호출 쪽에서 하세요. 보존 기간은 완료 후 90일입니다. 보존 기간이 지나면 items 는 빈 배열이고 items_expired: true, items_keep_days 가 함께 옵니다(status 는 그대로 done).

진행 중 (pending / running)

아직 끝나지 않았으면 progress 로 진행 상황만 옵니다(items 없음).

{ "success": true, "data": { "request_id": 42, "channel": "naver_cafe_win", "status": "running", "external_ref": null, "result_count": null, "started_at": "2026-06-16T09:00:05+09:00", "finished_at": null, "duration_ms": null, "duration_sec": null, "created_at": "2026-06-16T09:00:00+09:00", "updated_at": "2026-06-16T09:01:30+09:00", "progress": { "count": 12, "phase": "comments" }, "elapsed_ms": 85000 } }

완료 (done) — 댓글 포함

status 가 done 이면 data.items[] 에 결과가 담깁니다. 실패 시엔 status: "failed" 와 error 가 옵니다.

{ "success": true, "data": { "request_id": 42, "channel": "naver_cafe_win", "status": "done", "external_ref": null, "result_count": 1, "started_at": "2026-06-16T09:00:05+09:00", "finished_at": "2026-06-16T09:02:00+09:00", "duration_ms": 115000, "duration_sec": 115, "created_at": "2026-06-16T09:00:00+09:00", "updated_at": "2026-06-16T09:02:00+09:00", "items": [ { "post_id": "10258021/123456", "url": "https://cafe.naver.com/f-e/cafes/10258021/articles/123456", "title": "로얄캐닌 사료 한 달 후기", "author": "냥집사", "posted_at": "2026-06-10T14:22:00+09:00", "views": 1532, "comment_count": 8, "recommends": null, "body": "한 달 먹여봤는데 기호성이 좋네요 ...", "source": "네이버 카페 / 강아지를 사랑하는 모임", "extra": { "cafe_id": "10258021", "article_no": "123456", "keyword": "로얄캐닌", "keywords": [ "로얄캐닌" ], "refreshed": true, "refresh_reason": "comment_changed", "source_kind": "cafe_search_win_app", "comments": [ { "comment_id": "12345", "author": "멍멍이", "text": "정보 감사합니다!", "date": "2026-06-10 15:01:00", "is_reply": false }, { "comment_id": "12346", "author": "냥집사", "text": "도움 되셨다니 다행이에요", "date": "2026-06-10 15:10:00", "is_reply": true } ] } } ] } }

실패 (failed)

status 가 failed 면 error 에 사유가 옵니다(items 없음). 일시적 실패는 자동 재시도되며, 위 응답은 마지막 시도 기준입니다.

{ "success": true, "data": { "request_id": 42, "channel": "naver_cafe_win", "status": "failed", "external_ref": null, "result_count": 0, "started_at": "2026-06-16T09:00:05+09:00", "finished_at": "2026-06-16T09:00:16+09:00", "duration_ms": 11000, "duration_sec": 11, "created_at": "2026-06-16T09:00:00+09:00", "updated_at": "2026-06-16T09:00:16+09:00", "error": "로그인 필요 — 계정 '기본' 이 네이버에 로그인되어 있지 않습니다 (수집 서버에서 로그인 후 다시 요청)" } }

최상위 data에는 항상 request_id·channel·status·external_ref·result_count·started_at·finished_at·duration_ms·duration_sec·created_at·updated_at이 포함되고, 상태에 따라 items(done)·progress+elapsed_ms(진행 중)·error(failed/cancelled)가 추가됩니다. duration_*는 허브가 잰 수집 소요 시간(시작~종료) — 자세히는 비동기 & 콜백. 요청을 잘못 시작했다면 취소 API로 중단할 수 있습니다.

결과 필드 (items[])

필드설명
post_id글 고유 ID — 숫자 cafe_id/글번호. 여러 키워드에 함께 걸린 글은 1건으로 합쳐지고 extra.keywords[] 에 걸린 키워드가 모두 남습니다
url원문 주소
title / body제목 / 본문 — 항상 글 상세 페이지를 열어 전체 본문을 가져옵니다
author작성자 닉네임
posted_at작성 시각 (ISO8601, KST)
views / comment_count조회수 / 댓글 수
recommends미제공 — 항상 null
source네이버 카페 / 카페 이름(인벤토리에 이름이 없으면 네이버 카페)
extra.cafe_id숫자 카페 ID
extra.article_no글번호
extra.keyword이 글을 처음 찾은 키워드
extra.keywords이 글에 걸린 모든 키워드(배열)
extra.refreshed증분 수집에서 이번 실행에 상세를 다시 읽었는지(true) / 캐시 본문 재사용(false)
extra.refresh_reason다시 읽은 이유: new·comment_changed·title_changed·stale·need_comments·full
extra.source_kindcafe_search_win_app
extra.comments댓글 배열(아래 표) — collect_comments=true일 때
채널 참고
  • 고정 배정 채널입니다 — server(수집 서버 이름) · account(그 서버의 계정 이름) · cafe_id(그 계정이 가입한 카페) 조합은 GET /cafe-servers 목록 안에 있어야 합니다. 서버가 오프라인이거나(server_offline) 계정이 로그아웃 상태면(account_login_required) 409, 연결되지 않은 카페는 422 cafe_not_linked 로 거절됩니다.
  • keywords 는 배열(["a","b"]) 또는 쉼표/줄바꿈 구분 문자열, 한 요청에 최대 20개. 키워드마다 카페 내 검색을 돌리고 결과를 글 단위로 합칩니다(limit·max_pages 는 키워드당).
  • exclude_keywords(선택) 도 배열 또는 쉼표/줄바꿈 구분 문자열(최대 50개, 대소문자 무시·부분일치). 제목은 검색 목록 단계에서 상세를 열지 않고 거르고, 본문은 상세를 읽은 뒤 한 번 더 거릅니다. 제외분은 상한에 세지 않으며 건너뛴 수는 관리자 화면의 summary.excluded 로 남습니다.
  • 증분 수집이 기본입니다. 수집 PC 가 한 번 읽은 글을 로컬 캐시에 두고, 다음 요청에서는 검색 목록의 댓글수·제목이 바뀐 글, 새 글, 캐시가 refresh_days(기본 7일) 지난 글만 상세를 다시 읽습니다. 나머지는 캐시 본문에 목록의 최신 조회수·댓글수를 얹어 돌려주므로 결과는 기간 전체이고, 항목마다 extra.refreshed(이번에 다시 읽었는지)와 extra.refresh_reason(new/comment_changed/title_changed/stale/full)이 붙습니다. 변동분만 쓰려면 이 플래그로 거르거나 GET /requests/{id}?changed_only=1 을 쓰세요. 본문 수정까지 확실히 반영해야 하면 refresh=full.
  • 요청자 DB 를 기준으로 증분하려면 known_posts 에 이미 가진 글을 [{"post_id":"카페ID/글번호","comment_count":N,"title":"선택"}] 로 보내세요(최대 5,000). 이때는 새 글·변동 글만 items 로 오고, 변동 없는 글은 unchanged 배열(post_id·views·comment_count)로 최신 카운트만 옵니다. 조회수는 판정에 쓰지 않으므로 보내지 않아도 됩니다.
  • 검색 결과가 0건이면 items 가 빈 배열인 done 으로 끝납니다. 수집 PC 가 결과 목록도 "결과 없음" 안내도 확인하지 못한 채 페이지만 정상 로드된 키워드는 0건으로 처리하되 warnings.search_uncertain(키워드 배열)에 남기니, 이 값이 있으면 네이버 화면 변경 가능성을 의심하세요. 검색 페이지에 오류 안내가 보이거나 검색 페이지를 벗어난 경우는 성격에 따라 갈립니다: 카페·게시판 없음·폐쇄는 재시도해도 같으므로 즉시 종결(failed, 재시도 없음), 일시 오류·점검과 주소 이탈은 재시도 가능한 실패(점검이면 10분 이상 간격), 차단·캡차·보호조치는 즉시 중단 후 종결되고 그 계정은 login_state:"blocked" 로 바뀌어 사람이 수집 PC 에서 확인·해제할 때까지 그 계정으로의 요청은 409 account_blocked 로 거절됩니다.
  • 효율을 위한 요청 습관: 기간은 짧고 일정하게(예: 매일 "최근 7일"), 키워드는 한 요청에 배열로 묶고, 키워드 세트는 자주 바꾸지 마세요. 새 PC·새 카페·새 키워드는 첫 회에 전체를 읽고 그 뒤부터 빨라집니다.
  • 수집 서버(윈도우 PC)의 실제 Chrome 이 사람처럼 움직이므로(mode=human 기본) 글당 수 초가 걸립니다. 무인 운영 중 로그인이 끊기면 기다리지 않고 즉시 failed 로 끝납니다(재시도 없음 — 수집 서버에서 로그인한 뒤 다시 요청).

댓글 필드 (extra.comments[])

필드설명
comment_id댓글 고유 ID
author작성자
text내용 — 글자 없이 이미지·스티커(디시콘 등)만 있는 댓글은 [이미지] 같은 대체 텍스트 또는 빈 문자열
date작성 시각
is_reply대댓글 여부(true=답글)

결과 수신(폴링·콜백) 방식은 비동기 & 콜백을 참고하세요.