☰
在 Kotlin/Android 中提取远程文本文档:Xberg URL 提取实战指南
2026/10/8 7:54:36 网站建设 项目流程
  • 后端
  • 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
点击查看免费下载

本文以 Kotlin (Android) 绑定为视角,完整讲解如何通过Xberg.extract()从 HTTP(S) URL 提取远程纯文本文档内容。你将掌握ExtractInput/ExtractionConfig的 JSON 序列化方式、mode: "document"单文档模式与ssrf安全策略的用法,以及如何从返回结果中读取正文内容与remoteUrls统计信息——并借助仓库中的 e2e 测试与 fixture 逐层印证每个细节。

场景概览:让 App 直接消费远程文档

在移动端或后端服务中,常会遇到"给定一个 URL,需要把链接指向的文档正文提取出来"的需求:可能是抓取一份远程.txt说明、一个纯文本配置、或任意由text/plain提供的文档资源。Xberg 的 Kotlin (Android) 绑定将这一过程收敛为一次Xberg.extract(input, config)调用:输入侧用ExtractInput描述"我要提取哪个 URI",配置侧用ExtractionConfig描述"按何种模式与安全策略执行",返回结果中同时给出正文内容与远程资源统计,适合直接接入协程化的 Android 业务代码。

核心代码走读

关联文档 url_remote_text_document.md 给出了一个可直接运行的完整示例:

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\":{\"ssrf\":{}},\"mode\":\"document\"}}", ExtractionConfig::class.java) val result = Xberg.extract(input, config) println(result.results.first().content) println(result.summary.remoteUrls) }

这段代码的四个关键动作值得逐一拆解:

  1. 构建 Jackson ObjectMapper:绑定层生成的 Kotlin 数据类(如ExtractInput、ExtractionConfig)与底层 Rust 服务之间通过 JSON 交换数据,且字段采用 snake_case 命名。因此必须调用setPropertyNamingStrategy(SNAKE_CASE),否则kind/uri等字段的序列化会与原生端失配。
  2. 构造输入:{"kind":"uri","uri":"https://example.com"}反序列化为ExtractInput,声明本次提取的来源是 URI。
  3. 构造配置:{"url":{"crawl":{"ssrf":{}},"mode":"document"}}反序列化为ExtractionConfig,指定 URL 提取以"单文档模式"执行,并携带默认 SSRF 安全策略。
  4. 执行并读取结果:Xberg.extract()返回ExtractResult,正文位于results.first().content,远程文档统计位于summary.remoteUrls。

ExtractInput:用 URI 声明提取来源

ExtractInput是"所有公开提取入口的统一输入结构",其定义见 ExtractInput.kt:

data class ExtractInput( val kind: ExtractInputKind = ExtractInputKind.URI, // bytes 需配 bytes;uri 需配 uri val bytes: ByteArray? = null, val uri: String? = null, // 本地路径、file:// URI 或 HTTP(S) URL val mimeType: String? = null, // MIME 类型提示 val filename: String? = null, // 用于 MIME 检测与元数据的文件名提示 val config: FileExtractionConfig? = null, // 单输入级提取覆盖 )

在远程文本文档场景中,kind固定为uri,uri字段填写完整 HTTP(S) 地址。值得留意的是kind的默认值就是URI,因此{"uri":"https://example.com"}这种省略kind的写法同样合法;但显式声明kind更利于代码可读性。mimeType与filename在此场景属于可选提示字段——当远端响应头未给出明确Content-Type时,它们能帮助 MIME 推断更准确。

ExtractionConfig:URL 模式的配置骨架

主配置结构ExtractionConfig承载了提取流程的全部选项(OCR、缓存、质量后处理、分块等),见 ExtractionConfig.kt。其中与 URL 提取直接相关的是顶层url子配置,文档示例给出的是最精简的可用形态:

{ "url": { "crawl": { "ssrf": {} }, "mode": "document" } }

mode:单文档模式与爬取模式

mode: "document"表示"仅提取起始 URL 指向的那一个文档",不跟随链接扩散。与之相对的mode: "crawl"则会把目标当作站点入口进行遍历。e2e 测试 UrlTest.kt 展示了 crawl 模式的最小形态:配置{"url":{"crawl":{"max_depth":1,"max_pages":4,"respect_robots_txt":false,"ssrf":{}},"mode":"crawl"}}后,结果会携带summary.pagesCrawled统计,且results中会出现多个条目。如果你的诉求只是"拿下一个远程文档的正文",mode: "document"是最贴合、开销最小的选择。

crawl 子配置:为什么示例必须带上crawl

即便使用mode: "document",示例仍保留了"crawl": {"ssrf": {}}。原因在于 URL 提取的取数逻辑(HTTP 抓取、重定向、文档下载上限等)统一收敛在 crawl 配置下。从 CrawlConfig.kt 可以看到该结构覆盖了丰富的行为参数,例如:

  • requestTimeout:单次 HTTP 请求超时,默认 30000ms;
  • maxRedirects:最大重定向次数,默认 10;
  • retryCount/retryCodes/retryInitialDelayMs/retryMaxDelayMs:失败重试与指数退避策略;
  • maxBodySize:响应体上限,未显式设置时存在 100 MiB 的安全兜底上限;
  • downloadDocuments:是否下载非 HTML 文档(PDF、DOCX、图片等),默认true;
  • documentMaxSize:文档下载大小上限,默认 50 MB;
  • userAgent/userAgents:自定义 UA 或轮换列表;
  • cookiesEnabled、proxy、customHeaders等:会话与代理相关能力。

在单文档模式下,这些字段多数沿用默认值即可;显式提供crawl块的主要目的,是把ssrf安全策略带进配置。

ssrf:默认即安全的出站策略

ssrf: {}表示采用默认的 SSRF 策略。根据 CrawlConfig.kt 的文档说明,默认策略为:拒绝访问私网地址、仅允许 http/https 协议、最多跟随 5 次重定向。这是服务端场景的重要防线——避免恶意 URL 把提取引擎当作代理去打内网地址。e2e 测试套件在companion object中通过System.setProperty("CRAWLBERG_ALLOW_PRIVATE_NETWORK", "true")放宽该限制(UrlTest.kt),因为其 mock 服务器运行在本地;你在真实业务中不应照搬这一放宽,默认的私网拒绝策略才是生产环境的正确选择。

结果解读:正文与远程资源统计

Xberg.extract()的返回值中,本次示例用到两个字段:

  • result.results.first().content:第一个(也是 document 模式下唯一的)提取结果的正文字段。对纯文本文档而言,content即文档正文本身。
  • result.summary.remoteUrls:本次提取过程中实际访问的远程资源数量。e2e 测试断言其等于1(UrlTest.kt),恰好印证"单文档模式只拉取一个远程文档"这一行为——如果起始页面还引用了图片、CSS 等资源,该计数会相应增加,可作为观测提取副作用规模的指标。

从 fixture 到 e2e:源码级证据链

仓库中围绕该场景提供了一条完整的证据链:

  1. fixture 定义:url_remote_text_document.json 声明了本用例的输入、配置与断言:mock 服务器对GET /返回200、Content-Type: text/plain; charset=utf-8、正文为Remote document hello from Xberg URL e2e.;输入为{"kind":"uri","uri":"$mock_url"};配置为{"url":{"mode":"document"}};断言"不报错、正文包含Remote document hello、summary.remote_urls等于 1"。
  2. e2e 测试:UrlTest.kt 中的testUrlRemoteTextDocument将上述 fixture 落地为可执行代码,通过系统属性或环境变量注入 mock 服务器地址后调用Xberg.extract并验证正文与统计。
  3. 绑定实现:Xberg单例对象在 Xberg.kt 中完成 Jackson 定制(ByteArray 以无符号字节数组编解码,与 Rust serde 的Vec<u8>对齐)与 JNI 分发,Android 侧通过System.loadLibrary("xberg_jni")加载原生库。

对读者而言,这套证据链意味着:示例代码的行为是有测试背书的,你在集成时可以直接以该测试为模板,把 mock 服务器地址替换为自己的目标 URL。

集成要点与注意事项

  1. 命名策略必须匹配:忘记SNAKE_CASE是这类集成最常见的坑,会导致ExtractInput/ExtractionConfig反序列化出的字段与原生端不一致。
  2. JNI 库加载:Android 环境需要xberg_jni原生库可用(System.loadLibrary),并建议在初始化阶段完成,而非每次提取时重复加载。
  3. 协程环境:示例使用runBlocking包裹,实际业务中应放入Dispatchers.IO或专用调度器,避免阻塞主线程;大量输入可使用Xberg.extractBatch批量处理(同见 UrlTest.kt 的混合批量示例)。
  4. 安全默认值:除非确有内网抓取需求,否则保持默认 SSRF 策略(拒绝私网);如需突破,请评估暴露面,而不是像测试套件那样全局放开。
  5. 文档大小预算:注意maxBodySize(默认 100 MiB 兜底)与documentMaxSize(默认 50 MB)两项限制,超大文档需显式调大或改为流式输出目录(documentOutputDir)。

小结

通过Xberg.extract()提取远程文本文档,在 Kotlin (Android) 绑定中只需"一个输入对象 + 一份 URL 配置 + 一次调用"。本文从示例代码出发,剖析了ExtractInput的 URI 语义、mode: "document"与 crawl 配置的关系、默认 SSRF 策略的含义,以及结果中content与remoteUrls的读取方式,并以仓库中的 fixture 与 e2e 测试作为完整证据链。将该模式推广到 HTML 页面、gzip 编码文档乃至递归文档链接等场景时,只需在同一配置骨架中调整 crawl 字段即可平滑演进。

  • 后端
  • 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
点击查看免费下载
上一篇:GNU Emacs效率提升:节省时间的30个高级技巧
下一篇:eSpeak NG 文本转语音引擎安装和配置指南

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询