在 Kotlin(Android)中使用 Xberg 递归提取 URL 文档链接

发布时间:2026/10/8 1:25:52
在 Kotlin(Android)中使用 Xberg 递归提取 URL 文档链接 后端AI 应用NLP【免费下载链接】xbergPolyglot 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点击查看免费下载递归 URL 提取recursive URL extraction是 Xberg URL 摄取能力中的一项进阶特性当以document模式抓取一个网页时引擎会从提取结果中发现的文档链接PDF、TXT、DOCX 等继续向下抽取形成一条网页 → 文档 → 文档内链接 → …的递归链路。本文以 url_recursive_document_urls.md 中的 KotlinAndroid示例为主线讲解如何用Xberg.extract打开递归文档链接抓取、如何通过CrawlConfig.follow_document_urls与document_url_depth控制递归深度与边界并结合仓库源码说明其底层实现原理。读完本文你将能在自己的 Android/JVM 工程中直接落地一个 URL 一次调用、递归收获整条文档链的提取方案。说明文中的 Kotlin 示例来自 alef 自动生成的 e2e 夹具fixture其完整定义位于 url_recursive_document_urls.json对应的端到端测试用例见 UrlTest.kt。场景一次调用拿到页面 文档链官方夹具对这条特性的一句话概括是extract: recursive URL extraction follows document links discovered in results翻译过来即递归 URL 提取会跟随提取结果中发现的文档链接。典型使用场景是一个 HTML 首页上列出了一批下载链接.pdf、.txt、.docx…你想把首页正文和所有链接指向的文档内容一并提取出来一个文档如 PDF内部又引用了其他文档需要沿引用链继续抓取站点资源分散在不同 CDN 域名上文档链接默认允许跨主机跟随见下文stay_on_domain的说明。在 Xberg 中这不需要写任何爬虫循环——document模式加上递归开关即可引擎内部会自动把结果中发现的新 URL重新投喂给提取管线。完整可运行的 KotlinAndroid示例夹具生成的 Kotlin 代码形态如下它同时演示了 Jacksonsnake_case反序列化、ExtractInput与ExtractionConfig的 JSON 构造以及Xberg.extract的调用与结果访问import io.xberg.* import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper fun main() kotlinx.coroutines.runBlocking { val mapper jacksonObjectMapper().setPropertyNamingStrategy(com.fasterxml.jackson.databind.PropertyNamingStrategies.SNAKE_CASE) val input mapper.readValue({\kind\:\uri\,\uri\:\https://example.com\}, ExtractInput::class.java) val config mapper.readValue({\url\:{\crawl\:{\document_url_depth\:1,\follow_document_urls\:true,\respect_robots_txt\:false,\ssrf\:{}},\mode\:\document\}}, ExtractionConfig::class.java) val result Xberg.extract(input, config) println(result.results) println(result.results.get(1).content) }逐段拆解ExtractInput输入{kind:uri,uri:https://example.com}表示本次输入是一个 HTTP(S) URI。在 Kotlin 绑定中它对应 ExtractInput.kt 的ExtractInput(kind ExtractInputKind.URI, uri ...)与本地路径、file://URI 一样共用Xberg.extract入口。ExtractionConfig配置核心是url段——mode document告诉引擎把种子 URL 当作一个远程文档/页面来抓取而不是站点级crawlcrawl段内打开递归文档链接的两个开关见下节。Xberg.extract(input, config)同步阻塞调用返回ExtractionResult。由于递归开启results不再是单元素results.get(1)取到的是递归抓取到的第二个文档。Jackson 注意点Kotlin 绑定通过 JNI 与 Rust 核心通信使用 snake_case 命名策略保证 JSON 字段与 Rust serde 的 wire 格式一致runBlocking说明该绑定是协程友好的。夹具背后的断言怎么验证它真的递归了同一 fixture 在 url_recursive_document_urls.json 中给出了服务端 mock 与断言mock 服务返回一个 HTML 首页内含链接linked.txt/→htmlbodyh1Recursive source/h1a href/linked.txtLinked document/a/body/html/linked.txt→Recursive document target reached by Xberg.\n断言count_min(results) 2只有递归真正发生了才会产生第 2 个 result断言results[1].content包含Recursive document target验证第二个结果确实是顺着链接抓到的文档内容。对应地端到端测试 UrlTest.kt 中的testUrlRecursiveDocumentUrls()把上面的 JSON 原样搬进 Kotlin 测试并在本地起 mock server 后运行同样的断言。这套fixture → 生成代码 → e2e 测试的链路正是仓库中验证递归文档提取行为的方式。递归文档链接的配置项详解递归行为由CrawlConfig上的两个字段控制在 Kotlin 绑定中位于 CrawlConfig.kt与它们配合的还有UrlExtractionConfig的若干边界参数见 UrlExtractionConfig.kt。follow_document_urls总开关默认false/** Re-enqueue discovered LinkType.Document URLs into the crawl frontier so * the crawl follows links *from* document pages (PDFs, etc.) as it would * from HTML pages. Default: false (documents terminate at materialisation). */ val followDocumentUrls: Boolean false默认关闭时文档在物化下载并提取后就终结了——不会继续跟随文档内部发现的链接。置为true后提取结果里发现的文档链接会被重新入队re-enqueue到抓取前沿文档页和 HTML 页一样可以产生后续跳转。document_url_depth文档链深度默认继承max_depth/** Maximum document-depth (from the seed URL through document links only) * when follow_document_urls is true. null means inherit max_depth. * Independent of max_depth: a document URL is enqueued only if BOTH the * outer max_depth and (if set) document_url_depth permit it. */ val documentUrlDepth: Int? null注意两点关键语义独立于max_depthmax_depth是页面链接跳数document_url_depth是仅沿文档链接走的跳数二者是**与AND**关系——一个文档 URL 只有在外层max_depth和若设置的document_url_depth同时放行时才会被入队null时继承max_depth的值夹具里显式设为1即只沿文档链接追一层。递归边界与安全兜底递归不是无界的UrlExtractionConfig提供了两道上限默认值见 types.rs 中UrlExtractionConfig::default参数默认值作用document_url_patternNone正则过滤器只允许匹配到的文档 URL 被跟随max_document_urls_per_result100单个提取结果最多跟随的 URL 数max_total_urls1000整个提取调用累计跟随的 URL 总数上限此外种子域名约束stay_on_domain/allow_subdomains对文档链接的默认行为是页面链接始终限定在种子域名及其子域内文档链接却默认允许跨主机——因为文档常托管在 CDN 或对象存储上只有当你显式把stay_on_domain置为true时才要求文档也必须落在种子域名内见 CrawlConfig.kt 的注释说明。示例中的respect_robots_txt与ssrf夹具配置里还有两项respect_robots_txt: false测试场景为快速抓取 mock 服务临时关闭 robots.txt 约束。生产环境抓取不受信任的站点时官方指南建议保持respect_robots_txt与stay_on_domain开启并显式设置max_pages/max_total_urls上限ssrf: {}空对象即使用默认 SSRF 策略——拒绝私有/内网地址、仅允许 http/https、最多 5 次重定向。Kotlin 端对应SsrfPolicy见 SsrfPolicy.kt默认deny_private true。抓取用户提供的 URL 属于 SSRF 攻击面务必保留该策略。底层实现递归链路在 Rust 核心中的样子递归文档链接的发动机在 extract_impl.rs 的follow_recursive_document_urlsL1670-L1717与enqueue_discovered_urlsL1719-L1744两个函数中逻辑清晰可读follow_recursive_document_urls ├─ follow_document_urls(config)? // 总开关关闭则直接返回 ├─ document_url_depth(config) 0? // 深度为 0 同样直接返回 ├─ 编译 document_url_pattern 正则非法正则 → validation 错误 ├─ enqueue_discovered_urls(初始结果, depth1) // 首次入队 └─ while 队列非空: ├─ 以 ExtractInput::from_uri(uri) 递归调用 extract_one() ├─ depth max_depth 时再次 enqueue_discovered_urls(depth1) ├─ 累加 remote_urls / pages_crawled / documents_downloaded └─ results / errors 追加进总输出几个值得注意的实现细节URL 从哪里来urls_from_result每个ExtractedDocument结果中uris里Hyperlink/Reference/Citation三类 URI 会被收集同时正文content里出现的https?://文本也会被正则扫描出来末尾标点会被 trim。也就是说无论是结构化的链接元数据还是纯文本里的 URL都能进入递归队列。跟随条件should_follow_discovered_url必须是http/https协议若有document_url_pattern则必须匹配若stay_on_domain开启则主机必须属于种子域名或allow_subdomains时其子域。去重与上限seen集合去重命中max_total_urls默认 1000即停止入队每个结果最多取max_document_urls_per_result默认 100个链接。深度语义document_url_depth(config)在未显式设置时回退到crawl.max_depth再回退到默认 1见 L1802-L1817。结果顺序递归抓到的文档按遍历顺序追加在初始结果之后这正解释了示例中results.get(1)能拿到第二个文档。这段实现同时服务于extract的多种路径L177/L385/L514 三处调用点即无论走哪种 URL 摄取分支递归逻辑都是同一份。在 Android 工程中落地把示例接入真实 Android 工程推荐做法是直接使用 Kotlin 数据类构造而非字符串反序列化仓库 packages/kotlin-android/README.md 的 Quick Start 即采用这种风格import io.xberg.* fun extractRecursively(url: String): ExtractionResult { val config ExtractionConfig( url UrlExtractionConfig( mode UrlExtractionMode.DOCUMENT, crawl CrawlConfig( followDocumentUrls true, documentUrlDepth 1, // 仅沿文档链接追一层 respectRobotsTxt true, // 生产环境建议开启 maxPages 50, maxConcurrent 5, ssrf SsrfPolicy(), // 默认拒绝内网地址 ), maxDocumentUrlsPerResult 100, maxTotalUrls 1000, ), ) return Xberg.extract( ExtractInput(kind ExtractInputKind.URI, uri url), config, ) } // 使用results[0] 是种子页面/文档后续元素是递归发现的文档 val output extractRecursively(https://example.com) output.results.forEachIndexed { index, doc - println([$index] ${doc.content.take(200)}) }要点提示JNI 加载e2e 测试套件在companion object中通过System.loadLibrary(xberg_jni)加载本地库并默认开启CRAWLBERG_ALLOW_PRIVATE_NETWORK环境变量以允许测试访问本地 mock server见 UrlTest.kt。生产环境请勿放开内网访问限制依赖版本Kotlin DSL 中声明implementation(io.xberg:xberg-android:1.3.6)即可见 README.md特性前提递归文档链接依赖url-ingestionCargo 特性full构建已包含WASM 目标不提供 URL 摄取能力Android/JVM 不受影响结果语义ExtractionResult信封里results为发现顺序的文档列表errors记录单个输入的非致命错误summary汇总remote_urls/pages_crawled/documents_downloaded等计数见 types.rs可用于在 UI 上展示抓取概况。总结Xberg 的递归文档 URL 提取让你用一次Xberg.extract调用即可页面 文档链一网打尽。打开CrawlConfig.follow_document_urls、用document_url_depth设定文档链深度再用max_document_urls_per_result/max_total_urls/document_url_pattern划定边界即可在 Android 上获得可控、安全、可观测的递归提取能力。仓库内的 fixtureurl_recursive_document_urls.json、自动生成的 Kotlin 示例url_recursive_document_urls.md与端到端测试UrlTest.kt三份材料互相印证是深入理解与二次开发这条特性的最佳入口。赞分享后端AI 应用NLP【免费下载链接】xbergPolyglot 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点击查看免费下载相关推荐使用 C 在 Xberg 中实现递归 URL 文档提取从页面链接一路追到文件内容使用 C 在 Xberg 中实现递归 URL 文档提取从页面链接一路追到文件内容 Xberg 是一个以 Rust 为核心的 Polyglot 文档智能引擎其后端AI 应用NLPxberg 递归 URL 文档提取实战用 follow_document_urls 沿文档链接自动抓取关联资源xberg 递归 URL 文档提取实战用 follow_document_urls 沿文档链接自动抓取关联资源 本篇技术指南聚焦 xberg 的 URL 递归后端AI 应用NLPxberg Dart 实战用 URL 递归提取配置自动跟随文档链接fixture 全解析xberg Dart 实战用 URL 递归提取配置自动跟随文档链接fixture 全解析 本篇指南围绕 xberg 仓库中 Dart 语言的 url_re后端AI 应用NLP上一篇如何快速开发text-generation-inference自定义后端扩展支持新模型的完整指南下一篇毫秒级响应MediaMTX赋能AR/VR的超低延迟流媒体方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考