关于 WebReaper
WebReaper 是一个面向 AI 的网页抓取 MCP 服务,可将网页抓取、爬取和站点地图生成为干净的 Markdown,通过 stdio 提供。它以单一二进制文件分发,无需 Docker 或数据库,采用 MIT 许可证。
主要功能
- 01单一二进制文件,无需额外运行环境
- 02默认输出 Markdown,无需预先定义 schema
- 03遭遇拦截时自动从 HTTP 升级到浏览器或隐身模式
- 04被拦截的挑战页面会被丢弃,不写入输出
- 05支持 LLM 兜底提取与选择器自修复
适用场景
- 01为 LLM 构建博客或文档站点的上下文
- 02定时监控竞品价格或状态页面的变化
- 03抓取受 Cloudflare 等防护的目录页面
MCP 相关
WebReaper.Mcp 通过 stdio 暴露 scrape、map、extract、crawl 等工具,供 Cursor、Claude Desktop 等本地客户端调用;WebReaper.Mcp.AspNetCore 通过 Streamable HTTP 提供同样的工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍

WebReaper
AI 原生网页抓取工具。单个二进制文件,内置 Claude Code 技能。
由 HighCraft.io 构建。
安装
macOS / Linux(Homebrew):
brew install alex-on-ai/webreaper/webreaper
任意 POSIX shell(install.sh):
curl -fsSL https://raw.githubusercontent.com/alex-on-ai/WebReaper/master/scripts/install.sh | sh
.NET 库:
dotnet add package WebReaper
Windows 二进制文件可在 GitHub Releases 页面获取;winget 和 Scoop 已列入 v10.1 路线图。
**更新:**使用 Homebrew 时运行 brew upgrade webreaper,或在 install.sh 命令后追加 --upgrade 并重新运行(| sh -s -- --upgrade),或运行 dotnet add package WebReaper(库)。有更新版本时,scrape / crawl / map 会在 stderr 输出一行更新提示(仅限交互式终端,在管道或 CI 中不会提示);设置 WEBREAPER_NO_UPDATE_CHECK=1 可关闭此检查。
30 秒演示
$ webreaper scrape https://news.ycombinator.com
# Hacker News
- [Show HN: ...](https://news.ycombinator.com/item?id=...)
- [Ask HN: ...](https://news.ycombinator.com/item?id=...)
...
$ webreaper init
Wrote WebReaper Agent Skill to .claude/skills/webreaper/SKILL.md
Try it out:
webreaper scrape https://example.com
webreaper map https://example.com
运行 webreaper init 后,下一次 Claude Code 会话就会加载该技能,并自动将抓取意图(“给我 X 的 Markdown”、“Y 上有哪些博客文章”、“抓取排名前 5 的文章”)交给 webreaper 处理。
目录
- 为什么选择 WebReaper
- 快速开始
- 轻松应对机器人防护
- 为 Agent 提供动力
- AI 功能
- 使用场景
- 软件包
- 与 Firecrawl、Crawl4AI 和 Crawlee 的比较
- API 概览
- 架构与接口
- 仓库结构
- 许可证
为什么选择 WebReaper
| 🪶 放到 PATH 中,直接运行。 无需 Docker、Postgres 或注册。二进制文件约 12 MB。 | 🤖 以 AI 为核心构建。 默认输出 Markdown。支持架构提取、大模型回退、自修复选择器和自主 Agent。可与 .With…() 组合使用。 | 🔌 接入任意大模型。 通过 Microsoft.Extensions.AI 支持 OpenAI、Anthropic、Ollama、Azure OpenAI 和 llamafile。 |
| 🛡 自动处理机器人检查。 页面被拦截时,会按页面逐级尝试 HTTP → 浏览器 → 隐身模式,并对同一主机保持选择。挑战页面会被丢弃,不会作为数据返回。使用浏览器回退无需设置任何标记。 | 📡 按需分布式运行。 可将调度器、跟踪器和接收器替换为 Redis、MongoDB、SQLite、Azure Service Bus 或 Cosmos。代码保持不变。 | 📜 MIT 许可,而非 AGPL。 可嵌入商业软件、分叉、修改和再分发。Firecrawl 的 AGPL 要求公开服务源代码,或购买商业许可证。 |
快速开始
命令行界面
# One page as Markdown
webreaper scrape https://example.com
# Save Markdown to a file
webreaper scrape https://example.com --output page.md
# Discover URLs on a site
webreaper map https://example.com --search /blog/ --max-urls 50
# Crawl a whole site recursively (every on-domain page) to JSON Lines
webreaper crawl https://example.com > pages.jsonl
# Structured fields with a JSON schema (output: JSON; multi-page: JSON Lines)
webreaper scrape https://example.com --schema schema.json
# Schema-free extraction with an LLM (bring your own OpenAI-compatible endpoint)
webreaper scrape https://example.com --prompt "title and author" \
--model gpt-4o-mini --llm-url https://api.openai.com/v1
# Whole site, fields, cheaply: infer a schema once, then extract the rest
webreaper crawl https://example.com --infer "product name and price" \
--model gpt-4o-mini --llm-url https://api.openai.com/v1 --output-dir ./out
# JS-rendered single-page app
webreaper scrape https://example.com --browser
# Bot-protected site: a plain scrape already auto-climbs HTTP -> browser on a
# block; --stealth starts at a stealth backend (--auto-stealth = no prompt, for CI)
webreaper scrape https://example.com --stealth
# Install the Claude Code skill
webreaper init
命令行界面采用 Native-AOT 构建(ADR-0043),每个带标签的 GitHub 版本都会为六种 RID(linux-x64、linux-arm64、osx-x64、osx-arm64、win-x64、win-arm64)发布单个二进制文件,并能识别拦截状态,自动升级到浏览器/隐身模式(ADR-0083)。macOS 二进制文件经过 Apple 代码签名和公证(ADR-0071);在干净的机器上通过 Homebrew 安装,无需担心 Gatekeeper 警告。
库
using WebReaper.Builders;
var engine = await ScraperEngineBuilder
.Crawl("https://news.ycombinator.com")
.AsMarkdown()
.WriteToConsole()
.BuildAsync();
await engine.RunAsync();
它仅支持 HTTP,不需要额外的包,也不需要架构。对于结构化字段,将 AsMarkdown() 换成 Extract(schema);对于由 JS 渲染的页面,将 Crawl 换成 CrawlWithBrowser,并添加传输卫星(WebReaper.Playwright 或 WebReaper.Cdp)。完整功能请参阅 API 概览。
开箱即用的反机器人保护
大多数抓取工具都要求你一开始就选择使用浏览器,还得猜测网站何时在拦截你。WebReaper 会检测拦截,并按页面自行升级:
HTTP -> browser (Chromium) -> stealth (CloakBrowser)
(climbs only when a page actually looks blocked)
- 自动处理。 普通的
scrape或crawl会先使用快速 HTTP 获取,只有在页面看起来被拦截时(挑战状态、响应头或正文标记)才会升级到真实浏览器。浏览器回退无需设置标志。 - 逐页处理,主机级记忆。 首次确认某个主机发生拦截后,该主机的最低处理层级就会提升,因此整个站点爬取的其余页面都会从可用层级开始,而不会再次为失败的层级付出代价。升级只需付出一次成本,而非每页一次。
- 数据不掺杂垃圾。 如果页面在最高层级仍遭拦截,就会被丢弃,不会写入输出;运行也会以非零状态码退出,让无人值守的任务能够知晓。只提供干净数据或明确的信号,绝不让挑战页面伪装成内容。
- 隐身模式由你决定。
--stealth从隐身后端开始;--auto-stealth(或WEBREAPER_AUTO_STEALTH=1)可启用无人值守模式;--no-auto-stealth会将升级限制在普通浏览器。约 220 MB 的隐身后端仅在你选择启用时才会下载。
可自托管、单一二进制文件,无需往返云端(ADR-0083)。
为你的 Agent 提供动力
从零开始接入 Agent?把 docs/AI-ONBOARDING.md 交给它——在一个页面上完成安装 → 验证 → 选择路径,全程无需任何凭据。
Claude Code 技能
webreaper init
将精心编写的 SKILL.md 写入 .claude/skills/webreaper/。Claude Code 会在下一个会话中加载它,并将抓取请求路由到 CLI:“抓取 HN 上排名前 5 的故事并分别总结”、“给我这篇文章的 Markdown”、“这个受 Cloudflare 保护的网站正在拦截我”。该技能说明何时应优先使用 webreaper 而非内置的 WebFetch(通过 webreaper 获取产物和结构化数据;对话式回答则使用 WebFetch)。
MCP 服务
两个 MCP 服务为使用 Model Context Protocol 的客户端提供相同的工具(scrape、map、extract、extract_with_prompt、extract_inferred、crawl):
-
WebReaper.Mcp(ADR-0049)使用 stdio,适用于会启动进程的本地客户端:Cursor、Claude Desktop、Copilot Studio。 -
WebReaper.Mcp.AspNetCore(ADR-0086)使用 Streamable HTTP,适用于连接到 URL 的客户端。典型场景是 n8n:它的 MCP Client 节点仅支持 URL,无法连接 stdio 服务。运行内置 Chromium 的镜像,将 n8n 的 MCP Client 节点指向带有 bearer token 的 URL,然后在工作流中调用这些工具:docker run -p 8080:8080 -e WEBREAPER_MCP_TOKEN=your-secret \ ghcr.io/alex-on-ai/webreaper-mcp-http:latest请参阅 n8n 快速入门。
两者都是库 API 的轻量封装;主要的 Agent 接口仍然是 CLI。
在任意 Agent 执行环境中使用 CLI
这个单一二进制文件可在任何能启动 shell 的 Agent 中运行:LangChain ShellTool、OpenAI Assistants code-interpreter、GitHub Actions、内部脚本。无需安装运行时;只需一次系统调用即可启动。
AI 功能
1. 面向大模型的 Markdown,无需架构
await ScraperEngineBuilder
.Crawl("https://example.com")
.AsMarkdown() // ADR-0040 + ADR-0063
.WriteToConsole()
.BuildAsync()
.Result.RunAsync();
Markdown 提取器(HtmlToMarkdown 基元,ADR-0063;MarkdownContentExtractor 适配器,ADR-0040)会为每个页面输出 {title, markdown}。将输出直接传入后续的大模型提示词即可。
2. 带有编译时保护的源生成架构
using WebReaper.Extraction.Attributes;
[ScrapeSchema]
public partial class Article
{
[ScrapeField("h1")] public string? Title { get; set; }
[ScrapeField(".views", Type = SchemaFieldType.Integer)] public int Views { get; set; }
[ScrapeField(".tag", IsList = true)] public List<string> Tags { get; set; } = new();
}
// Emitted at compile time, reflection-free, AOT-clean:
// public static Schema Schema { get; }
// public static Article Materialize(JsonObject json)
var engine = await ScraperEngineBuilder
.Crawl("https://example.com/post")
.Extract(Article.Schema)
.Subscribe(p => HandleArticle(Article.Materialize(p.Data)))
.BuildAsync();
WebReaper.Extraction.Generators Roslyn 分析器(ADR-0045)会生成架构和 Materialize 函数。架构中的拼写错误会导致编译错误;生成的路径不使用反射,因此兼容 AOT。
3. 为确定性提取提供 LLM 安全网
三种可组合模式,仅当确定性路径无法完成任务时才会调用 LLM。三种模式采用相同的提议者-验证者结构。
using WebReaper.AI;
// (a) Fire LLM only when a field returns empty (ADR-0046)
.WithLlmFallback(chatClient)
// (b) Repair a broken selector once per (Schema, field), cache forever (ADR-0047)
.WithLlmSelfHealing(chatClient)
// (c) No schema at all: infer it from the URL, re-infer on validator failure (ADR-0067 + ADR-0069)
.UseAi(chatClient, AiPolicyMode.Inferred)
稳定页面不会产生 LLM 调用;有问题的页面每个(页面,字段)会产生一次调用,并缓存结果。每个站点只需调用一次进行架构推断(在本次运行中缓存)。WebReaper.AI 附属包基于 Microsoft.Extensions.AI 构建,因此适用于任何 IChatClient。
4. 自主 Agent:根据目标选择页面
using WebReaper.AI;
var result = await LlmAgent.RunAsync(
"https://example.com",
goal: "Find the contact email and phone number for the support team.",
chatClient);
AgentEngine(ADR-0051)会通过封闭和类型 AgentDecision(Extract | Follow | Act | Stop)运行顺序执行的 decide → persist → execute 循环。大脑根据有界的 AgentState 视图选择每个步骤;引擎负责验证(已访问链接的强制执行、MaxSteps 上限)、持久化(IAgentRunStore)和分派。进程重启后可持久恢复。
5. 语义页面操作
ScraperEngineBuilder
.CrawlWithBrowser(url, actions => actions
.Do(PageAction.SemanticAct("click 'sign in'")) // ADR-0050
.Do(PageAction.WaitForNetworkIdle())
.Build())
.WithLlmActionResolver(chatClient)
// ...
自然语言 PageAction.SemanticAct(intent) 是十个封闭和类型分支之一(ADR-0050 添加了它;ADR-0074 为表单交互添加了 Fill / Press / ScrollIntoView)。传输层通过已注册的 IActionResolver(默认由 LLM 提供支持)解析一次,然后分派具体分支,并按意图字符串缓存每次爬取的解析结果。第一个页面会调用 LLM;后续具有相同意图的页面会分派缓存的分支,不再调用 LLM。
可运行的端到端演示
Examples/WebReaper.AiNativeShowcase 展示了本节中的所有功能:
dotnet run --project Examples/WebReaper.AiNativeShowcase -- markdown
dotnet run --project Examples/WebReaper.AiNativeShowcase -- sourcegen
dotnet run --project Examples/WebReaper.AiNativeShowcase -- llm
dotnet run --project Examples/WebReaper.AiNativeShowcase -- router
dotnet run --project Examples/WebReaper.AiNativeShowcase -- changetrack
使用场景
- 从博客或文档站点构建 LLM 上下文。 对每个 URL 执行
webreaper map和webreaper scrape,并将结果传入提示词或向量数据库。 - 监控竞争对手的定价或状态页面变化。 使用 cron 或工作程序定时运行 CLI,将记录存入 MongoDB 或 SQLite,并接入
.WithChangeTracking()(ADR-0048),这样只有发生差异时才会触发接收器。基于哈希去重;适合 cron。 - 运行自主研究 Agent。
LlmAgent.RunAsync(url, goal, chatClient)会决定要跟进哪些链接,直到达成目标。重启后可持久恢复。 - 抓取受 Cloudflare 保护的目录。 普通的
scrape在遭到拦截时会自动从 HTTP 升级到浏览器;添加--stealth(或在无人值守运行时使用--auto-stealth)即可升级到隐身后端。被拦截的页面会被丢弃,绝不会作为挑战页面垃圾数据输出。 - 从半结构化页面生成干净的数据集。 使用
[ScrapeSchema]POCO 和源生成器;无需反射,可通过 AOT 编译为原生二进制文件。 - 在自己的应用中嵌入抓取功能。 执行
dotnet add package WebReaper;公共注册接口可让你接入 Redis、Cosmos DB 或自己的接收器。
程序包
此版本共发布十五个程序包(一个核心包、十四个附属包),版本号保持一致。核心包依赖精简,可发布为 Native-AOT,且零警告;附属包引入各自的 SDK 依赖,并将其隔离在核心依赖图之外(ADR-0009)。
| 软件包 | 用途 | 关键构建器调用 |
|---|---|---|
| WebReaper | 核心功能。HTTP 爬取和解析、内存和文件调度器/已访问链接跟踪器/Cookie 和配置存储、Console/CSV/JSON-Lines 输出目标、Markdown 提取器、架构折叠。依赖轻量,已准备好支持 Native AOT,不依赖 Newtonsoft。 | Crawl Extract AsMarkdown Follow Paginate Sweep WriteToJsonFile WriteToCsvFile WriteToConsole Subscribe |
| WebReaper.Cdp | 原始 CDP IPageLoadTransport(ADR-0052)。AOT 兼容(不依赖 PuppeteerSharp / Playwright);使用 System.Net.WebSockets 和 System.Text.Json source-gen。隐蔽模式的基础。 | .WithCdpPageLoader(cdpUrl)(自带)或 .WithCdpPageLoader(CdpLaunchOptions)(启动托管的 Chromium) |
| WebReaper.Playwright | 基于 Microsoft.Playwright 的传输层(ADR-0053)。支持多种浏览器(默认 Chromium;可选启用 Firefox / WebKit)。支持全部十种 PageAction 分支。适用于现代多浏览器需求;与 WebReaper.Cdp 搭配使用可支持 AOT 或隐蔽模式。 | .WithPlaywrightPageLoader() |
| WebReaper.Stealth.CloakBrowser | 首个隐蔽后端卫星包(ADR-0054)。首次使用时自动下载 CloakBrowser;基于 WebReaper.Cdp 组合构建。可通过 ADR-0058 引擎拆卸链释放。 | .WithCloakBrowser() |
| WebReaper.AI | 大模型提取、大模型操作解析器、大模型大脑、大模型自愈、大模型架构推断器(ADR-0044 / 0050 / 0051 / 0067)。基于 Microsoft.Extensions.AI 构建;需自带 IChatClient。 | .WithLlmFallback .WithLlmSelfHealing .WithLlmExtractor .WithLlmAgentBrain .WithLlmActionResolver .WithLlmSchemaInferrer .UseAi(client) |
| WebReaper.AI.Http | AOT 安全的 OpenAI 兼容 IChatClient(ADR-0084):原始 HttpClient 加 System.Text.Json source-gen,不依赖提供商 SDK。AOT CLI 和 MCP 服务用于提示词提取的自带客户端。 | new OpenAiCompatibleChatClient(baseUrl, model, apiKey) |
| WebReaper.Extraction.Attributes | [ScrapeSchema] / [ScrapeField] 标记类型。独立运行,无运行时开销。 | [ScrapeSchema] [ScrapeField("selector")] |
| WebReaper.Extraction.Generators | Roslyn 源生成器,可生成 static Schema 和无反射的 static Materialize(JsonObject)(ADR-0045)。DevelopmentDependency=true;不会在运行时传递。 | 仅编译时使用 |
| WebReaper.Mcp | MCP 服务 Exe,通过 stdio 将 scrape / map / extract / extract_with_prompt / extract_inferred / crawl 暴露为 MCP 工具(ADR-0049)。为本地 MCP 客户端(Cursor、Claude Desktop)提供互操作适配器。 | 此软件包 本身就是 可执行文件 |
| WebReaper.Mcp.AspNetCore | 通过 Streamable HTTP 提供 MCP 服务(ADR-0086),供 n8n 等基于 URL 的客户端使用;工具与 WebReaper.Mcp 相同,另提供 bearer-token 身份验证和 WEBREAPER_CDP_URL 浏览器 sidecar。还提供内置 Chromium 的容器映像。 | 此软件包 本身就是 可执行文件;或运行 docker run ghcr.io/alex-on-ai/webreaper-mcp-http |
| WebReaper.Mongo | MongoDB 结果输出目标和基于 MongoDB 的配置/Cookie 存储。 | .WriteToMongoDb(...) .WithMongoDbConfigStorage(...) .WithMongoDbCookieStorage(...) |
| WebReaper.Redis | Redis 调度器、已访问链接跟踪器、结果输出目标、配置/Cookie 存储。 | .WithRedisScheduler(...) .TrackVisitedLinksInRedis(...) .WriteToRedis(...) .WithRedisConfigStorage(...) .WithRedisCookieStorage(...) |
| WebReaper.AzureServiceBus | 基于 Azure Service Bus 队列的分布式调度器。 | .WithAzureServiceBusScheduler(...) |
| WebReaper.Cosmos | Azure Cosmos DB 结果输出目标。 | .WriteToCosmosDb(...) |
| WebReaper.Sqlite | 基于嵌入式 SQLite 存储的本地持久化调度器和已访问链接跟踪器;恢复时只需查询,无需位置文件。可选的强健本地方案(无需服务器,与 Redis 不同)。 | .WithSqliteScheduler(...) .TrackVisitedLinksInSqlite(...) |
WebReaper.Cli(AOT 单文件二进制;ADR-0043)不是 NuGet 包;它作为平台二进制文件随每个 GitHub 版本发布(Native-AOT 与 dotnet tool install 在同一目标上互不兼容)。通过 Homebrew 或 install.sh 安装,或从源代码构建。 |
与 Firecrawl、Crawl4AI 和 Crawlee 的对比
| WebReaper | Firecrawl | Crawl4AI | WebFetch(Claude) | |
|---|---|---|---|---|
| 许可证 | MIT | AGPL-3.0(另有商业许可) | Apache 2.0 | 随 Claude 捆绑 |
| 安装 | 单个二进制文件,约 12 MB | Docker + Postgres + Redis(自托管)或托管服务 | Docker + Python + Playwright | 无需安装 |
| 费用 | 免费 | 按量计费 API,另有免费额度 | 免费 | 已包含在 Claude 中 |
| 自带 LLM | 任意 IChatClient | 否(使用其模型) | 是(LiteLLM) | 仅限 Claude |
| 自主 Agent | Agent.RunAsync() 持久化、进程内运行 | /agent 端点(仅云端) | 自行编写代码 | 不提供 |
| 整站爬取 | webreaper crawl / .Sweep():递归、限于同一域名、由站点地图提供种子,并以 JSON Lines 流式输出 | crawl(云端或自托管) | 深度爬取策略(需自行编写代码) | 不支持(单次抓取) |
| 页面操作 | 10 种声明式操作:Click、Wait、Fill、Press、ScrollToEnd、ScrollIntoView、WaitForSelector、WaitForNetworkIdle、EvaluateExpression、SemanticAct(自然语言) | 9 种操作:wait、click、write、press、scroll、executeJavascript,以及 3 种观察操作(screenshot、pdf、scrape) | JS 钩子;没有封闭集合的操作词汇 | 无(仅支持单次抓取) |
| 受机器人防护的网站 | 自动按 HTTP → 浏览器 → 隐身模式逐级升级,按页面处理,主机级粘滞,自托管 | 云端支持;自托管能力受限(没有 Fire-engine) | 自行提供 | 不支持 |
| Claude Code 技能 | webreaper init 内置 | 社区版 firecrawl-claude-code-skill 封装云端 API | 无官方版本 | 不适用 |
Crawlee(Apify 的 Node/Python 库)也值得了解;它涵盖了与 WebReaper 库 API 类似的功能,但不提供二进制文件、Claude Code 技能或内置 LLM 安全网。如果你已经在使用 Apify 生态,可选择它。
最接近的参考是 Firecrawl:两者都定位为 AI 原生产品,但分发形态截然相反。Firecrawl 针对托管 API 工作流进行优化;WebReaper 则针对本地二进制文件工作流进行优化。如果你想使用由他人提供代理和基础设施的托管云服务,Firecrawl 是更合适的选择。如果你想要一个在本地运行、使用自己的 LLM 密钥且不按量计费的二进制文件,WebReaper 是更合适的选择。
API 概览
该库通过一小组接口提供流畅的构建器。有关各接口、主要实体和自定义接收器的详细参考,请参阅 docs/architecture.md。
架构提取
using WebReaper.Builders;
var engine = await ScraperEngineBuilder
.Crawl("https://www.alexpavlov.dev/blog")
.Extract(new()
{
new("title", ".text-3xl.font-bold"),
new("text", ".max-w-max.prose.prose-dark")
})
.Follow("a.text-gray-900.transition")
.WriteToJsonFile("output.json")
.PageCrawlLimit(10)
.WithParallelismDegree(30)
.LogToConsole()
.BuildAsync();
await engine.RunAsync();
每个 new("field", "css-selector") 都是一个叶节点;嵌套架构可表示对象,设置 IsList = true 可表示数组,设置 Attr = "href" 可读取 HTML 属性而非内部文本。
在进程内收集记录
在自己的进程中获取抓取到的记录,无需文件或自定义接收器。将线程安全集合的 Add 传给 Subscribe(ADR-0038),然后在运行结束后读取记录:
using System.Collections.Concurrent;
using WebReaper.Builders;
using WebReaper.Sinks.Models;
var records = new ConcurrentBag<ParsedData>();
var engine = await ScraperEngineBuilder
.Crawl("https://news.ycombinator.com")
.AsMarkdown()
.Subscribe(records.Add) // called concurrently; collect into a thread-safe type
.BuildAsync();
await engine.RunAsync();
foreach (var record in records)
Console.WriteLine($"{record.Url}: {record.Data["markdown"]?.GetValue<string>()?.Length ?? 0} chars");
Crawl 驱动会并发地将数据分发给各个接收器,因此应使用 ConcurrentBag 收集,而不是直接使用 List。对于结构化字段,请从 record.Data 中读取架构键,而不是读取 "markdown"。
解析动态页面(SPA)
对于由 JS 渲染的页面,将 Crawl 替换为 CrawlWithBrowser,并注册浏览器传输。有两个卫星包可供选择。
WebReaper.Playwright 是现代默认选项(ADR-0053):支持多种浏览器,涵盖全部十种 PageAction 分支。
using WebReaper.Builders;
using WebReaper.Playwright;
await ScraperEngineBuilder
.CrawlWithBrowser("https://example.com")
.Extract(new() { new("title", "h1") })
.WithPlaywrightPageLoader()
.BuildAsync();
WebReaper.Cdp 是适用于 AOT 的替代方案(ADR-0052):通过 System.Net.WebSockets 使用原始 CDP,可发布为 AOT。适用于 AOT 消费者,也可作为隐身后端的基础。
using WebReaper.Cdp;
.WithCdpPageLoader(new CdpLaunchOptions { Headless = true })
// or .WithCdpPageLoader(cdpUrl: "http://localhost:9222") for BYO browser
对于受机器人防护的网站,可在 WebReaper.Cdp 之上叠加 WebReaper.Stealth.CloakBrowser(ADR-0054):
using WebReaper.Stealth.CloakBrowser;
.WithCloakBrowser() // auto-downloads CloakBrowser on first use, ~220 MB
如需调试可见浏览器,添加 .HeadlessMode(false)。
运行 JavaScript 和页面操作
在页面加载时驱动页面。传入一个操作 lambda。
using WebReaper.Builders;
using WebReaper.Playwright;
using WebReaper.Domain.PageActions;
await ScraperEngineBuilder
.CrawlWithBrowser("https://www.reddit.com/r/dotnet/", actions => actions
.ScrollToEnd()
.Build())
.Extract(new() { new("title", "h1") })
.WithPlaywrightPageLoader()
.BuildAsync();
PageActionBuilder 提供 Click、Wait、ScrollToEnd、ScrollIntoView、WaitForSelector、WaitForNetworkIdle、EvaluateExpression、Fill、Press、SemanticAct、Repeat / RepeatWithDelay 和 Build()。Fill(selector, value) / Press(key) / ScrollIntoView(selector)(ADR-0074)具有隐式的 30 s 自动等待功能,并在 CDP 传输中使用兼容 React 的原生 setter 技巧,因此 React / Vue / Svelte 中的受控组件可以感知到变化。SemanticAct(ADR-0050)接收自然语言意图,并通过已注册的 IActionResolver 进行解析(参见 AI 功能 §5)。
在本地持久化进度
即使遇到 kill -9 也能保留进度,并在重启后继续。提供两个适配器:基于文件的适配器(零依赖,位于核心库中)和基于 SQLite 的适配器(持久化存储,通过 WebReaper.Sqlite 选择启用)。
using WebReaper.Builders;
using WebReaper.Sqlite;
await ScraperEngineBuilder
.Crawl("https://example.com")
.Extract(new() { new("name", "h1") })
.Follow(".forumlink>a")
.Paginate("a.torTopic", ".pg")
.WriteToJsonFile("result.json")
.WithSqliteScheduler("crawl/state.db") // resume is a query, not a position file
.TrackVisitedLinksInSqlite("crawl/state.db") // the table is the set
.BuildAsync();
向任何 sink、tracker 或 scheduler 方法传入 dataCleanupOnStart: true,即可在启动时清空其存储(注意:WriteToJsonFile 默认为 true,其他方法默认为 false)。
授权
如果网站需要 Cookie,请调用 SetCookies 并填充容器。登录操作由你自行完成。
using System.Net;
using WebReaper.Builders;
await ScraperEngineBuilder
.Crawl("https://example.com/protected")
.Extract(new() { new("name", "h1") })
.SetCookies(cookies =>
{
cookies.Add(new Cookie("AuthToken", "123"));
})
.BuildAsync();
分布式和无服务器
将 scheduler、配置存储和链接 tracker 替换为 Redis 或 Azure Service Bus;多个 worker 或无服务器函数可以共享一次爬取。Examples/WebReaper.AzureFuncs 展示了无服务器模式(两个函数:StartScraping 为任务提供种子,WebReaperSpider 是分布式 Crawl 驱动程序)。Examples/WebReaper.DistributedScraperWorkerService 展示了 worker 服务模式。
DistributedSpiderBuilder.BuildSpider() 返回一个不带 Crawl 种子的裸 ISpider(ADR-0009 / ADR-0025:“两个接缝,而不是一个 bug”的拆分)。worker 的配置由启动端点单独持久化。
存储和 scheduler 后端
每个后端都是可替换的接缝。默认使用内存;基于文件的后端位于核心库中;其他后端来自卫星包。
| 接缝 | 核心库(默认使用内存 + 文件) | 卫星包选项 |
|---|---|---|
| Scheduler | 内存、WithTextFileScheduler | WithSqliteScheduler、WithRedisScheduler、WithAzureServiceBusScheduler |
| 已访问链接 tracker | 内存、TrackVisitedLinksInFile | TrackVisitedLinksInSqlite、TrackVisitedLinksInRedis |
| 配置存储 | 内存、WithFileConfigStorage | WithMongoDbConfigStorage、WithRedisConfigStorage |
| Cookie 存储 | 内存、WithFileCookieStorage | WithMongoDbCookieStorage、WithRedisCookieStorage |
| Agent 运行存储 | 内存、文件(ADR-0051) | WithSqliteAgentRunStore、WithRedisAgentRunStore、WithMongoAgentRunStore、WithCosmosAgentRunStore |
| 结果 sink | WriteToConsole、WriteToCsvFile、WriteToJsonFile | WriteToMongoDb、WriteToRedis、WriteToCosmosDb |
| 页面加载器传输 | HTTP(默认) | WithPlaywrightPageLoader、WithCdpPageLoader、WithCloakBrowser |
自定义 sink、完整的接口索引和主要领域实体位于 docs/architecture.md。
仓库结构
| 项目 | 描述 |
|---|---|
WebReaper | 核心库(WebReaper NuGet 包)。 |
WebReaper.Cdp | 原始 CDP 传输附属项目(ADR-0052)。 |
WebReaper.Playwright | Microsoft.Playwright 传输附属项目(ADR-0053)。 |
WebReaper.Stealth.CloakBrowser | 首个隐身后端附属项目(ADR-0054)。 |
WebReaper.AI | 大模型提取、操作解析器、Agent 大脑、自我修复、架构推断器。 |
WebReaper.Extraction.Attributes | [ScrapeSchema] / [ScrapeField] 标记类型(ADR-0045)。 |
WebReaper.Extraction.Generators | Roslyn 源生成器(ADR-0045)。 |
WebReaper.Mcp | MCP 服务附属项目(ADR-0049)。 |
WebReaper.Mongo | MongoDB 数据接收端,以及配置 / Cookie 存储。 |
WebReaper.Redis | Redis 调度器、跟踪器、数据接收端,以及配置 / Cookie 存储。 |
WebReaper.AzureServiceBus | Azure Service Bus 分布式调度器。 |
WebReaper.Cosmos | Azure Cosmos DB 数据接收端。 |
WebReaper.Sqlite | 基于嵌入式 SQLite 的本地持久化调度器和已访问链接跟踪器。 |
WebReaper.Cli | AOT 单二进制命令行工具(ADR-0043)。 |
Examples/WebReaper.ConsoleApplication | 在控制台应用程序中使用 WebReaper。 |
Examples/WebReaper.AiNativeShowcase | 本 README 中每项 AI 功能的可运行演示。 |
Examples/WebReaper.SchemaInferenceShowcase | ADR-0067 / 0068 / 0069 架构推断演示。 |
Examples/WebReaper.ScraperWorkerService | 在 .NET Worker Service 中使用 WebReaper。 |
Examples/WebReaper.DistributedScraperWorkerService | 多个工作器共享爬取状态的分布式爬取。 |
Examples/WebReaper.AzureFuncs | 使用 Azure Functions 和 Azure Service Bus 进行无服务器爬取。 |
Examples/BrownsfashionScraper | 真实电商爬虫示例。 |
Misc/WebReaper.ProxyProviders | 代理提供程序实现示例。 |
许可证
WebReaper 采用 MIT 许可证(ADR-0017)。所有 NuGet 包和 WebReaper.Cli 二进制文件均遵循相同条款。可将其用于商业用途、嵌入专有软件、分叉、修改和再分发;唯一要求是保留版权声明。
在 10.0.0 版本浪潮之前,WebReaper 采用 GPL-3.0-or-later 许可证。重新授权仅使许可更加宽松:现有用户不受影响;此前无法在 GPL 许可下嵌入软件的新用户现在可以了。历史贡献者已列于 CONTRIBUTORS.md。有关分析和贡献者同意流程,请参阅 docs/adr/0017-relicense-gpl-mit.md。
欢迎按相同的 MIT 条款贡献;请通过 DCO 签署(CONTRIBUTING.md)。
由 HighCraft.io 打造——一支软件与 AI 工程团队。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。