빠른 답변
Node.js에서 웹페이지를 Markdown으로 변환하려면 어떻게 하나요?
Node.js 18+의 내장 fetch을 사용하세요. Authorization 헤더에 키를 넣고 https://webreaderapi.com/api/v1/read?url=…를 호출한 뒤, JSON 응답에서 markdown을 읽으면 됩니다. WebReaderAPI은 페이지의 제목, 작성자, 날짜와 함께 본문을 반환합니다. 한 페이지에 1 크레딧, 헤드리스 브라우저가 필요하면 2 크레딧이며, 2026년 10월 기준 US$0.07/1K 페이지부터입니다. KYC 없이, 암호화폐로 결제합니다.
무엇이 필요한가요?
Node.js 18 이상(전역 fetch 사용)과 WEBREADER_API_KEY 환경 변수에 설정한 API 키가 필요합니다. 예제는 ES 모듈입니다. .mjs 확장자로 저장하거나 package.json에 "type": "module"을 설정해 최상위 await이 동작하게 하세요.
JSDoc 주석이 응답 구조를 설명하므로 VS Code 같은 에디터에서 TypeScript 빌드 단계 없이 완성을 제공합니다.
/**
* @typedef {Object} Page
* @property {string} url
* @property {string} final_url
* @property {number} status_code
* @property {boolean} rendered
* @property {number} credits_used
* @property {string} [title]
* @property {string} [author]
* @property {string} [published_at]
* @property {string} [language]
* @property {string} [markdown]
* @property {number} word_count
*/
/** @returns {Promise<Page>} */
export async function readPage(url, options = {}) {
const params = new URLSearchParams({ url, ...options });
const res = await fetch(`https://webreaderapi.com/api/v1/read?${params}`, {
headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}` },
signal: AbortSignal.timeout(75_000),
});
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.error.message), { code: body.error.code });
return body;
}
const page = await readPage('https://example.com/docs/getting-started', { max_chars: '20000' });
console.log(page.title, page.word_count, 'words,', page.credits_used, 'credit(s)');
한도를 넘지 않고 URL 목록을 읽으려면 어떻게 하나요?
공유 큐에서 URL을 가져가는 고정된 수의 워커를 실행하세요. 전체 목록에 Promise.all을 걸어 모든 요청을 한꺼번에 시작해 429 concurrency_limit에 부딪히는 것보다 간단합니다. 모든 계정에는 동시에 읽는 페이지 수에 대한 한도가 있으며, 대시보드에 표시됩니다. 지원팀이 이를 높일 수 있습니다.
아래 풀은 오류를 결과 옆에 두므로, 거부된 페이지 하나가 실행을 멈추지 않습니다. blocked_by_robots 같은 거부는 최종적이며 무료입니다. 개수를 세고 넘어가세요.
import { readPage } from './read.mjs';
export async function readAll(urls, workers = 8) {
const queue = [...urls];
const results = [];
async function worker() {
while (queue.length) {
const url = queue.shift();
try {
const page = await readPage(url, { max_chars: '50000' });
results.push({ url, page });
} catch (err) {
results.push({ url, error: err.code ?? err.name });
}
}
}
await Promise.all(Array.from({ length: workers }, worker));
return results;
}
const urls = Array.from({ length: 30 }, (_, i) => `https://example.com/blog/post-${i + 1}`);
for (const r of await readAll(urls)) console.log(r.url, '->', r.error ?? r.page.title);
Node.js에서 크롤링 작업을 따라가려면 어떻게 하나요?
POST https://webreaderapi.com/api/v1/crawl으로 작업을 시작한 뒤 루프에서 https://webreaderapi.com/api/v1/jobs/{job_id}을 읽으세요. next_cursor이 반환될 때마다 cursor을 전달하고, 커서가 없고 상태가 done이면 작업이 끝난 것입니다. 빈 폴링 사이에는 기다리고 최대 30초까지 대기 시간을 두 배로 늘리세요. 사이트의 Crawl-delay를 준수하는 크롤링은 느릴 수 있습니다.
배치 및 크롤링 페이지에서 크롤링이 페이지를 어떻게 고르고 limit이 읽는 범위를 어떻게 제한하는지 설명합니다.
const headers = {
Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`,
'Content-Type': 'application/json',
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const start = await fetch('https://webreaderapi.com/api/v1/crawl', {
method: 'POST',
headers,
body: JSON.stringify({ url: 'https://docs.example.com/', limit: 300, include_paths: ['/docs/*'] }),
});
const { job_id } = await start.json();
const pages = [];
let cursor = '';
let wait = 2000;
for (;;) {
const url = `https://webreaderapi.com/api/v1/jobs/${job_id}${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ''}`;
const job = await (await fetch(url, { headers })).json();
pages.push(...job.results.filter((r) => !r.error));
if (job.next_cursor) {
cursor = job.next_cursor;
wait = 2000;
continue;
}
if (job.status === 'done') break;
await sleep(wait);
wait = Math.min(wait * 2, 30000);
}
console.log(pages.length, 'pages read, job', job_id);
결과를 모델에 어떻게 전달하나요?
전체 JSON이 아니라 Markdown을 보내세요. markdown 필드가 모델이 읽어야 할 내용이며, 메타데이터는 인용에 쓰는 편이 좋습니다. 모델이 출처를 밝힐 수 있도록 제목과 final_url를 앞에 붙이고, max_chars은 모델의 컨텍스트에 들어가는 크기(페이지당 20,000자 등)로 유지하세요.
OpenAI function calling 페이지는 Python으로 전체 툴 루프를 보여줍니다. 위의 readPage 함수도 Node.js 에이전트의 툴 본문으로 쓸 수 있습니다.
Node.js: 자주 묻는 질문
Deno, Bun 또는 브라우저에서 동작하나요?
Deno와 Bun은 같은 fetch과 ES 모듈을 지원합니다. 브라우저 페이지에서 API를 호출하지 마세요. 키가 모든 방문자에게 노출됩니다. 대신 서버에서 호출하세요.
npm 패키지가 있나요?
없습니다. 이 페이지의 함수가 통합의 전부입니다. WebReaderAPI은 순수 HTTPS와 JSON이므로 재시도, 타임아웃, 로깅을 직접 제어할 수 있습니다.
429 concurrency_limit은 어떻게 처리하나요?
워커 수를 줄이거나, 짧게 기다렸다가 매번 두 배로 늘려 재시도하세요. 429는 비용이 들지 않으며, 오류 페이지에 바로 쓸 수 있는 백오프 함수가 있습니다.
10,000 페이지를 읽으면 비용이 얼마인가요?
일반 페이지 기준 약 10,000 크레딧이며, 일부가 헤드리스 브라우저를 필요로 하면 더 듭니다. 10,000페이지 비용은 US$3.75입니다. 선불 크레딧은 만료되지 않습니다. 사용하지 않은 페이지는 사용할 때까지 계정에 남아 있습니다.