KYC不要 — 身分証もセルフィーも書類も不要。暗号資産で支払い:BTC, USDT, USDC, ETH, SOL, LTC
言語: 日本語
APIキーを取得

ドキュメント · ジョブ

バッチ・クロールAPI: 多数のURLまたはサイト全体を読み取る

バックグラウンドジョブを開始するendpointは2つあります。最大100 URLのリストには/batch、1つのウェブサイトには/crawlです。どちらもジョブIDを返します。結果は/jobs/{job_id}から1ページ分ずつ取得します。

最終更新: · 3 分で読めます

概要

WebReaderAPIでウェブサイトをMarkdownにクロールするには?

開始URLをlimit付きでPOST https://webreaderapi.com/api/v1/crawlに送信します。WebReaderAPIがバックグラウンドでサイトを読み取り、同一ドメインのみ、サイトマップ、robots.txt、Crawl-delayに従い、1ジョブあたり最大10,000ページまで処理します。Markdownページはジョブから1ページ分ずつ取得します。各ページの読み取りは1クレジット(ブラウザ使用時は2クレジット)、$0.07/1Kページより2026年10月時点。KYC不要、暗号資産で支払い。

ジョブの概要

バッチバッチジョブあたり最大100 URL: POST https://webreaderapi.com/api/v1/batch
クロール1ジョブにつき1つのWebサイトを、最大10,000ページまでクロール。サイトマップ、robots.txt、Crawl-delayに従います: POST https://webreaderapi.com/api/v1/crawl
結果GET https://webreaderapi.com/api/v1/jobs/{job_id}、その後次の結果ページには?cursor=…
課金各ページの読み取りは/read呼び出しと同様に課金されます。robots.txtによりスキップされたページと失敗したページは無料です
クロールの範囲1つのドメインのみ。他のドメインへのリンクは一覧表示されますが読み取られません
ジョブのキャンセルv1では利用できません: 支払い可能な最大ページ数をlimitに設定してください

バッチジョブの開始

POST/api/v1/batch

同じオプションでバックグラウンドで最大100 URLを読み取ります。オプションは/readの名前と値を使用します。返答はジョブIDです。値は例示です。

認証:Authorization: Bearer API_KEYヘッダーのAPIキー。

リクエストボディ

フィールド型必須説明
urlsarray of stringsはいhttpまたはhttpsのURLを1〜100個。重複は1回だけ読み取ります。
optionsobjectいいえurl以外の任意の/readパラメータ: format、main_content、render、include_links、include_images、country、max_chars、timeout。
例: three articles as Markdown
{
  "urls": [
    "https://example.com/blog/post-1",
    "https://example.com/blog/post-2",
    "https://example.org/news/launch"
  ],
  "options": {
    "format": "markdown",
    "max_chars": 50000
  }
}

レスポンス 202 Accepted

{
  "job_id": "job_5c1e8a90d2"
}

コード例

curl
curl -s "https://webreaderapi.com/api/v1/batch" \
  -H "Authorization: Bearer $WEBREADER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com/blog/post-1", "https://example.com/blog/post-2"], "options": {"format": "markdown"}}'
Python
import os
import requests

resp = requests.post(
    "https://webreaderapi.com/api/v1/batch",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    json={"urls": ["https://example.com/blog/post-1", "https://example.com/blog/post-2"], "options": {"format": "markdown"}},
    timeout=30,
)
print(resp.json()["job_id"])
Node.js
const res = await fetch('https://webreaderapi.com/api/v1/batch', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ urls: ['https://example.com/blog/post-1', 'https://example.com/blog/post-2'], options: { format: 'markdown' } }),
});
console.log((await res.json()).job_id);

クロールジョブを開始する

POST/api/v1/crawl

開始URLから1つのWebサイトを幅優先で読み取ります。クローラーは開始URLのドメインに留まり、robots.txtで指定された、または/sitemap.xmlで見つかったsitemapを使用し、robots.txtとCrawl-delayを尊重します。値は例示です。

認証:Authorization: Bearer API_KEYヘッダーのAPIキー。

リクエストボディ

フィールド型必須説明
urlstringはい開始ページ。たとえばドキュメントサイトのホームページなどです。
limitintegerいいえ読み取るページ数の上限で、最大10,000。ジョブはこの数に達すると停止します。
max_depthintegerいいえ開始URLからリンクをたどる最大ステップ数。
include_pathsarray of stringsいいえ保持する単純なパスパターン。たとえば/docs/*などです。
exclude_pathsarray of stringsいいえスキップする単純なパスパターン。たとえば/blog/tag/*などです。
optionsobjectいいえurl以外の任意の/readパラメータで、すべてのページに適用されます。
例: the docs section of a site, 500 pages at most
{
  "url": "https://docs.example.com/",
  "limit": 500,
  "max_depth": 3,
  "include_paths": [
    "/docs/*"
  ],
  "exclude_paths": [
    "/docs/archive/*"
  ],
  "options": {
    "format": "markdown"
  }
}

レスポンス 202 Accepted

{
  "job_id": "job_8b27f41c0e"
}

コード例

curl
curl -s "https://webreaderapi.com/api/v1/crawl" \
  -H "Authorization: Bearer $WEBREADER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://docs.example.com/", "limit": 500, "include_paths": ["/docs/*"]}'
Python
import os
import requests

resp = requests.post(
    "https://webreaderapi.com/api/v1/crawl",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    json={"url": "https://docs.example.com/", "limit": 500, "include_paths": ["/docs/*"]},
    timeout=30,
)
print(resp.json()["job_id"])
Node.js
const res = await fetch('https://webreaderapi.com/api/v1/crawl', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://docs.example.com/', limit: 500, include_paths: ['/docs/*'] }),
});
console.log((await res.json()).job_id);

ジョブのステータスと結果を取得する

GET/api/v1/jobs/{job_id}

ジョブのステータスと、準備ができた次の結果を返します。resultsの各項目は、完全な/readレスポンスか、読み取れなかったページの{url, error}のいずれかです。next_cursorが存在する場合は、cursorにその値を設定してもう一度呼び出してください。存在しない場合は、まだ準備ができた結果はありません。値は例示です。

認証:Authorization: Bearer API_KEYヘッダーのAPIキー。

パラメータ

名前場所型必須説明
job_idpathstringはい/batchまたは/crawlが返したID。
cursorquerystringいいえ前回の呼び出しで得たnext_cursorの値。続きの結果を取得するために使用します。

レスポンス 200

{
  "job_id": "job_8b27f41c0e",
  "status": "running",
  "results": [
    {
      "url": "https://docs.example.com/docs/install",
      "final_url": "https://docs.example.com/docs/install",
      "status_code": 200,
      "rendered": false,
      "credits_used": 1,
      "title": "Install",
      "markdown": "# Install\n\nRun the installer...",
      "word_count": 418
    },
    {
      "url": "https://docs.example.com/docs/private",
      "error": {
        "code": "blocked_by_robots",
        "message": "robots.txt disallows this page for WebReaderAPI."
      }
    }
  ],
  "next_cursor": "c_000002",
  "credits_used": 1
}

コード例

curl
curl -sG "https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e" \
  -H "Authorization: Bearer $WEBREADER_API_KEY" \
  -d cursor=c_000002
Python
import os
import requests

resp = requests.get(
    "https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e",
    headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
    params={"cursor": "c_000002"},
    timeout=30,
)
job = resp.json()
print(job["status"], len(job["results"]), job.get("next_cursor"))
Node.js
const res = await fetch('https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e?cursor=c_000002', {
  headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}` },
});
const job = await res.json();
console.log(job.status, job.results.length, job.next_cursor);

ジョブの完了を待つにはどうすればよいですか?

/jobs/{job_id}をポーリングし、カーソルを保持します。取得した結果を処理したら、cursorにnext_cursorを設定してもう一度呼び出してください。next_cursorが存在せず、statusがdoneであれば、すべて取得済みです。存在せず、ジョブがまだrunningの場合は、待ってから同じカーソルで再度問い合わせてください。

最初は2秒ごとにポーリングし、新しい結果が届かない間は待ち時間を最大30秒まで倍にしていきます。サイトのCrawl-delayを尊重するクロールは時間がかかることがあるため、長い待ち時間は正常であり、コストはかかりません。

Python: ジョブをポーリングし、すべてのページを.mdファイルとして保存する
import os
import pathlib
import re
import time

import requests

JOBS = "https://webreaderapi.com/api/v1/jobs"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}


def save_job(job_id, folder="pages"):
    out = pathlib.Path(folder)
    out.mkdir(exist_ok=True)
    cursor, wait, saved = None, 2, 0
    while True:
        params = {"cursor": cursor} if cursor else {}
        job = requests.get(f"{JOBS}/{job_id}", headers=HEADERS, params=params, timeout=30).json()
        for item in job["results"]:
            if "error" in item:
                print("skipped", item["url"], item["error"]["code"])
                continue
            name = re.sub(r"[^a-z0-9]+", "-", item["final_url"].lower()).strip("-")[:120]
            (out / f"{name}.md").write_text(item["markdown"], encoding="utf-8")
            saved += 1
        if job.get("next_cursor"):
            cursor, wait = job["next_cursor"], 2
            continue
        if job["status"] == "done":
            return saved
        time.sleep(wait)
        wait = min(wait * 2, 30)


if __name__ == "__main__":
    print(save_job("job_8b27f41c0e"), "pages saved")

クロールはどのページを読み取りますか?

クロールは指定したURLから開始し、幅優先で1リンクステップずつ外側へ進み、最大max_depthまで読み取ります。また、リンクが少ないページを見つけるため、robots.txtで指定されたアドレスまたは/sitemap.xmlにあるサイトのsitemapも読み取ります。

  • 同一ドメインのみ。 他のドメインへのリンクは、include_linksを指定した場合に結果に一覧表示されますが、読み取られません。
  • パスフィルター。 include_pathsとexclude_pathsは/blog/*のような単純なパターンを受け付けます。
  • ページごとに1コピー。 サイトがcanonical URLを宣言している場合、複数のアドレスから到達したページは1回だけ読み取られます。
  • 強制停止。 ジョブはlimitページを読み取ると終了します。

クロールはどのようにサイトを尊重しますか?

すべてのリクエストにはUser-Agent WebReaderAPI/1.0 (+https://webreaderapi.com/bot/)が付与され、クローラーはWebReaderAPIに対するrobots.txtのルール、または該当する名前がない場合はすべてのロボットに対するルールに従います。許可されていないページはスキップされ、エラーblocked_by_robotsとともにresultsに表示されます。コストはかかりません。

robots.txtにCrawl-delayが設定されている場合、クローラーはサイトへの2つのリクエストの間にその時間だけ待機します。サイトがrobots.txtでContent-Signal: ai-input=noを宣言している場合、そのページをあなたのために読み取ることはありません。サイトが当社のリクエストを拒否した場合、その回答をそのまま返します。CAPTCHAを解いたり、アカウントにログインしたり、ブロックやペイウォールを回避しようとしたりすることは決してありません。

クロールのコストはいくらですか?

読み取った各ページには、/read呼び出しと同じコストがかかります: 1クレジット、ブラウザが必要なページは2クレジット、さらにcountryの場合は10クレジット。スキップされたページと失敗したページは無料です。ジョブのcredits_usedには、これまでに課金された分が合計されます。

ブラウザなしで読み取る500ページのドキュメントサイトでは約500クレジットを使用し、10,000ページパック($3.75)で何度もまかなえます。v1ではジョブをキャンセルできないため、limitが支出上限となります。支払ってもよい最大ページ数に設定してください。

バッチとクロール: よくある質問

/batchと多数の/read呼び出しのどちらを使うべきですか?

URLがすでにあり、各回答をすぐに必要としない場合は/batchを使用してください。並行処理とリトライの管理が不要になります。エージェントが今すぐ1ページを必要とする場合は/readを使用してください。

ジョブの結果はどのくらい保持されますか?

準備ができたらすぐに取得してください。結果は取得するまで保持されますが、一度配信されるとページ内容のコピーは保持されないため、必要なものはご自身の側で保存してください。

クロールは他のWebサイトへのリンクをたどれますか?

いいえ。クロールは1つのドメインのみを読み取ります。他のドメインは、指定した場合にリンクとして表示され、読み取りたい場合はそれらのURLを/batchに送ることができます。

開始したクロールを停止できますか?

v1ではできません。ジョブはlimitページで停止するため、予算に合った上限を選んでください。読み取り済みのページは課金されたままになり、読み取られなかったページは無料です。

$0.07/1Kページから · KYC不要

APIキーを取得