RAG数据处理:PDF/HTML

RAG而言用户输入的数据通常是各种各样文档,本文主要采用langchain实现PDF/HTML文档的处理方法

PDF文档解析

PDF文档很常见格式,但内部结构常常较复杂:

  • 复杂的版式布局
  • 多样的元素(段落、表格、公式、图片等)
  • 文本流无法直接获取
  • 特殊元素如页眉页脚、侧边栏

主流分为两类:

  1. 基于规则匹配(实战不常用,效果差)

技巧:转md

在实际应用中,我们经常会遇到这样的情况:

  • PDF文档中的数学公式在导入知识库过程中变成乱码
  • 解析过程极慢,特别是对于包含大量公式的长文档

几乎所有主流大模型都原生支持Markdown格式,它们的输出也多采用Markdown,因此我们可以考虑选择将pdf识别前转为md格式。现在主流方法采用MinerU(star33k)
在这里插入图片描述
在这里插入图片描述

常规电子版解析

pdfplumber 对中文支持较好,且在表格解析方面表现优秀,但对双拦文本的解析能力较差;pdfminer 和 PyMuPDF 对中文支持良好,但表格解析效果较弱;PyPDF2 对英文支持较好,但中文支持较差;papermage集成了pdfminer 和其他工具,特引适合处理论文场景。开发者可以根据实际业务场景的测试结果选择合适的工具odfplumber 或 pdfminer 都是兰不错的选择。

  1. PyMuPDF (fitz):功能强大的PDF解析库,支持文本提取、表格识别和版面分析。

  2. LangChain中的解析器

    • PyMuPDFLoader:基于PyMuPDF的封装,可提取文本和图片
  3. 基于机器视觉的解析工具

    • 深度学习方案:如百度飞桨的PP-Structure、上海AI实验室的MADU
    • 商业解决方案:如PDFPlumber、LlamaIndex的LlamaParse

代码示例

# 使用LangChain的PyMuPDFLoader
from langchain.document_loaders import PyMuPDFLoaderloader = PyMuPDFLoader("example.pdf")
documents = loader.load()# 直接使用PyMuPDF进行高级解析
import fitz  # PyMuPDF# 打开PDF
doc = fitz.open("example.pdf")# 提取所有文本(按页)
for page_num, page in enumerate(doc):text = page.get_text()print(f"页面 {page_num + 1}:\n{text}\n")# 提取表格
for page_num, page in enumerate(doc):tables = page.find_tables()for i, table in enumerate(tables):# 转换为pandas DataFramedf = table.to_pandas()print(f"页面 {page_num + 1}, 表格 {i + 1}:\n{df}\n")# 提取图片
for page_num, page in enumerate(doc):image_list = page.get_images(full=True)for img_index, img in enumerate(image_list):xref = img[0]  # 图片的xref(引用号)image = doc.extract_image(xref)# 可以保存图片或进行进一步处理print(f"页面 {page_num + 1}, 图片 {img_index + 1}: {image['ext']}")

含图片电子版解析

基于深度学习匹配

比规则匹配有更好的效果
Layout-parser、Pp-StructureV2、PDF-Extract-Kit、pix2text、MinerU、 marker

HTML文档解析

HTML是网页的标准标记语言,包含文本、图片、视频等多种内容,通过不同标签组织。

常用解析工具

  1. Beautiful Soup:Python中最常用的HTML解析库,能通过标签和CSS选择器精确提取内容。

  2. LangChain中的解析器

    • WebBaseLoader:结合urllib和Beautiful Soup,先下载HTML再解析
    • BSHTMLLoader:直接解析本地HTML文件

代码示例

# 使用LangChain的WebBaseLoader解析网页
from langchain.document_loaders import WebBaseLoaderloader = WebBaseLoader("https://example.com")
documents = loader.load()# 使用Beautiful Soup定制解析
from bs4 import BeautifulSoup
import requestsresponse = requests.get("https://example.com")
soup = BeautifulSoup(response.text, "html.parser")# 提取所有代码块
code_blocks = soup.find_all("div", class_="highlight")
for block in code_blocks:print(block.get_text())# 提取所有标题和段落
content = []
for heading in soup.find_all(["h1", "h2", "h3"]):content.append({"type": "heading", "text": heading.get_text()})# 获取标题后的段落for p in heading.find_next_siblings("p"):if p.find_next(["h1", "h2", "h3"]) == p:breakcontent.append({"type": "paragraph", "text": p.get_text()})

进阶技巧

对于复杂的HTML页面,可以考虑以下策略:

  • 使用CSS选择器精确定位元素
  • 识别并过滤导航栏、广告等无关内容
  • 保留文档结构(标题层级关系)
  • 特殊处理表格、代码块等结构化内容

基于深度学习的通用文档解析:以DeepDoc为例

传统的解析方法各有局限,近年来基于深度学习的文档解析技术取得了突破性进展。DeepDoc(来自RapidocAI)是一个典型代表,它采用机器视觉方式解析文档。

DeepDoc的工作流程

  1. 文档转图像:将PDF等文档转换为图像
  2. OCR文本识别:识别图像中的文本内容
  3. 布局分析:使用专门模型识别文档布局结构
  4. 表格识别与解析:使用TSR(Table Structure Recognition)模型解析表格
  5. 内容整合:将识别的各部分内容整合成结构化数据

代码示例

# 使用DeepDoc进行文档解析
from rapidocr import RapidOCR
from deepdoc import LayoutAnalyzer, TableStructureRecognizer# 初始化模型
ocr = RapidOCR()
layout_analyzer = LayoutAnalyzer()
table_recognizer = TableStructureRecognizer()# 文档OCR
image_path = "document.png"  # 可以是PDF转换的图像
ocr_result = ocr.recognize(image_path)
texts, positions = ocr_result# 布局分析
layout_result = layout_analyzer.analyze(image_path)
# 识别出的布局元素:标题、段落、表格、图片等
elements = layout_result["elements"]# 处理识别到的表格
for element in elements:if element["type"] == "table":table_image = element["image"]# 表格结构识别table_result = table_recognizer.recognize(table_image)# 表格数据可转换为CSV或DataFrametable_data = table_result["data"]# 整合所有内容
document_content = []
for element in sorted(elements, key=lambda x: x["position"]):if element["type"] == "title":document_content.append({"type": "title", "text": element["text"]})elif element["type"] == "paragraph":document_content.append({"type": "paragraph", "text": element["text"]})elif element["type"] == "table":document_content.append({"type": "table", "data": element["table_data"]})# 其他类型元素...

DeepDoc的优势

  • 多格式支持:可处理PDF、Word、Excel、PPT、HTML等多种格式
  • 结构保留:准确识别文档的层次结构和布局
  • 表格处理:精确解析复杂表格,包括合并单元格
  • 图像处理:可提取和关联文档中的图像内容
  • 多语言支持:支持中英文等多种语言的文档解析

通用文档解析:Unstructured库

对于需要处理多种文档格式但又不想为每种格式单独编写解析代码的场景,Unstructured库提供了统一的解决方案。

Unstructured的工作原理

Unstructured可自动识别文件格式,并调用相应的解析器提取内容,支持多种常见文档格式。

代码示例

from unstructured.partition.auto import partition# 自动识别文件格式并解析
elements = partition("document.pdf")  # 也可以是docx, pptx, html等# 提取所有文本元素
text_elements = [el for el in elements if hasattr(el, "text")]
for element in text_elements:print(element.text)# 根据元素类型处理
from unstructured.partition.html import partition_html
from unstructured.chunking.title import chunk_by_title# HTML特定解析
html_elements = partition_html("document.html")# 按标题分块
chunks = chunk_by_title(elements)
for chunk in chunks:print(f"标题: {chunk.title}")print(f"内容: {chunk.text}")

构建文档处理管道

在实际的RAG系统中,我们通常需要构建完整的文档处理管道,将解析、清洗、分块等步骤串联起来。

完整处理流程示例

import os
from typing import List, Dict, Any
from langchain.document_loaders import PyMuPDFLoader, WebBaseLoader, UnstructuredExcelLoader
from langchain.text_splitter import RecursiveCharacterTextSplitterdef process_document(file_path: str) -> List[Dict[str, Any]]:"""处理各种格式的文档,返回标准化的文档块"""# 根据文件扩展名选择合适的加载器ext = os.path.splitext(file_path)[1].lower()if ext == ".pdf":loader = PyMuPDFLoader(file_path)elif ext == ".html" or ext == ".htm":# 假设是本地HTML文件with open(file_path, "r", encoding="utf-8") as f:content = f.read()loader = WebBaseLoader(file_path)elif ext in [".xlsx", ".xls"]:loader = UnstructuredExcelLoader(file_path)else:# 对于其他格式,使用Unstructuredfrom langchain.document_loaders import UnstructuredFileLoaderloader = UnstructuredFileLoader(file_path)# 加载文档documents = loader.load()# 文本清洗(去除多余空格、特殊字符等)cleaned_documents = []for doc in documents:text = doc.page_content# 基本清洗text = text.replace("\n\n", " ").replace("\t", " ")text = ' '.join(text.split())  # 规范化空格# 更新文档doc.page_content = textcleaned_documents.append(doc)# 文本分块text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200,separators=["\n\n", "\n", ". ", " ", ""])chunks = text_splitter.split_documents(cleaned_documents)# 转换为标准格式processed_chunks = []for chunk in chunks:processed_chunks.append({"text": chunk.page_content,"metadata": chunk.metadata,"source": file_path,"chunk_id": f"{os.path.basename(file_path)}_{chunks.index(chunk)}"})return processed_chunks# 使用示例
pdf_chunks = process_document("example.pdf")
html_chunks = process_document("example.html")
excel_chunks = process_document("example.xlsx")# 合并所有文档的处理结果
all_chunks = pdf_chunks + html_chunks + excel_chunks# 现在可以将这些块用于向量化和索引

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/83449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时源芯微| KY键盘接口静电浪涌防护方案

KY键盘接口静电浪涌防护方案通过集成ESD保护元件、电阻和连接键,形成了一道有效的防护屏障。当键盘接口受到静电放电或其他浪涌冲击时,该方案能够迅速将过电压和过电流引导至地,从而保护后续电路免受损害。 ESD保护元件是方案中的核心部分&a…

Java 原生网络编程(BIO | NIO | Reactor 模式)

1、基本常识 Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,是一组接口,使用了门面模式对应用层隐藏了传输层以下的实现细节。TCP 用主机的 IP 地址加上主机端口号作为 TCP 连接的端点,该端点叫做套接字 Socket。 比如三次握手&…

OpenCV透视变换

概念 OpenCV 透视变换是将图像从一个视平面投影到另一个视平面的过程,也叫投影映射 ,属于空间立体三维变换。它基于透视原理,通过 33 的变换矩阵作用于图像像素坐标来实现映射转换 ,能模拟人眼或相机镜头观看三维空间物体时的透视…

STM32F103定时器1每毫秒中断一次

定时器溢出中断,在程序设计中经常用到。在使用TIM1和TIM8溢出中断时,需要注意“TIM_TimeBaseStructure.TIM_RepetitionCounter0;”,它表示溢出一次,并可以设置中断标志位。 TIM1_Interrupt_Initializtion(1000,72); //当arr1…

数据库——SQL约束窗口函数介绍

4.SQL约束介绍 (1)主键约束 A、基本内容 基本内容 p r i m a r y primary primary k e y key key约束唯一表示数据库中的每条记录主键必须包含唯一的值(UNIQUE)主键不能包含NULL值(NOT NULL)每个表都应…

【typenum】 8 常量文件(consts.rs)

一、源码 这段代码通过类型级编程(type-level programming)在编译期实现数值计算。以下是常量定义部分: // THIS IS GENERATED CODE #![allow(missing_docs)] use crate::int::{NInt, PInt}; /** Type aliases for many constants.This fil…

第8讲、Multi-Head Attention 的核心机制与实现细节

🤔 为什么要有 Multi-Head Attention? 单个 Attention 机制虽然可以捕捉句子中不同词之间的关系,但它只能关注一种角度或模式。 Multi-Head 的作用是: 多个头 多个视角同时观察序列的不同关系。 例如: 一个头可能专…

百度智能云千帆携手联想,共创MCP生态宇宙

5月7日,2025联想创新科技大会(Tech World)在上海世博中心举行,本届大会以“让AI成为创新生产力”为主题。会上,联想集团董事长兼CEO杨元庆展示了包括覆盖全场景的超级智能体矩阵,包括个人超级智能体、企业超…

【OpenCV】帧差法、级联分类器、透视变换

一、帧差法(移动目标识别): 好处:开销小,不怎么消耗CPU的算力,对硬件要求不高,但只适合固定摄像头 1、优点 计算效率高,硬件要求 响应速度快,实时性强 直接利用连续帧…

数据库迁移的艺术:团队协作中的冲突预防与解决之道

title: 数据库迁移的艺术:团队协作中的冲突预防与解决之道 date: 2025/05/17 00:13:50 updated: 2025/05/17 00:13:50 author: cmdragon excerpt: 在团队协作中,数据库迁移脚本冲突是常见问题。通过Alembic工具,可以有效地管理和解决这些冲突。冲突预防的四原则包括功能分…

Linux常用命令43——bunzip2解压缩bz2文件

在使用Linux或macOS日常开发中,熟悉一些基本的命令有助于提高工作效率,bunzip2可解压缩.bz2格式的压缩文件。bunzip2实际上是bzip2的符号连接,执行bunzip2与bzip2 -d的效果相同。本篇学习记录bunzip2命令的基本使用。 首先查看帮助文档&#…

盲盒:拆开未知的惊喜,收藏生活的仪式感

一、什么是盲盒?—— 一场关于“未知”的浪漫冒险 盲盒,是一种充满神秘感的消费体验: 🎁 盒中藏惊喜——每个盲盒外观相同,但内含随机商品,可能是普通款、稀有款,甚至是“隐藏款”;…

Android 中使用通知(Kotlin 版)

1. 前置条件 Android Studio:确保使用最新版本(2023.3.1)目标 API:最低 API 21,兼容 Android 8.0(渠道)和 13(权限)依赖库:使用 WorkManager 和 Notificatio…

使用大模型预测急性结石性疾病技术方案

目录 1. 数据预处理与特征工程伪代码 - 数据清洗与特征处理数据预处理流程图2. 大模型构建与训练伪代码 - 模型训练模型训练流程图3. 术前预测系统伪代码 - 术前风险评估术前预测流程图4. 术中实时调整系统伪代码 - 术中风险预警术中调整流程图5. 术后护理系统伪代码 - 并发症预…

每日Prompt:生成自拍照

提示词 帮我生成一张图片:图片风格为「人像摄影」,请你画一张及其平凡无奇的iPhone对镜自拍照,主角是穿着JK风格cos服的可爱女孩,在自己精心布置的可按风格的房间内的落地镜前用后置摄像头随手一拍的快照。照片开启了闪光灯&…

动态规划-64.最小路径和-力扣(LetCode)

一、题目解析 从左上角到右下角使得数字总和最小且只能向下或向右移动 二、算法原理 1.状态表示 我们需要求到达[i,j]位置时数字总和的最小值,所以dp[i][j]表示:到达[i,j]位置时,路径数字总和的最小值。 2.状态转移方程 到达[i,j]之前要先…

LeetCode LCR 010 和为 K 的子数组 (Java)

两种解法详解:暴力枚举与前缀和哈希表寻找和为k的子数组 在解决数组中和为k的连续子数组个数的问题时,我们可以采用不同的方法。本文将详细解析两种常见的解法:暴力枚举法和前缀和结合哈希表的方法,分析它们的思路、优缺点及适用…

OpenVLA (2) 机器人环境和环境数据

文章目录 [TOC](文章目录) 前言1 BridgeData V21.1 概述1.2 硬件环境 2 数据集2.1 场景与结构2.2 数据结构2.2.1 images02.2.2 obs_dict.pkl2.2.3 policy_out.pkl 3 close question3.1 英伟达环境3.2 LIBERO 环境更适合仿真3.3 4090 运行问题 前言 按照笔者之前的行业经验, 数…

深度学习(第3章——亚像素卷积和可形变卷积)

前言: 本章介绍了计算机识别超分领域和目标检测领域中常常使用的两种卷积变体,亚像素卷积(Subpixel Convolution)和可形变卷积(Deformable Convolution),并给出对应pytorch的使用。 亚像素卷积…

大模型在腰椎间盘突出症预测与治疗方案制定中的应用研究

目录 一、引言 1.1 研究背景 1.2 研究目的与意义 二、腰椎间盘突出症概述 2.1 定义与病因 2.2 症状与诊断方法 2.3 治疗方法概述 三、大模型技术原理与应用基础 3.1 大模型的基本原理 3.2 大模型在医疗领域的应用现状 3.3 用于腰椎间盘突出症预测的可行性分析 四、…