Quarto × quarto-dsh × Kitesurf で情報収集を自動化

低リソースの AI エージェント向けブラウザ Kitesurf でページを取得し、quarto-dsh で検証・整形して Quarto でレポート化する情報収集パイプライン

概要

Web からの情報収集を自動化するとき、「収集 → 抽出 → 検証 → 整形 → レンダリング → 公開」 のループをすべて人手で回すのは非効率です。本記事では、次の 3 つのツールを組み合わせて、このループを仕組み化する手法を解説します。

ツール 役割 担当
Kitesurf(Cloudflare) 対象ページの HTML / Markdown / スクリーンショット / PDF を低リソースで大量取得 収集・抽出
quarto-dsh .qmd の記法・設定を実在キーで検証し、レンダリング・デプロイを自動化 検証・整形
Quarto 収集結果を構造化し、レポート・サイトとして整理・公開 整理・公開
Note

本記事の位置づけ — 本記事は Kitesurf の 正当な情報収集・分析用途 における使い方の解説です。Kitesurf の低コスト・低リソースという特性は、悪用(過剰なスクレイピング・競合 LP の模倣など)にも転用し得ます。この点については Cloudflare Kitesurf 評価・考察レポート を参照してください。収集対象サイトの利用規約・robots.txt・著作権には必ず従ってください。

前提と準備

必要物 内容
Cloudflare アカウント dash.cloudflare.com で無料取得
Browser Run API トークン カスタム API トークン(権限: Browser Rendering - Edit)
Quarto >= 1.3(brew install quarto)
Node.js / pnpm Node >= 20、pnpm(任意)

API トークンは次の手順で作成します。

  1. API トークン → Create Token
  2. Custom token → Browser Rendering - Edit の権限を付与
  3. 生成したトークンを環境変数に保存
export CLOUDFLARE_API_TOKEN=xxxxx
export CLOUDFLARE_ACCOUNT_ID=<あなたのアカウントID>
Note
  • Kitesurf は 無料ベータ として提供されており、アカウント単位の limits が適用されます。トークンは 最小権限 に絞り、コードに直接書かず環境変数やシークレットで管理してください。
  • 本記事のエンドポイント・パラメータは 2026-08-17 時点 の公式ドキュメントに基づきます。仕様はベータ期間中に変更される可能性があります。

Step 1: Kitesurf でページを取得する(Quick Actions)

Kitesurf を有効にするには、Browser Run の Quick Actions エンドポイントに ?browser=kitesurf を付与します。これを付けないと既定の Chromium が使われます。

Warning

エンドポイントのパスについて(重要) — 公式ドキュメントの間で API パスに表記ゆれがあります。

  • Kitesurf ドキュメント(2026-08-07 更新): https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/screenshot?browser=kitesurf
  • Quick Actions API リファレンス: https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-rendering/screenshot

Browser Rendering から Browser Run へのリネーム移行中のためと推察されます。一方のパスが 404 を返す場合はもう一方を試してください。実環境では必ず API リファレンス を確認してください。

1-1. HTML を取得する(/content)

JS 実行後のレンダリング済み HTML(head セクション含む)を取得します。SPA や JS 主体のページ向けです。

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/content?browser=kitesurf' \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com"}' \
  --output page.html

JavaScript 主体のページ(SPA など) は、既定の読み込み完了判定では空・不完全な結果になることがあります。gotoOptions.waitUntil でネットワークが落ち着くまで待ちます。

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/content?browser=kitesurf' \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com",
    "gotoOptions": {
      "waitUntil": "networkidle0"
    }
  }'
  • waitUntil は networkidle0 / networkidle2 を指定できます。より速く応答させたい場合は、全体のネットワーク待ちではなく waitForSelector で特定要素の出現を待ちます。
  • 読み込むリソースを制限するには rejectResourceTypes(image など)や rejectRequestPattern(正規表現)を使います。画像・CSS を外すと応答が軽くなります。
  • userAgent でページ単位のユーザーエージェントを設定できます。ただし ボット対策を回避できるわけではありません(Browser Run のリクエストは常にボットとして識別されます)。

1-2. Markdown を抽出する(/markdown)

ページ本文を Markdown に変換して返します。レスポンスは JSON で、result に Markdown 文字列が入ります。整形・要約・差分比較・埋め込み向きです。

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/markdown?browser=kitesurf' \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com"}'
{
  "success": true,
  "result": "# Example Domain\n\nThis domain is for use in illustrative examples in documents..."
}

取得済みの生 HTML から直接変換することもできます(url の代わりに html を渡します)。CSS などの不要なリクエストを除外するには rejectRequestPattern を使います。

1-3. スクリーンショットを撮る(/screenshot)

レンダリング後のページを PNG で返します。バイナリなので --output でファイルに保存します。

curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/screenshot?browser=kitesurf' \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com"}' \
  --output "screenshot.png"

よく使うオプション:

オプション 内容
screenshotOptions.fullPage true でページ全体を撮影
viewport 表示領域の width / height(既定 1920×1080)。deviceScaleFactor(既定 1)を上げると解像度が上がります
quality PNG 形式では非対応(400 エラー)。type: "jpeg" と併せて指定
selector CSS セレクタで特定要素だけを撮影

PDF 生成は /pdf エンドポイントで行えます(browser=kitesurf を同様に付与)。対象が 動画・WebGL・実 TLS ハンドシェイク・長時間の認証セッション を必要とする場合は Kitesurf は未対応です(評価レポート 参照)。こうした用途では Chromium(?browser=kitesurf なし)を使ってください。

1-4. Worker binding から呼び出す

Worker 内からは env.BROWSER.quickAction() で直接呼べます(API トークン不要)。wrangler.json に browser binding と compatibility date >= 2026-03-24 を設定します。

{
  "compatibility_date": "2026-03-24",
  "browser": {
    "binding": "BROWSER",
    "remote": true
  }
}
export default {
  async fetch(request, env) {
    return await env.BROWSER.quickAction("markdown", {
      url: "https://example.com",
    });
  },
};
Note

quickAction() はローカル開発(wrangler dev)では未対応です。npx wrangler dev --remote か binding の "remote": true が必要です。

Step 2: CDP / MCP で柔軟に取得する

Quick Actions は 1 回のリクエストで完結する「ショット」向けです。対話的操作(クリック・フォーム入力・複数要素の抽出) が必要な場合は、CDP エンドポイントまたは MCP を使います。

CDP エンドポイント

wss://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/devtools/browser?browser=kitesurf

Chrome DevTools Protocol を話せるクライアント(Puppeteer / Playwright / chrome-remote-interface)が既存のまま動作します。browser=kitesurf を付与するだけで切り替えられます。

MCP クライアントから使う

MCP 対応エージェント(opencode など)からは chrome-devtools-mcp を経由して接続します。

{
  "mcp": {
    "kitesurf": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "chrome-devtools-mcp@latest",
        "--wsEndpoint=wss://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/browser-run/devtools/browser?browser=kitesurf",
        "--wsHeaders={\"Authorization\":\"Bearer <API_TOKEN>\"}"
      ],
      "enabled": true
    }
  }
}

これでエージェントが「このページの CTA ボタンのリンク先を調べて」「フォームを送信して結果を取得して」といったタスクを Kitesurf 上で実行できます。

Step 3: 収集結果を .qmd に整形する

収集した HTML / Markdown を、情報収集シートとして .qmd にまとめます。front matter に収集日時と出典を必ず記録します。

---
title: "LP 調査シート: example.com"
description: "Kitesurf で取得した example.com LP の構造解析メモ"
date: 2026-08-17
categories: [情報収集]
source: "https://example.com"
---

## 概要

<!-- ここに取得した Markdown / HTML から要約を記載 -->

## 見出し構造

## CTA / フォーム

| 要素 | 内容 | リンク先 |
|---|---|---|
| 主要 CTA | ... | ... |
| 入力フォーム | ... | ... |

## メタタグ

## スクリーンショット

![](screenshot.png)

LP 解析の視点(見出し・CTA・フォーム・メタタグ)は、評価レポートの活用手順 の手順 2「構造化データ抽出」に沿ったものです。

Step 4: quarto-dsh で検証・整形する

外部から取得したコンテンツをそのまま貼り付けると、Quarto の記法を壊す不整合(未対応の callout 型・チャンクオプション・Div の開閉ミス)が混入することがあります。quarto-dsh で機械的に検証します。

quarto-dsh lint                 # front matter の実在キーを検証
quarto-dsh scan info-sheet.qmd  # callout 型・チャンクオプション・相互参照・Div 開閉を検査
  • lint — title / date / categories などの front matter が実在キーかどうかを検証し、誤記を即座に指摘します。
  • scan — 収集元の Markdown 由来で混入した不正な記法を検出します。
  • chat — DeepSeek エージェントに「収集した Markdown を要約して .qmd に整形して」と依頼できます。
export DEEPSEEK_API_KEY=sk-...
quarto-dsh chat "raw-content.md を読んで、情報収集シートの形式で summary.qmd に整形して"

Step 5: レンダリングと公開(自動化)

手動

quarto-dsh render       # サイト / レポートを生成
quarto-dsh ci --dir site # GitHub Actions のデプロイ設定を生成

定期収集の自動化(ループの完成形)

GitHub Actions の schedule(cron) で「Kitesurf で収集 → .qmd 更新 → レンダリング → デプロイ」を定期実行します。

name: Scheduled info-gathering

on:
  schedule:
    - cron: "0 2 * * 1"   # 毎週月曜 02:00 UTC
  workflow_dispatch:

permissions:
  contents: write
  pages: write
  id-token: write

jobs:
  gather:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: quarto-dev/quarto-actions/setup@v2
      - name: Fetch pages with Kitesurf
        run: |
          curl -X POST 'https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/browser-run/markdown?browser=kitesurf' \
            -H "Authorization: Bearer ${{ secrets.CF_API_TOKEN }}" \
            -H 'Content-Type: application/json' \
            -d '{"url": "https://example.com"}' \
            --output data/example.json
      - name: Update report qmd
        run: quarto-dsh chat "data/example.json を集計し site/report/weekly.qmd を更新して"
        env:
          DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
      - name: Validate
        run: |
          quarto-dsh lint
          quarto-dsh scan site/report/weekly.qmd
      - name: Render and deploy
        run: quarto render site
      - uses: actions/configure-pages@v5
      - uses: actions/upload-pages-artifact@v3
        with:
          path: site/_site
Note

シークレット(CF_API_TOKEN / CF_ACCOUNT_ID / DEEPSEEK_API_KEY)は GitHub の Settings → Secrets and variables → Actions で登録してください。quarto-dsh ci が生成するワークフローをベースに、収集ステップを足すのが早道です。

全体フロー

1. 対象 URL を選定(収集範囲・頻度を決める)
2. Kitesurf で収集: /content(HTML)・/markdown(本文)・/screenshot(画像)
3. 抽出: 見出し・CTA・フォーム・メタタグを整理
4. 整形: front matter(date / source 付き)で .qmd 化
5. 検証: quarto-dsh lint / scan で記法・キーを検査
6. レンダリング: quarto-dsh render でサイトを生成
7. 公開: quarto-dsh ci / GitHub Actions で自動デプロイ
8. 反復: cron で定期実行(ループ化)

本サイトの Cloudflare Kitesurf 評価・考察レポート は、この情報収集パイプラインの流れを踏まえて作成・掲載された実例です(収集 → 公式情報での裏付け → .qmd 化 → 検証 → 公開)。

運用上の注意とベストプラクティス

  1. 収集対象の尊重 — robots.txt・利用規約・著作権を確認し、情報収集が過剰なスクレイピングや競合 LP の丸ごと模倣にならないようにする。負荷をかける同時実行は避け、レートリミットに配慮する。
  2. トークンは最小権限 — Browser Rendering - Edit のみ。CI では GitHub のシークレットで管理し、コードに書かない。
  3. 出典と日時の記録 — front matter の date(収集日)と source(URL)を必ず残す。レポート運用規約(DEV-MEMO)と整合。
  4. 未検証情報の扱い — 数値や主張が一次情報で確認できない場合は「要検証」と注記する。
  5. 仕様変更容易性 — Kitesurf はベータのため、エンドポイント・パラメータ・limits は随時公式ドキュメントを確認する。
  6. Kitesurf の適用範囲 — 動画・WebGL・実 TLS・長時間の認証セッションが必要なページでは Chromium(?browser=kitesurf なし)を使う。

まとめ

  • Kitesurf が「収集・抽出」、quarto-dsh が「検証・整形」、Quarto が「整理・公開」を担う情報収集ループを構築できます。
  • Quick Actions(/content /markdown /screenshot)で低コストに取得し、CDP / MCP で対話的操作を拡張します。
  • quarto-dsh の lint / scan / render / ci / chat を組み合わせ、cron 定期実行まで含めれば完全に自動化できます。

関連