news 2026/9/28 19:40:55

用 C 通过 Xberg 从 URL 提取网页正文:ExtractAsync 与 UrlExtractionConfig 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 C 通过 Xberg 从 URL 提取网页正文:ExtractAsync 与 UrlExtractionConfig 实战
  • 后端
  • AI 应用
  • NLP

【免费下载链接】xberg

Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.

项目地址:https://gitcode.com/gh_mirrors/kr/xberg
点击查看免费下载

本文以 Xberg 的 C# 绑定为例,讲解如何基于XbergConverter.ExtractAsync直接传入一个 HTTP(S) URL,让引擎自动抓取网页并返回可读正文(Markdown/纯文本)与结构化元数据。读完你可以掌握ExtractInput、UrlExtractionConfig、UrlExtractionMode三种模式(auto/document/crawl)的完整用法,并理解底层 crawlberg 抓取引擎的工作方式与批量 URL 的共享执行机制。

场景概述:把"抓网页"当成"提取文档"

在传统方案里,抓取网页正文往往需要组合 HTTP 客户端、HTML 解析器与正文抽取逻辑。而 Xberg 把 URL 视为与本地文件、内存字节并列的一等输入类型:只要在ExtractInput中把kind设为"uri"并传入 URL,核心引擎就会自动完成下载、MIME 识别、HTML 转 Markdown、元数据抽取等整条流水线,最终返回一个统一的ExtractedDocument结果。仓库中对应的端到端 fixture 位于 fixtures/url/url_html_page_extract.json,其描述正是 "extract: website URL returns page content"(网站 URL 返回页面内容)。

核心 API 速览

围绕 URL 提取,C# 绑定暴露了三个关键类型:

  • XbergConverter.ExtractAsync(...):统一的异步提取入口,位于 packages/csharp/src/Xberg/XbergConverter.cs;
  • ExtractInput:描述"提取什么",其中Kind = Uri表示输入是一个 URI(本地路径、file://URI 或 HTTP(S) URL);
  • ExtractionConfig.Url:UrlExtractionConfig类型,专门描述"如何抓取/爬取这个 URL"。

对应的 Rust 核心类型定义在 crates/xberg/src/core/config/extraction/types.rs,包括ExtractInput、ExtractInputKind、UrlExtractionMode、UrlExtractionConfig与ExtractionResult。

完整示例:提取单个网页正文

关联文档给出的 C# 示例是这套 API 最精简的用法,原文完整保留如下:

using System; using System.Text.Json; using Xberg; var ConfigOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var result = await XbergConverter.ExtractAsync(new ExtractInput { Kind = JsonSerializer.Deserialize<ExtractInputKind>("\"uri\"", ConfigOptions)!, Uri = "https://example.com" }, new ExtractionConfig { Url = new UrlExtractionConfig { Mode = JsonSerializer.Deserialize<UrlExtractionMode>("\"document\"", ConfigOptions)! } }); Console.WriteLine(result.Results[0].Content); Console.WriteLine(result.Results);

这段代码做了三件事:

  1. 构造输入:ExtractInput.Kind解析为枚举值uri,Uri字段指向https://example.com。这里通过JsonSerializer.Deserialize把字符串"uri"/"document"转换为枚举,是因为绑定层以 JSON 序列化方式与 Rust 核心通信,而核心侧枚举的 JSON 形式就是小写 snake_case 变体名。
  2. 配置抓取模式:在ExtractionConfig.Url中把Mode显式设为document,告诉引擎"把这个 URL 当作单个远程文档页面处理",而不是当作爬虫种子。
  3. 输出结果:result.Results[0].Content是提取出的页面正文文本,result.Results是完整的ExtractedDocument列表(可 JSON 化,包含元数据、标题、语言等信息)。

为了方便实际工程使用,可以把枚举解析换成更直接、可读性更高的写法(效果完全等价):

using System; using Xberg; var result = await XbergConverter.ExtractAsync( new ExtractInput { Kind = ExtractInputKind.Uri, Uri = "https://example.com" }, new ExtractionConfig { Url = new UrlExtractionConfig { Mode = UrlExtractionMode.Document } }); Console.WriteLine(result.Results[0].Content);

注意:ExtractInputKind与UrlExtractionMode的枚举成员(Auto/Document/Crawl)在 UrlExtractionMode.cs 中通过[JsonPropertyName]显式标注了序列化名,序列化到核心时会自动转为auto/document/crawl。

UrlExtractionMode:三种 URL 处理模式

UrlExtractionMode决定引擎拿到 URL 之后采取哪种抓取策略,定义于 crates/xberg/src/core/config/extraction/types.rs:

模式JSON 值行为对应引擎路径
Auto(默认)auto抓取后自动分类 HTTP(S) 资源,再决定如何提取batch_scrape分支
Documentdocument把该 URI 当作单个远程文档/页面处理batch_scrape分支
Crawlcrawl以该 URI 为种子爬取,提取发现的页面与文档batch_crawl分支

从引擎实现 crates/xberg/src/engine/extract_impl.rs 的分支代码(UrlExtractionMode::Auto | UrlExtractionMode::Document走 scrape,UrlExtractionMode::Crawl走 crawl)可以确认:document模式只抓取目标页本身;而crawl模式会继续跟随页面内发现的链接,并把每个发现的页面/文档分别转化为结果。本文示例正是document模式——对应 fixture 里"mode": "document"的配置。

UrlExtractionConfig 全部参数

除了Mode,UrlExtractionConfig(C# 侧见 UrlExtractionConfig.cs,Rust 侧见 types.rs)还支持以下参数,完整 JSON 形态如下:

{ "mode": "document", "crawl": { }, "document_url_pattern": null, "max_document_urls_per_result": 100, "max_total_urls": 1000, "allow_local_file_inputs": true, "allow_file_uris": true }

各字段含义与默认值:

字段类型默认值说明
modeUrlExtractionModeauto上文所述的抓取模式
crawlCrawlConfig内置默认策略底层 crawlberg 的爬取配置,含max_depth、max_pages、max_concurrent、request_timeout_ms、rate_limit_ms等
document_url_patternstring?null对文档中发现 URL 的可选正则过滤
max_document_urls_per_resultuint?100每个提取结果最多跟随的 URL 数
max_total_urlsuint?1000整次提取调用全局最多跟随的 URL 数
allow_local_file_inputsbooltrue是否允许裸本地文件系统路径输入
allow_file_urisbooltrue是否允许本地file://URI 输入

内置默认 crawl 策略(Rust 侧UrlExtractionConfig::default_xberg_crawl_config())值得特别说明:max_depth: Some(1)、max_pages: Some(100)、max_concurrent: Some(10)、respect_robots_txt: true、soft_http_errors: true、stay_on_domain: true、allow_subdomains: true、document_url_depth: Some(1)。也就是说,即便不显式配置,引擎也会默认遵守 robots.txt、限制爬取深度与并发,并对 HTTP 软错误做宽容处理——这些默认值正是"单页提取默认安全可控"的保障。

底层原理:crawlberg 引擎与批量共享 URL

URL 提取的落地实现位于 crates/xberg/src/engine/extract_impl.rs,整体依赖一个共享的 crawlberg 引擎实例:

  • 单条 URL:ExtractInputKind::Uri分支进入extract_uri_input,先由crawlberg_config(config)把ExtractionConfig.Url.Crawl编译为 crawlberg 的CrawlConfig,随后按模式选择batch_scrape或batch_crawl;
  • 批量 URL 去重共享:当一次extract_batch中多个输入指向同一个 URL 时,引擎会通过run_shared_url_group把同 URL 的输入合并,只发起一次网络请求,再把结果回填到各自输入槽位(positions_for_url映射),既节省请求又保证每个输入都有结果或错误;
  • 超时语义:批量模式下网络抓取由 crawlberg 内部的request_timeout_ms/rate_limit_ms管理,extraction_timeout_secs则约束抓取后的转换(提取)阶段。

抓取完成后返回的ExtractionResult结构(types.rs)包含:

  • results:按发现顺序排列的ExtractedDocument列表;
  • errors:非致命的逐输入错误(ExtractionErrorItem,含稳定错误码、错误类型、来源与消息);
  • summary:聚合统计,包括inputs、results、errors、remote_urls(解析为远程 HTTP(S) 的 URI 数)、pages_crawled(爬取/抓取的 HTML 页数)、documents_downloaded(下载的非 HTML 文档数);
  • crawl_final_urls/crawl_redirect_count/crawl_unique_normalized_urls:重定向最终 URL、重定向次数与去重归一化后的 URL 列表,便于审计爬取轨迹。

从 fixture 看验证方式:mock 服务器与断言

本示例对应 fixture url_html_page_extract.json 展示了官方如何端到端验证"URL 提取"行为:

  • 测试先起一个本地 mock HTTP 服务器,对GET /返回content-type: text/html; charset=utf-8的页面,正文为<html><body><h1>Xberg URL Page</h1><p>HTML extraction through crawlberg.</p></body></html>($mock_url会被替换为 mock 地址);
  • 输入为{"kind": "uri", "uri": "$mock_url"},配置为{"url": {"mode": "document"}};
  • 断言共三条:not_error(调用不报错)、results[0].content包含文本"Xberg URL Page"、results数量至少为 1。

这意味着"URL 提取"的成功标准就是:结果非空、正文包含页面真实文本、且结果数量符合预期。C# 端同样的 e2e 断言可在 e2e/csharp/tests 目录下的测试文件中找到(通过XbergConverter.ExtractAsync+ExtractionConfig.FromJson("{}")的统一调用模式),其余语言绑定(Go、Rust、Java、Python、Node 等)也共享同一套 fixture 与语义。

实战注意事项

  • 本地输入开关:allow_local_file_inputs与allow_file_uris默认均为true,即kind = "uri"时也能直接传本地路径或file://URI。若你的场景只接受远程 URL(如服务端不信任调用方),应显式将这两项设为false。
  • 安全边界:max_document_urls_per_result与max_total_urls是防失控爬取的关键闸门;默认的max_total_urls = 1000已经是跨整次调用的全局上限。批量场景下同 URL 共享引擎的设计也天然避免了重复请求放大。
  • 结果结构:result.Results[0].Content是纯文本/可读正文;如需 Markdown 或 HTML,可在ExtractionConfig中设置output_format为markdown/html(参考ExtractionConfig.OutputFormat与HtmlOptions)。配合pages、keywords、chunking等配置,还能在抓取后直接产出分页文本、关键词或分块结果,适合直接接入 RAG 管道。
  • 异步与依赖:URL 抓取依赖网络栈(tokio 运行时与url-ingestion特性),C# 绑定通过ExtractAsync直接返回Task,调用方按 async/await 使用即可。

相关资源

  • C# 绑定类型定义:UrlExtractionConfig.cs、UrlExtractionMode.cs、ExtractionConfig.cs
  • Rust 核心配置与输入模型:crates/xberg/src/core/config/extraction/types.rs
  • URL 抓取引擎实现:crates/xberg/src/engine/extract_impl.rs
  • 官方 fixture 与断言:fixtures/url/url_html_page_extract.json,同目录下还有url_crawl_linked_pages.json(爬取模式)、url_remote_text_document.json(远程文本文档)、url_gzip_encoded_document.json(gzip 文档)等更多 URL 场景
  • C# 端到端测试:e2e/csharp/tests
  • 后端
  • AI 应用
  • NLP

【免费下载链接】xberg

Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with CLI, REST API, and MCP server.

项目地址:https://gitcode.com/gh_mirrors/kr/xberg
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 19:38:25

LDA主题建模Python实战:从环境配置到参数调优与避坑指南

简介&#xff1a;资源为基于Python的LDA&#xff08;潜在狄利克雷分配&#xff09;主题模型实现代码&#xff0c;面向自然语言处理学习者和文本挖掘开发者&#xff0c;帮助解决主题建模从零实现、环境配置与参数调优的常见问题。内容围绕LDA核心流程展开&#xff0c;涵盖语料库…

作者头像 李华
网站建设 2026/9/28 19:34:52

树莓派多版本Python共存,如何干净卸载指定版本且不影响系统?

刚折腾完树莓派上的Python多版本共存问题&#xff0c;踩了一圈坑之后发现&#xff0c;真正麻烦的不是安装某个版本的Python&#xff0c;而是卸载一个已经被各种依赖“焊死”的指定版本。尤其是在树莓派这种资源紧张的板子上&#xff0c;多个Python版本共存会把环境变量、软链接…

作者头像 李华