KYC 없음 — 신분증도, 셀피도, 서류도 없습니다. 암호화폐로 결제하세요: BTC, USDT, USDC, ETH, SOL, LTC
언어: 한국어
API 키 발급받기

문서 · 오류

오류, robots.txt 거부 및 재시도

각 오류에는 HTTP 상태, 안정적인 code, 읽을 수 있는 message가 있습니다. 어느 것도 크레딧을 사용하지 않습니다. 일부는 재시도할 가치가 있습니다. 사이트에서 비롯된 거부는 최종적이며, 우리는 이를 우회하지 않습니다.

마지막 업데이트: · 4 분 읽기

빠른 답변

WebReaderAPI 오류 코드는 무엇을 의미하며, 어느 것을 재시도해야 하나요?

WebReaderAPI 오류는 세 그룹으로 나뉘며, 어느 것도 청구되지 않습니다. 요청 문제(invalid_url, invalid_api_key, insufficient_credits)는 회원님 쪽에서 수정해야 합니다. 사이트 결정(blocked_by_robots, blocked_by_site_policy, target_refused)은 최종적입니다. 일시적 실패(fetch_failed, fetch_timeout, concurrency_limit)는 백오프를 두고 재시도할 수 있습니다. 크레딧은 US$0.07/1K 페이지부터 시작하며, KYC 없이 암호화폐로 결제합니다.

API가 반환할 수 있는 오류 코드는 무엇인가요?

본문은 항상 {"error": {"code", "message"}}이며, 거부가 사이트에서 비롯된 경우에는 target_status가 추가됩니다.

HTTPcode원인재시도할까요?
400invalid_urlhttp 또는 https가 아니거나, 너무 길거나, 사설·로컬·클라우드 메타데이터 주소입니다아니요: URL을 수정하세요
400invalid_parameter파라미터 값이 허용 목록이나 범위를 벗어났습니다아니요: 요청을 수정하세요
401invalid_api_key키가 없거나, 잘못되었거나, 폐기되었습니다아니요: 키를 확인하세요
402insufficient_credits잔액에 남은 크레딧이 없습니다팩 구매 후
403blocked_by_robots사이트의 robots.txt가 WebReaderAPI 또는 모든 로봇에 대해 해당 페이지를 허용하지 않습니다아니요: 최종입니다
403blocked_by_site_policy사이트가 Content-Signal: ai-input=no을(를) 선언합니다아니요: 최종입니다
422unsupported_content읽지 않는 유형(동영상, 압축 파일)이거나 파일이 너무 큽니다아니요
429concurrency_limit동시에 실행 중인 요청이 너무 많습니다예, 백오프와 함께
502target_refused사이트가 거부했습니다: 403, 429, 챌린지 페이지 또는 로그인 벽이며, 상태는 target_status에 있습니다아니요: 최종입니다
502fetch_failedDNS, TLS 또는 연결 오류이거나 사이트가 404 또는 410으로 응답했습니다한두 번, 백오프와 함께
504fetch_timeout사이트가 timeout 안에 응답하지 않았습니다예, 백오프 또는 더 긴 타임아웃과 함께

robots.txt와 사이트 거부는 왜 최종인가요?

사이트 소유자의 결정이기 때문이며, WebReaderAPI은(는) 이를 따르도록 만들어졌습니다. 우리는 robots.txt를 준수합니다. 크롤러는 WebReaderAPI로 자신을 식별하고, 자신 또는 모든 로봇을 위해 작성된 규칙을 따르며, 사이트가 허용하지 않은 페이지는 읽지 않습니다. 거부된 페이지는 과금되지 않습니다. 사이트가 robots.txt에 Content-Signal: ai-input=no를 선언하면, 해당 페이지를 대신 읽지 않습니다.

사이트가 403, 429, 챌린지 페이지 또는 로그인 폼 등 다른 방식으로 요청을 거절하면 target_refused와 사이트 자체의 상태를 target_status에서 받습니다. 사이트가 우리 요청을 거부하면 그 응답을 그대로 반환합니다. 우리는 CAPTCHA를 풀거나, 계정에 로그인하거나, 차단이나 페이월을 우회하려 시도하지 않습니다. 같은 URL을 1분 후에 다시 시도해도 보통 같은 답이 돌아오므로, 이 코드들은 실패가 아닌 결과로 보고 기록한 뒤 넘어가세요.

페이지가 거부된 이유는 어떻게 확인하나요?

사이트의 /robots.txt를 열고 WebReaderAPI을(를) 명시한 그룹 또는 모든 로봇에 적용되는 * 그룹을 찾으세요. 경로와 일치하는 Disallow 줄은 blocked_by_robots을(를) 설명합니다. Content-Signal: ai-input=no과 같은 줄은 blocked_by_site_policy을(를) 설명합니다.

저희는 각 robots.txt의 사본을 최대 24시간 동안 보관합니다. 사이트가 방금 어떤 섹션을 로봇에게 개방했다면 변경이 적용되기까지 최대 하루가 걸릴 수 있습니다. 사이트 소유자는 크롤러 페이지]에서 저희 크롤러의 동작 방식과 허용 또는 차단 방법을 확인할 수 있습니다.

일시적 실패는 어떻게 재시도해야 하나요?

concurrency_limit, fetch_timeout, 그리고 한두 번은 fetch_failed만 재시도하세요. 새 시도 전에 기다리고 대기 시간을 매번 두 배로 늘리되, 병렬 워커들이 동시에 재시도하지 않도록 약간의 무작위 지터를 더하세요. 4~5회 시도 후 중단하세요.

concurrency_limit에는 동시에 보내는 요청 수를 줄이는 것이 더 나은 해결책입니다: 모든 계정에는 동시에 읽는 페이지 수에 대한 한도가 있으며, 대시보드에 표시됩니다. 지원팀이 이를 높일 수 있습니다. fetch_timeout에는 느린 사이트를 재시도하기 전에 timeout을(를) 최대 60초까지 늘리세요. 실패한 시도는 과금되지 않으므로 재시도에는 비용이 들지 않습니다.

Python: 결과가 바뀔 수 있는 오류만 재시도
import os
import random
import time

import requests

API = "https://webreaderapi.com/api/v1/read"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}
RETRY = {"concurrency_limit", "fetch_timeout", "fetch_failed"}
FINAL = {"blocked_by_robots", "blocked_by_site_policy", "target_refused", "unsupported_content"}


def read_page(url, attempts=5, **options):
    wait = 1.0
    for attempt in range(1, attempts + 1):
        resp = requests.get(API, headers=HEADERS, params={"url": url, **options}, timeout=75)
        if resp.status_code == 200:
            return resp.json()
        error = resp.json().get("error", {})
        code = error.get("code", "unknown")
        if code in FINAL:
            return {"url": url, "skipped": code, "target_status": error.get("target_status")}
        if code not in RETRY or attempt == attempts or (code == "fetch_failed" and attempt >= 3):
            raise RuntimeError(f"{code}: {error.get('message')}")
        time.sleep(wait + random.uniform(0, wait / 2))
        wait = min(wait * 2, 30)
    raise RuntimeError("unreachable")


if __name__ == "__main__":
    print(read_page("https://example.com/blog/first-post", max_chars=20000).get("title"))
Node.js: 지수 백오프를 적용한 동일한 규칙
const RETRY = new Set(['concurrency_limit', 'fetch_timeout', 'fetch_failed']);
const FINAL = new Set(['blocked_by_robots', 'blocked_by_site_policy', 'target_refused', 'unsupported_content']);
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

export async function readPage(url, options = {}, attempts = 5) {
  let wait = 1000;
  for (let attempt = 1; attempt <= attempts; attempt++) {
    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}` },
    });
    const body = await res.json();
    if (res.ok) return body;
    const code = body.error?.code ?? 'unknown';
    if (FINAL.has(code)) return { url, skipped: code, target_status: body.error.target_status };
    if (!RETRY.has(code) || attempt === attempts) throw new Error(`${code}: ${body.error?.message}`);
    await sleep(wait + Math.random() * (wait / 2));
    wait = Math.min(wait * 2, 30000);
  }
}

배치나 크롤링 내부의 오류는 어떻게 하나요?

한 페이지가 실패해도 작업은 멈추지 않습니다. 해당 페이지는 results에 위와 같은 코드인 {url, error}로 표시되며, 크레딧이 차감되지 않습니다. 크롤링 중 특정 섹션에서 blocked_by_robots가 발생하면 사이트의 나머지 부분은 그대로 읽습니다.

작업이 끝나면 에러 코드를 집계하세요. 한 사이트에서 target_refused가 많다면 그 사이트가 자동 리더를 허용하지 않는다는 뜻이고, fetch_timeout가 많다면 응답이 느리다는 뜻이므로 작업 옵션에서 timeout를 늘리면 도움이 될 수 있습니다.

에러: 자주 묻는 질문

robots.txt가 차단한 페이지에도 비용이 청구되나요?

아니요. 1 크레딧 = 브라우저 없이 페이지 1회 읽기, 페이지가 JavaScript를 렌더링하는 데 브라우저가 필요하면 2 크레딧. 실패한 요청이나 사이트의 robots.txt가 거부한 요청은 과금되지 않습니다. 이 페이지의 다른 모든 에러도 마찬가지입니다.

요청하면 크롤러를 차단하는 페이지도 읽을 수 있나요?

아니요. 저희는 사이트 소유자의 선택을 따르며, 이 정책은 모든 고객에게 동일하게 적용됩니다. 사이트를 소유하고 계시다면 robots.txt에 WebReaderAPI에 대한 규칙을 추가하세요. 크롤러 페이지에서 방법을 확인할 수 있습니다.

존재하는 페이지에서 fetch_failed가 뜨는 이유는 무엇인가요?

사이트가 다운되었거나, TLS 연결을 느리게 수락하거나, 자동화 클라이언트에 404를 반환했을 수 있습니다. 백오프를 적용해 한두 번 재시도하세요. 계속 실패하면 브라우저에서 주소를 확인하세요.

거부된 후 에이전트가 사용자에게 무엇을 알려야 하나요?

'해당 사이트는 그 페이지의 자동 읽기를 허용하지 않습니다'처럼 간단하게 알려주세요. 그런 다음 모델이 다른 출처를 사용하도록 하세요. 에러 코드를 도구 결과로 반환하는 것만으로도 대부분의 모델에 충분합니다.

US$0.07/1K 페이지부터 · KYC 없이

API 키 발급받기