스크래핑 시작하기
스크래핑은 웹페이지에 보이는 정보를 프로그램으로 모아 표로 만드는 일입니다. 퓨쳐인프라에서는 수집 프로그램을 액터라고 부릅니다. 네이버·유튜브·SNS·커뮤니티·쇼핑몰용 액터 99개가 준비돼 있어, 입력만 채우면 결과를 CSV·엑셀로 받을 수 있습니다.
쓰는 법 세 가지
같은 액터를 어디서 실행하든 결과·요금·실행 기록은 한곳에 모입니다.
| 어디서 | 이렇게 | 이런 분께 |
|---|---|---|
| 콘솔 | 왼쪽 메뉴 데이터 › 스크래핑 → 액터 탭의 액터 스토어에서 카드를 골라 실행. 결과는 실행 기록 탭에서 표로 보고 CSV·엑셀로 내려받습니다 | 코딩 없이 바로 써 보고 싶을 때 |
| API 키 | 콘솔 API 키 › 새 키 발급으로 키를 받아 아래 명령을 복사해 실행합니다 | 내 프로그램·서버에서 정기적으로 모을 때 |
| AI 도구 (MCP) | MCP 연동으로 Claude·Cursor 같은 AI 에 연결한 뒤 말로 시킵니다 | AI 에게 수집부터 정리까지 맡길 때 |
scrape:read(결과 보기)·scrape:write(실행)를 넣어 주세요. 아무것도 고르지 않으면 둘 다 들어갑니다.
복사해서 바로 쓰기
네이버 블로그 검색 액터로 실행 → 끝날 때까지 기다리기 → CSV 내려받기까지 한 번에 합니다. 키만 바꿔 붙여 넣으세요.
export FI_KEY=pk_live_... # 콘솔 › API 키 › 새 키 발급
API=https://futureinfra.ai/v1/scrape
# 1) 실행 — 결과를 기다리지 않고 실행 id 가 바로 옵니다
RUN=$(curl -s -X POST $API/runs -H "Authorization: Bearer $FI_KEY" -H "Content-Type: application/json" \
-d '{"actor":"store:naver-blog-search","input":{"queries":["캠핑의자"],"maxResults":20,"sort":"sim","period":"all","includeContent":false}}' \
| sed -E 's/^\{"id":"([^"]+)".*/\1/')
# 2) 끝날 때까지 5초마다 확인
until curl -s $API/runs/$RUN -H "Authorization: Bearer $FI_KEY" | grep -qE '"status":"(succeeded|failed|aborted)"'; do sleep 5; done
# 3) 결과를 CSV 로 내려받기 — 엑셀에서 바로 열립니다
curl -s "$API/runs/$RUN/items?format=csv" -H "Authorization: Bearer $FI_KEY" -o result.csv
실행 요청에는 바로 이런 답이 옵니다. 실제 수집은 뒤에서 이어집니다.
{ "id": "6705c1…", "actor": "store:naver-blog-search", "status": "queued", "items": 0, "costKRW": 0, … }
actor 에는 준비된 액터 목록의 실행 이름(store:이름)을, input 에는 그 액터의 입력 예시를 넣습니다.
입력 칸이 무엇인지는 GET /v1/scrape/store/이름 으로도 볼 수 있습니다.
프로그램에서 — Node.js · Python
하는 일은 위와 같습니다. 키는 환경변수 FI_KEY 에 넣어 두세요.
// Node.js 18 이상, 설치할 것 없음 — 파일 이름을 run.mjs 처럼 .mjs 로 저장하세요
const API = "https://futureinfra.ai/v1/scrape";
const H = { Authorization: "Bearer " + process.env.FI_KEY, "Content-Type": "application/json" };
const run = await (await fetch(API + "/runs", { method: "POST", headers: H, body: JSON.stringify({"actor":"store:naver-blog-search","input":{"queries":["캠핑의자"],"maxResults":20,"sort":"sim","period":"all","includeContent":false}}) })).json();
let s;
do {
await new Promise((r) => setTimeout(r, 5000));
s = await (await fetch(API + "/runs/" + run.id, { headers: H })).json();
} while (s.status === "queued" || s.status === "running");
const items = await (await fetch(API + "/runs/" + run.id + "/items?limit=1000", { headers: H })).json();
console.log(s.status, s.costKRW + "원", items.total + "건");
console.log(items.data[0]);
# Python — pip install requests
import json, os, time, requests
API = "https://futureinfra.ai/v1/scrape"
H = {"Authorization": "Bearer " + os.environ["FI_KEY"]}
BODY = json.loads('{"actor":"store:naver-blog-search","input":{"queries":["캠핑의자"],"maxResults":20,"sort":"sim","period":"all","includeContent":false}}')
run = requests.post(API + "/runs", headers=H, json=BODY).json()
while True:
s = requests.get(API + "/runs/" + run["id"], headers=H).json()
if s["status"] not in ("queued", "running"):
break
time.sleep(5)
with open("result.csv", "wb") as f:
f.write(requests.get(API + "/runs/" + run["id"] + "/items", headers=H, params={"format": "csv"}).content)
print(s["status"], s["costKRW"], "원")
AI 도구에서 — MCP
연결만 해 두면 AI 가 액터를 고르고, 입력을 채우고, 결과를 정리합니다.
이렇게 말하면 됩니다.
- "네이버 블로그에서 캠핑의자 글 20개 모아서 CSV로 줘"
- "이 유튜브 영상 댓글 모아서 많이 나온 말 정리해 줘"
- "매일 아침 9시에 이 검색어로 새 글 모으게 해 줘"
AI 가 쓰는 도구: scrape.actors · scrape.run · scrape.store · scrape.store_actor · scrape.fork_store_actor · scrape.run_batch · scrape.my_actors · scrape.get_actor · scrape.create_actor · scrape.update_actor · scrape.tasks · scrape.create_task · scrape.update_task · scrape.run_task · scrape.webhooks · scrape.create_webhook · scrape.runs · scrape.run_status · scrape.items · scrape.abort
여러 개 한꺼번에
한 번 요청에 최대 50개. 하나가 잘못돼도 나머지는 그대로 만들어집니다.
curl -s -X POST https://futureinfra.ai/v1/scrape/runs/batch -H "Authorization: Bearer $FI_KEY" -H "Content-Type: application/json" \
-d '{"runs":[{"actor":"store:naver-blog-search","input":{"queries":["캠핑의자"],"maxResults":20,"sort":"sim","period":"all","includeContent":false}},{"actor":"store:youtube-search","input":{"queries":["캠핑 의자"],"searchType":"video","sortBy":"views","maxResults":20}}]}'
{ "created": 2, "failed": 0,
"results": [ { "index": 0, "ok": true, "id": "…", "status": "queued" },
{ "index": 1, "ok": true, "id": "…", "status": "queued" } ] }
대기열(차례를 기다리는 줄)에 들어가 한 조직에서 동시에 3개씩 돌고, 하나가 끝나면 다음 것이 바로 시작합니다. 대기 중인 것과 도는 것을 합쳐 조직당 100개까지 올려 둘 수 있습니다.
실행 상태와 결과
| 상태(status) | 뜻 |
|---|---|
queued | 차례를 기다리는 중 |
running | 모으는 중 — items 가 늘어납니다 |
succeeded | 다 모았습니다 |
failed | 중간에 멈췄습니다. 그때까지 모은 결과는 남아 있고, 모은 만큼만 청구됩니다 |
aborted | 직접 멈췄습니다(POST /v1/scrape/runs/<id>/abort) |
결과는 GET /v1/scrape/runs/<id>/items 에서 받습니다. format 으로 모양을 고릅니다.
| format | 모양 |
|---|---|
json (기본) | { total, offset, count, data:[…] } — offset·limit 으로 나눠 읽습니다 |
csv | 표 파일. 엑셀에서 열어도 한글이 깨지지 않게 저장합니다 |
xlsx | 엑셀 파일 |
jsonl | 한 줄에 결과 하나 |
- 실행 기록 —
GET /v1/scrape/runs/<id>/log - 액터가 남긴 파일(스크린샷 등) —
GET /v1/scrape/runs/<id>/records, 하나는…/records/<이름> - 최근 실행 목록 —
GET /v1/scrape/runs - 결과는 30일 동안 보관합니다. 오래 둘 것은 내려받아 두세요
매일 자동으로 — 태스크와 스케줄
태스크는 액터와 입력을 이름 붙여 저장해 둔 것입니다. 스케줄(cron)을 붙이면 정해진 시각마다 저절로 돕니다.
POST /v1/scrape/tasks
{
"name": "매일 아침 블로그 모으기",
"actor": "store:naver-blog-search",
"input": {
"queries": [
"캠핑의자"
],
"maxResults": 20,
"sort": "sim",
"period": "all",
"includeContent": false
},
"maxCostKrw": 500,
"cron": "0 9 * * *",
"cronEnabled": true
}
cron은 "분 시 일 월 요일" 순서이고 한국 시간입니다. 매일 09:00 =0 9 * * *, 평일 18:30 =30 18 * * 1-5- 가장 짧은 간격은 5분, 태스크는 조직당 50개까지 만들 수 있습니다
- 지금 한 번 돌리기 —
POST /v1/scrape/tasks/<id>/run. 고치기는PUT, 스케줄 끄기는{"cronEnabled": false} maxCostKrw를 주면 한 번 실행에 그 금액 안에서만 모읍니다- 잔액이 모자라 3번 연속 시작하지 못하면 스케줄이 저절로 꺼집니다. 충전한 뒤 다시 켜면 됩니다
콘솔에서는 스크래핑 › 태스크·스케줄 탭에서 만들고 켜고 끕니다.
끝나면 알림 — 웹훅
웹훅은 실행이 끝났을 때 내 서버 주소로 결과를 알려 주는 기능입니다. 슬랙·n8n·Zapier 같은 자동화 도구의 웹훅 주소도 됩니다.
POST /v1/scrape/webhooks
{ "url": "https://my-server.example.com/hooks/scrape", "events": ["run.succeeded","run.failed","run.aborted"] }
실행이 끝나면 이런 JSON 이 POST 로 갑니다. links.csv 를 그대로 내려받으면 됩니다.
{
"event": "run.succeeded",
"createdAt": "…",
"run": { "id": "…", "actor": "store:naver-blog-search", "status": "succeeded", "items": 20, "costKRW": 30, … },
"links": { "run": "…/v1/scrape/runs/<id>", "items": "…/items?format=json", "csv": "…/items?format=csv" }
}
- 받는 쪽 확인용 머리글:
X-FI-Event·X-FI-Delivery·X-FI-Signature X-FI-Signature=sha256=+ HMAC-SHA256(비밀값, 받은 본문 그대로). 비밀값은 웹훅을 만들 때 한 번만 보여 드립니다- 특정 태스크·액터의 실행만 받으려면
task·actor를 같이 넣습니다. 웹훅은 조직당 10개까지 - 시험 전송 —
POST /v1/scrape/webhooks/<id>/test. 받는 쪽이 응답하지 않으면 조금 뒤 다시 보냅니다
// 받는 쪽(Node.js)에서 서명 확인
import { createHmac, timingSafeEqual } from "node:crypto";
const want = "sha256=" + createHmac("sha256", process.env.FI_WEBHOOK_SECRET).update(rawBody).digest("hex");
const ok = want.length === sig.length && timingSafeEqual(Buffer.from(want), Buffer.from(sig)); // sig = X-FI-Signature
요금
충전해 둔 크레딧에서 실행이 끝날 때 빠집니다. 월 구독료는 없습니다. (부가세 포함)
| 무엇 | 어떻게 셈하나 |
|---|---|
| 준비된 액터 | 모은 결과 1,000건당 액터마다 정해진 값 — 지금 1,500원~5,000원. 계산 시간·프록시 데이터가 이 값에 들어 있습니다 |
| 기본 수집기 | 읽은 페이지 1개당 1원(브라우저로 읽으면 3원) |
| 내 액터 | 메모리 1GB로 1시간 돌면 400원 — 쓴 초 단위로 나눠 셉니다 |
- 준비된 액터는 결과가 0건이면 0원입니다. 결과가 있으면 한 번 실행에 최소 10원입니다
- 예) 네이버 블로그 검색(1,000건당 1,500원)으로 200건을 모으면 300원
- 시작할 때 잔액으로 모을 수 있는 건수까지만 모읍니다. 금액 상한을 정하려면
maxCostKrw를 넣으세요 - 실행마다 쓴 금액은 실행 결과의
costKRW와 콘솔 크레딧 내역에 남습니다
운영 규칙
- 한 조직에서 동시에 도는 실행은 3개, 대기열까지 합쳐 100개입니다. 다른 고객 실행 때문에 내 실행이 밀리지 않도록 조직마다 차례를 나눕니다
- 대기열에 넣은 지 24시간이 지나도록 시작하지 못한 실행은 요금 없이 정리합니다
- 도는 중에 멈추면 그때까지 모은 결과만큼만 청구합니다. 시작 전에 멈추면 0원입니다
- 공개된 정보만 모읍니다. 글쓴이·댓글 작성자 같은 개인 정보는 결과에 넣지 않습니다
- 사이트에 무리가 가지 않도록 요청 사이에 간격을 둡니다
자주 보는 오류
| 코드 | 뜻 |
|---|---|
insufficient_credits (402) | 잔액이 모자랍니다. 충전하거나 maxCostKrw 를 낮추세요 |
too_many_active_runs (429) | 대기열이 꽉 찼습니다(조직당 100개). 몇 개가 끝난 뒤 다시 넣으세요 |
input_required · input_invalid (400) | 입력 칸이 빠졌거나 모양이 다릅니다. field 에 칸 이름이 옵니다 |
actor_not_found (404) | 실행 이름이 틀렸습니다. store: 를 붙였는지 보세요 |
too_many_runs (400) | 한 번에 50개를 넘게 넣었습니다 |
자주 묻는 질문
-
스크래핑 요금은 어떻게 계산하나요?
준비된 액터는 모은 결과 1,000건당 액터마다 정해진 값(1,500원~5,000원)을 냅니다. 계산 시간과 프록시 데이터는 이 값에 들어 있습니다. 결과가 0건이면 0원이고, 결과가 있으면 한 번 실행에 최소 10원입니다.
-
코딩을 몰라도 쓸 수 있나요?
네. 콘솔의 스크래핑 화면에서 액터를 고르고 입력 칸을 채운 뒤 실행을 누르면 결과가 표로 나오고, CSV·엑셀로 내려받을 수 있습니다. AI 도구(MCP)를 연결했다면 "네이버 블로그에서 캠핑의자 글 20개 모아서 CSV로 줘"처럼 말로 시켜도 됩니다.
-
결과는 얼마나 보관되나요?
모은 날부터 30일 동안 보관합니다. 더 오래 두려면 CSV·엑셀·JSON 으로 내려받아 두세요.
-
여러 개를 한꺼번에 돌릴 수 있나요?
한 번 요청에 50개까지 넣을 수 있습니다. 대기열에 들어가 한 조직에서 동시에 3개씩 돌고, 끝난 자리에 다음 실행이 들어갑니다.
-
어떤 정보를 모으나요?
누구나 볼 수 있는 공개된 정보만 모읍니다. 글쓴이·댓글 작성자 같은 개인 정보는 결과에 넣지 않고, 사이트에 무리가 가지 않게 요청 사이에 간격을 둡니다.