RAG数据处理:PDF/HTML

RAG而言用户输入的数据通常是各种各样文档,本文主要讲述对比现主流的PDF/HTML文档的处理方法

PDF文档解析

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

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

主流分为两类:

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

一、基于规则的解析

效果较差,不能识别表格。不需GPU。适合文本密集型pdf
知名三方库:

  1. PyPDF2 对英文支持较好,但中文支持较差,不能识别表格
  2. pdfplumber 对中文支持较好,且在表格解析方面表现优秀,但对双拦文本的解析能力较差
  3. papermage集成了pdfminer 和其他工具,特引适合处理论文场景
代码示例-PyMuPDF
# 使用LangChain的PyMuPDFLoader
from langchain.document_loaders import PyMuPDFLoader

loader = 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 DataFrame
        df = 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']}")

二、基于深度学习解析

效果较好主流,主要处理含有非结构化数据。需GPU
知名三方库:

  1. MinerU(star33k)
  2. unstructured(star11k)
代码示例-MinerU
代码示例-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}")

三、基于多模态大模型的PDF处理

效果好但涉及信息泄露风险。无需GPU,适合快速处理少量PDF文件。

HTML文档解析

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

常用解析工具

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

  2. LangChain中的解析器

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

代码示例

# 使用LangChain的WebBaseLoader解析网页
from langchain.document_loaders import WebBaseLoader

loader = WebBaseLoader("https://example.com")
documents = loader.load()

# 使用Beautiful Soup定制解析
from bs4 import BeautifulSoup
import requests

response = 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:
            break
        content.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或DataFrame
        table_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等多种格式
  • 结构保留:准确识别文档的层次结构和布局
  • 表格处理:精确解析复杂表格,包括合并单元格
  • 图像处理:可提取和关联文档中的图像内容
  • 多语言支持:支持中英文等多种语言的文档解析

构建文档处理管道

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

完整处理流程示例

import os
from typing import List, Dict, Any
from langchain.document_loaders import PyMuPDFLoader, WebBaseLoader, UnstructuredExcelLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

def 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:
        # 对于其他格式,使用Unstructured
        from langchain.document_loaders import UnstructuredFileLoader
        loader = 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 = text
        cleaned_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

# 现在可以将这些块用于向量化和索引
<think>嗯,用户想了解或实现RAG架构相关的数据清洗方法。首先,我需要回忆一下RAG的基本概念和相关资料。根据提供的引用,RAG分为不同阶段,核心步骤包括索引、检索和生成。数据清洗应该属于索引阶段的一部分,因为数据预处理对后续的检索效果很关键。 用户需要的是具体的数据清洗方法教程,所以我得先整理RAG数据清洗的常见步骤。可能包括文本规范化、去重、去除噪声、分块、元数据标注、质量评估等。每个步骤需要详细说明,比如文本规范化可能涉及HTML标签去除、大小写转换、拼写检查等。 还要考虑用户可能的实际应用场景,例如处理PDF、网页文本或结构化数据,不同来源的数据清洗方法可能有差异。是否需要推荐工具或库?比如NLTK、Spacy、BeautifulSoup等,这些工具能帮助自动化清洗流程。 另外,用户可能关心数据清洗后的评估方法,比如准确率、召回率,或者人工抽检。需要强调数据清洗对检索效果的影响,确保用户理解其重要性。 最后,生成相关问题时要围绕数据清洗的挑战、工具、评估指标和与检索效果的关系展开,帮助用户深入思考可能遇到的问题。确保回答结构清晰,步骤明确,并引用提供的参考资料来支持内容。</think>### RAG架构数据清洗方法教程 RAG架构的数据清洗是索引阶段的关键步骤,直接影响后续检索和生成的质量。以下是数据清洗的核心方法及步骤: --- #### 一、数据清洗核心步骤 1. **文本规范化** - 移除HTML/XML标签:使用正则表达式或工具(如BeautifulSoup)清理网页数据 - 统一字符编码:将文本转换为UTF-8格式 - 大小写归一化:统一转为小写(需根据任务需求决定) - 特殊符号处理:保留句号、逗号等必要标点,移除乱码或无关符号 - 拼写纠错:使用`pySpellChecker`或`SymSpell`库修正拼写错误[^1] 2. **数据去重** - 精确去重:通过哈希值(如MD5)识别重复文档 - 语义去重:用嵌入向量(如BERT)计算余弦相似度,过滤相似度>90%的内容[^2] 3. **噪声过滤** - 停用词移除:使用NLTK或自定义列表过滤无意义词汇 - 低质量文本过滤: - 规则过滤:剔除长度<50字符的段落 - 模型过滤:用分类模型识别垃圾文本(如`fastText`) 4. **结构化分块** - 按固定长度分块:适合技术文档(如每512字符为一组) - 语义分块:使用`LangChain`的`RecursiveCharacterTextSplitter`按段落边界划分 5. **元数据标注** - 添加来源、作者、时间戳等信息 - 实体标注:用NER工具(如Spacy)标记人名、地点等实体 --- #### 二、实践工具推荐 | 工具/库 | 用途 | 示例代码片段 | |-----------------|--------------------------|---------------------------------------| | BeautifulSoup | HTML解析 | `soup.get_text()` | | LangChain | 分块与预处理 | `TextSplitter(chunk_size=300)` | | SentencePiece | 子词分词 | `spm.encode_as_pieces(text)` | | Dedupe库 | 模糊去重 | `dedupe.markPairs(duplicates)` | --- #### 三、质量评估指标 1. **准确性**:随机抽样人工验证清洗结果 2. **完整性**:检查关键信息(如数字、术语)是否保留 3. **检索增强测试**:对比清洗前后的问答准确率提升 --- #### 四、典型案例 **医学文献处理流程**: 原始PDFPDFMiner提取文本 → 正则表达式去除非文字内容 → BERT模型过滤非专业内容 → 按章节分块 → 存入向量数据库 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非常大模型

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值