当前位置: 首页 > news >正文

创新项目实训-个人博客(一)

一、使用Apache Tika实现数据内容提取

在开发AI应用时,给AI提供简洁有效的数据至关重要,为此必须要对原始数据进行整理。

Apache Tika 是一个开源的文档处理工具,能够自动检测并解析超过 1000 种文件格式,提取元数据和结构化文本内容,广泛应用于搜索引擎索引、内容分析和数据提取领域。我将使用Tika进行数据的清洗工作。

二、Tika 架构概览

Apache Tika 的设计理念是"抽象与解耦"。它本身并不直接处理每一种文件,而是充当一个"中间商",封装了许多专业的底层库(如处理 PDF 的 PDFBox,处理 Office 的 POI)。

Tika 处理流程

  1. Detect(识别类型):输入InputStream→ 通过魔数/内容等判断 MIME 类型(不依赖后缀)
  2. Parse(选择并解析)AutoDetectParser检测到类型后,会把解析请求委派给对应的具体Parser
  3. Handle(输出内容):解析结果以事件流写入ContentHandler,同时把元信息写入Metadata

三、Tika的基础运用

最简单的 Tika 使用方式:

// ❌ 不推荐:简单但有问题 Tika tika = new Tika(); String text = tika.parseToString(inputStream);

问题一:嵌入资源污染

Word 文档中的图片会被提取为文件名引用:

姓名:张三 image1.jpeg ← 简历中的头像图片 image2.png ← 项目截图 工作经验:5年Java开发

问题二:PDF 临时路径

PDF 中的内嵌资源会产生临时文件路径:

技术栈:Java, Spring Boot file:///tmp/apache-tika-123456.html?query=0 ← 临时文件路径 熟悉微服务架构

问题三:无长度限制

恶意文件可能产生超大文本,导致 OOM:

// 默认无限制,大文件可能撑爆内存 String text = tika.parseToString(hugeFile);

优化方案:显式 Parser + Context

针对上述问题,我们采用显式配置的方式:

public class DocumentParseService { private static final int MAX_TEXT_LENGTH = 5 * 1024 * 1024; // 5MB private final TextCleaningService textCleaningService; /** * 核心解析方法:使用显式 Parser + Context 方式解析文档 * * 优化点: * 1. 使用 BodyContentHandler 只提取正文内容 * 2. 禁用 EmbeddedDocumentExtractor,不解析嵌入资源(图片、附件) * 3. 配置 PDFParserConfig,关闭图片和注释提取 * 4. 显式指定 Parser 到 Context,增强健壮性 */ private String parseContent(InputStream inputStream) throws IOException, TikaException, SAXException { // ========== 1. 创建解析器 ========== AutoDetectParser parser = new AutoDetectParser(); // ========== 2. 创建内容处理器 ========== // BodyContentHandler:只提取正文,忽略元数据 // 参数 MAX_TEXT_LENGTH:限制最大文本长度,防止 OOM BodyContentHandler handler = new BodyContentHandler(MAX_TEXT_LENGTH); // ========== 3. 创建元数据容器 ========== Metadata metadata = new Metadata(); // ========== 4. 创建解析上下文 ========== ParseContext context = new ParseContext(); // 🔑 关键配置 1:将 Parser 注册到 Context // 某些解析器需要递归调用自己处理嵌套文档 context.set(Parser.class, parser); // 🔑 关键配置 2:禁用嵌入文档提取 // 这是解决"图片引用污染"的关键! context.set(EmbeddedDocumentExtractor.class, new NoOpEmbeddedDocumentExtractor()); // 🔑 关键配置 3:PDF 专用配置 PDFParserConfig pdfConfig = new PDFParserConfig(); pdfConfig.setExtractInlineImages(false); // 不提取内嵌图片 // 注意:Tika 2.9.2 中 setExtractAnnotations 方法可能不存在,关闭图片提取已足够 context.set(PDFParserConfig.class, pdfConfig); // ========== 5. 执行解析 ========== parser.parse(inputStream, handler, metadata, context); // ========== 6. 文本清理 ========== return textCleaningService.cleanText(handler.toString()); } }

NoOpEmbeddedDocumentExtractor 详解

这是解决嵌入资源污染的核心类:

public class NoOpEmbeddedDocumentExtractor implements EmbeddedDocumentExtractor { /** * 是否应该解析嵌入文档 */ @Override public boolean shouldParseEmbedded(Metadata metadata) { // 记录跳过的嵌入文档(使用字符串常量,兼容不同 Tika 版本) String resourceName = metadata.get("resourceName"); if (resourceName != null) { log.debug("Skip embedded document: {}", resourceName); } return false; } /** * 解析嵌入文档(空实现) */ @Override public void parseEmbedded(InputStream stream, ContentHandler handler, Metadata metadata, boolean outputHtml) { // 空实现,不执行任何操作 // 由于 shouldParseEmbedded 返回 false,此方法不会被调用 } }

工作原理

Tika 在解析过程中会调用EmbeddedDocumentExtractor接口:

  1. shouldParseEmbedded()- 询问是否要处理嵌入资源(返回 false 直接跳过)
  2. parseEmbedded()- 实际处理嵌入资源(因上一步返回 false 不会被调用)

哪些资源会被跳过?

文档类型

嵌入资源示例

默认行为

使用 NoOp 后

Word (DOCX)

图片、图表、OLE 对象

输出image1.jpeg

跳过

PDF

内嵌图片、附件

输出临时路径

跳过

Excel

嵌入图表、图片

输出引用

跳过

PPT

幻灯片图片

输出文件名

跳过

ContentHandler 的选择

Tika 提供多种ContentHandler,适用不同场景:

// 1. BodyContentHandler - 只提取正文(推荐用于简历) BodyContentHandler bodyHandler = new BodyContentHandler(maxLength); // 2. ToXMLContentHandler - 输出 XML 格式(保留结构) ToXMLContentHandler xmlHandler = new ToXMLContentHandler(); // 3. WriteOutContentHandler - 直接写入 Writer WriteOutContentHandler writerHandler = new WriteOutContentHandler(writer); // 4. 默认 ContentHandler - 提取所有内容(包括元数据) ContentHandler defaultHandler = new DefaultHandler();

我们这里选择BodyContentHandler

解析效果对比

原始简历(Word 格式)

  • 包含头像图片
  • 包含项目截图
  • 包含分隔线

默认解析结果

image1.jpeg 张三 联系方式:138xxxx1234 image2.png image3.jpeg --- 工作经验 XXX 公司 - 高级工程师 file:///tmp/tika-123.html?query=0 负责系统架构设计

优化后解析结果

张三 联系方式:138xxxx1234 工作经验 XXX 公司 - 高级工程师 负责系统架构设计
http://www.jsqmd.com/news/710882/

相关文章:

  • 告别命令行恐惧:在Qt Creator里可视化操作Git,轻松管理你的Gitee仓库
  • 《从反复返工到一次成型:QClaw长任务精准执行指南》
  • 和做工厂系统的印尼老哥,复刻了一套属于 MicroPython 的包管理系统
  • 后续技术路线预告:MyBatisPlus + Redis 专栏开启,业务落地全覆盖
  • VS Code Copilot Next 高级工作流配置:7步构建零手动干预的CI/CD就绪开发环境
  • 别再被行尾符搞崩溃了!Windows/Mac/Linux三平台协作,用git config core.autocrlf input一劳永逸
  • YOLOv5在甲状腺结节超声分割中的实践与优化
  • 作弊行为检测数据集分享(适用于目标检测任务已划分)
  • Nginx反向代理和负载均衡
  • 5分钟解锁虚幻引擎游戏资源宝库:FModel新手完整指南
  • Kevin的算法笔记(2)栈和队列①
  • 第四十三周周报
  • GESP学习考试必读((一)、《粗心怪其实是“漏洞怪”》)
  • 手把手教你用Python生成COE文件,为FPGA以太网通信初始化MAC地址
  • 告别Inspect!用微软官方推荐的Accessibility Insights搞定WinApp自动化测试元素定位
  • 别再乱用get_event_loop了!深入Python asyncio源码,看透事件循环的线程隔离机制
  • 自回归生成图像检测:D3QE方法解析与应用
  • FanControl深度解析:如何通过Windows开源工具实现精准风扇控制
  • DeepSeek总结的数据库外部表
  • STM32物联网云监控智能报警器(MQ-2烟雾/火焰/DHT11温湿度/红外)
  • Qt项目构建进阶:从.pro到.pri,详解那些藏在qmake里的‘黑魔法’与避坑指南
  • 保姆级教程:用YOLOv8/RT-DETR实现工地安全帽检测与人员追踪(附完整代码)
  • Docker镜像拉取总失败?除了换源,试试搭建自己的私有镜像缓存仓库(Harbor实战)
  • LLM分类器架构与特征工程实践对比
  • 2026年国内GEO行业入局指南:主流服务商实力解析与代理合作全攻略 - GEO优化
  • 仅剩48小时!Docker官方认证AI工程师考试大纲已同步更新至v2026.1,附赠3套高仿真模考卷(含动态权重评分系统)
  • C#面向对象
  • 如何快速掌握SubFinder字幕查找器:新手终极实战指南
  • 苍穹外卖订单状态流转设计:从下单到完成的全链路解析
  • 3步终极指南:免费开源工具G-Helper快速解决华硕笔记本性能瓶颈