2026-10-16

[C#] Web Agent 開發:使用 Cloudflare Browser Rendering 讀取動態網頁

前面研究過 Tavily Extract Keyless 跟 Jina Reader,都可以讓自己的 Web Agent 直接讀取網頁,再轉成 Markdown 給 LLM 使用

後來發現 Cloudflare 其實也有類似的服務,叫做 Browser Rendering ...


他跟一般 Web Fetch 有點不一樣,Cloudflare 會在雲端使用瀏覽器載入網頁,所以連需要執行 JavaScript 的網站(SPA)也有機會抓到內容,不用自己安裝 Chromium 或維護 Headless Browser ,而且 Cloudflare 還有免費額度,這個就很有戲了,開測 ..

這次直接用 C# HttpClient 呼叫它的 Markdown API

1. Cloudflare Browser Rendering 

Browser Rendering 是 Cloudflare 提供的雲端瀏覽器服務,除了可以取得網頁 Markdown,也支援 HTML、Screenshot、Links、PDF 等功能

我自己比較有興趣的是 Markdown API,畢竟做 AI Agent,主要就是想把網頁內容交給 LLM 閱讀

跟一般用 HttpClient 抓 HTML 不同,Browser Rendering 會先在雲端瀏覽器載入網頁、執行 JavaScript,再取得內容

如果網頁本身需要 JavaScript 才能顯示文章內容,這種方式就比較有機會抓到

不過遇到登入限制或網站防爬蟲,也不是保證一定成功

2. 免費額度與 API Token

翻了一下 Cloudflare 官方文件,目前 Workers Free 提供每天 10 分鐘的 Browser 使用時間

這不是每天只能使用 10 分鐘,而是累計 Browser 執行時間,例如每次擷取耗時 5 秒,理論上大約可以呼叫 120 次,實際還是以 Cloudflare 的計量為準

另外 Workers Paid 方案目前包含每月 10 小時的 Browser 使用時間,超過後依 Browser Hours 計費

跟 Tavily Keyless 不同,Cloudflare REST API 還是需要 Account ID 與 API Token,不過免費方案不用另外購買 Browser Rendering 服務,也不用自己部署 Worker

這邊有個坑,我自己就卡了一陣子

Cloudflare 現在有 User API Token 跟 Account API Token 兩種,我一開始跑去個人帳號的 API Tokens 建立 Token,結果 C# 呼叫 Browser Rendering 一直出現 

HTTP 401
{ "result": null, "success": false, "errors": [ { "code": 10000, "message": "Authentication error" } ], "messages": [] }

更麻煩的是,我另外呼叫 Cloudflare Token Verify API,結果竟然是 HTTP 200,而且 Token 狀態是 active

也就是說 Token 本身有效,但 Browser Rendering 還是拒絕存取

後來才找到 Cloudflare 帳戶底下還有另一個建立 Token 的地方 :

Manage Account → Account API tokens

網址 :

https://dash.cloudflare.com/{ACCOUNT_ID}/api-tokens

注意,這跟個人資料裡面的 API Tokens 不是同一個地方

這次改從 Account API tokens 建立,權限設定 :

Account
  Browser Rendering
    Edit

記得選擇正確的 Account,建立完成後複製 API Token

這裡要說一下,User API Token 並不是一定不能使用 Browser Rendering,只是 Cloudflare 的 User Token 跟 Account Token 有不同的授權模型

我這次踩到的問題就是 Token 驗證成功,但實際服務仍然回傳 401,所以如果你也遇到同樣情況,可以先檢查建立 Token 的位置、權限及 Account ID

另外 Account ID 不是 Zone ID,也不是 Token ID,這個不要填錯


官方文件 :

Cloudflare Account API Tokens

官方價格 :

Cloudflare Browser Rendering Pricing

3. C# 使用 HttpClient 呼叫 Markdown API

這次一樣使用 .NET 10,不需要額外安裝 SDK

Endpoint :

POST https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/markdown

認證使用 Bearer Token,這次就直接把 Account ID 跟 API Token 寫在程式碼裡面,方便測試

C# Code :

using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

namespace AgentSearchTest
{
    internal class CloudflareBrowserTest
    {
        public static async Task RunAsync()
        {
            // Cloudflare Account ID 與 Account API Token
            var accountId = "YOUR_ACCOUNT_ID";
            var apiToken = "YOUR_API_TOKEN";

            using var http = new HttpClient();

            // 設定 Bearer Token
            http.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", apiToken);

            // 指定要擷取的網頁
            var request = new
            {
                url = "https://donmalab.com/"
            };

            // Cloudflare Browser Rendering Markdown API
            var endpoint =
                $"https://api.cloudflare.com/client/v4/accounts/{accountId}/browser-rendering/markdown";

            using var response = await http.PostAsJsonAsync(
                endpoint,
                request);

            var body = await response.Content.ReadAsStringAsync();

            // API 呼叫失敗時顯示錯誤
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine($"HTTP {(int)response.StatusCode}");
                Console.WriteLine(body);
                return;
            }

            using var json = JsonDocument.Parse(body);
            var root = json.RootElement;

            // 檢查 Cloudflare 回傳狀態
            if (root.TryGetProperty("success", out var success) &&
                !success.GetBoolean())
            {
                Console.WriteLine(body);
                return;
            }

            // 輸出擷取後的 Markdown
            if (root.TryGetProperty("result", out var result))
            {
                Console.WriteLine(result.GetString());
            }
        }
    }
}

這邊主要就是看 API 回傳的 result,裡面會是 Cloudflare 轉換後的 Markdown

Cloudflare API 回傳的是 JSON,所以不是直接把整個 Response Body 印出來,而是取出 result

這次先用自己的網站當範例,實際能抓到多少內容還是得看網頁本身,以及 Browser Rendering 的執行情況

另外 API Token 直接寫在 Code 裡面只是方便測試,正式專案記得抽到環境變數比較安全



4. 跟 Tavily Extract、Jina Reader 有什麼不同?

前面研究過的 Tavily Extract、Jina Reader 都可以抓取網頁內容,Cloudflare Browser Rendering 則比較偏向真正的瀏覽器 Render

Tavily Extract 跟 Jina Reader 都可以直接取得 Markdown,而且不一定需要 API Key,拿來處理一般文章其實就夠用了

Cloudflare 不太一樣,它會在雲端使用瀏覽器載入網頁,包含執行 JavaScript,所以遇到一般 Web Fetch 抓不到內容的網站,可以再試試 Browser Rendering

不過 Cloudflare 需要 API Token,而且是依照 Browser 使用時間計量,沒有必要每次都動用瀏覽器

所以我自己會先使用 Tavily 或 Jina,真的遇到需要 JavaScript Render 的網頁,再換 Cloudflare 處理

簡單小結

Cloudflare Browser Rendering 不用自己安裝 Chromium,就能透過 API 取得網頁 Render 後的內容,而且還能直接轉成 Markdown

免費方案每天有 10 分鐘的 Browser 使用時間,拿來做 Agent 測試應該還可以

我自己會把它當成另一個 Web Fetch Provider,平常使用 Tavily Extract、Jina Reader,遇到需要 JavaScript Render 的網頁再交給 Cloudflare

這次最麻煩的反而不是 C# Code,而是 Cloudflare 的 API Token,光是找對申請位置就踩了一個坑

先記錄到這邊,如果你也在開發 Web Agent,多一個 Web Fetch 備援總是好事..

reference :

--

Before you read this, the article was in a superposition of human and AI. Upon observation, the wave function collapsed into a sleep-deprived developer.

如果這篇文章有幫助到您幫我分享一下,讓我有寫下去的動力...