打造灵活强大的PDF解析管道:从文本提取到智能分块的全流程实战
PDF 文件无处不在。你很可能在各种场合见过它们,比如大学论文、电费账单、办公合同、产品手册等等。PDF 格式非常常见,但实际操作起来并没有看上去那么简单。假设你想从一个 PDF 文件中提取有用信息,比如读取文本、将其分段,或快速生成摘要。听起来很简单,但当你真正尝试时,会发现过程并不顺利。
NWU 数据科学
为决策制定提供数据技能支持。
与 Word 或 HTML 文件不同,PDF 文件并不会以整齐、易读的方式存储内容。它们的设计目标是“看起来美观”,而不是被程序读取。文本内容可能分散在页面各处,被拆分成各种奇怪的块,与表格和图片混杂。这让我们很难从中提取出干净、结构化的数据。
NVIDIA RTX PRO
NVIDIA RTX PRO
在本文中,我们将构建一个能够应对这些问题的工具。我们将创建一个自定义的 PDF 解析器,它能做到:
- 按页面级别提取并清理 PDF 文本,可选择性保留布局以获得更好的格式
- 处理图片元数据的提取
- 通过检测跨页面重复的行来移除多余的页眉和页脚,减少噪声
- 获取详细的文档及页面级元数据,如作者、标题、创建日期、旋转角度和页面尺寸
- 将内容分块,便于后续的 NLP 或 LLM 处理
让我们开始吧!
文件夹结构
在开始之前,建议你合理组织项目文件,以便于后续维护和扩展。
custom_pdf_parser/
│
├── parser.py # PDF 解析核心代码
├── langchain_loader.py # 与 LangChain 集成的加载器
├── pipeline.py # 处理流程封装
├── example.py # 使用示例
├── requirements.txt # 依赖库清单
└── __init__.py # (可选)标记为 Python 包
你可以将 __init__.py
文件留空,它的主要作用只是标记该目录为一个 Python 包。接下来我会逐步解释其余各文件的作用。
所需工具(requirements.txt)
所需的主要库有:
- PyPDF:纯 Python 的 PDF 读写库,用于提取 PDF 文件中的文本。
- LangChain:用于构建上下文感知型语言模型应用的框架,我们用它来优化文本处理和任务编排。
安装方式:
pip install pypdf langchain
如果你希望更优雅地管理依赖,可以创建一个 requirements.txt
文件,内容如下:
pypdf
langchain
requests
然后执行:
pip install -r requirements.txt
步骤 1:建立 PDF 解析器(parser.py)
核心类 CustomPDFParser
使用 PyPDF 从每一页 PDF 中提取文本与元数据。它还包括清理文本、提取图片信息(可选)、以及移除经常出现在每页的页眉/页脚的方法。
主要功能包括:
- 支持保留布局格式
- 提取如页码、旋转角度、页面尺寸等元数据
- 能过滤掉内容过少的页面
- 文本清理会保留段落换行,同时移除多余空白
核心实现代码如下(代码段已略去,仅保留主要思路和功能点说明):
import os
import logging
from pathlib import Path
from typing import List, Dict, Any
import pypdf
from pypdf import PdfReader# 日志配置
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)class CustomPDFParser:def __init__(self, extract_images=False, preserve_layout=True, remove_headers_footers=True, min_text_length=10):# 初始化参数...def extract_text_from_page(self, page, page_num):# 从单页提取文本和元数据...def _clean_text(self, text):# 文本清理与格式规范...def _extract_image_info(self, page):# 提取图片元数据...def _remove_headers_footers(self, pages_data):# 自动检测并移除重复页眉/页脚...def _extract_document_metadata(self, pdf_reader, pdf_path):# 提取文档级元数据...def parse_pdf(self, pdf_path):# 综合解析整个 PDF 文件(文本、元数据、分段)...
步骤 2:与 LangChain 集成(langchain_loader.py)
LangChainPDFLoader
封装了自定义解析器,并将解析出的每一页转化为 LangChain 的 Document
对象,便于后续 NLP 流程使用。
- 支持使用 LangChain 的
RecursiveCharacterTextSplitter
对文档进行分块 - 可自定义分块大小和重叠部分,方便大语言模型输入
- 实现了原始 PDF 内容与 LangChain 文档抽象之间的无缝衔接
核心实现如下(代码段略去,仅保留功能描述):
from typing import List, Optional, Dict, Any
from langchain.schema import Document
from langchain.document_loaders.base import BaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from parser import CustomPDFParserclass LangChainPDFLoader(BaseLoader):def __init__(self, file_path, parser_config=None, chunk_size=500, chunk_overlap=50):...def load(self):# 加载并解析 PDF,转化为 Document 列表...def load_and_split(self):# 加载并按块分割文档,适配大语言模型输入...
步骤 3:构建处理流程(pipeline.py)
PDFProcessingPipeline
类为你提供更高层次的操作接口,包括:
- 处理单个 PDF 文件
- 支持多种输出格式(原始字典、LangChain 文档、纯文本)
- 可配置是否分块、分块大小等参数
- 内置错误处理与日志输出
实现思路如下:
from typing import List, Optional, Dict, Any
from langchain.schema import Document
from parser import CustomPDFParser
from langchain_loader import LangChainPDFLoader
import logginglogger = logging.getLogger(__name__)class PDFProcessingPipeline:def __init__(self, parser_config=None):...def process_single_pdf(self, pdf_path, output_format="langchain", chunk_documents=True, chunk_size=500, chunk_overlap=50):# 支持多种格式的解析与输出...
步骤 4:解析器测试(example.py)
你可以通过如下方式测试解析器:
import os
from pathlib import Pathdef main():print("👋 欢迎使用自定义 PDF 解析器!")print("你想要做什么?")print("1. 查看完整原始解析数据")print("2. 提取全部纯文本")print("3. 获取 LangChain 文档(不分块)")print("4. 获取 LangChain 文档(分块)")print("5. 显示文档元数据")print("6. 显示每页元数据")print("7. 查看清理后的文本(移除页眉/页脚)")print("8. 查看图片元数据")choice = input("请输入你的选择编号:").strip()...if __name__ == "__main__":main()
运行后,系统会提示你输入选项编号和 PDF 文件路径。例如:
👋 欢迎使用自定义 PDF 解析器!
你想要做什么?
1. 查看完整原始解析数据
2. 提取全部纯文本
3. 获取 LangChain 文档(不分块)
4. 获取 LangChain 文档(分块)
5. 显示文档元数据
6. 显示每页元数据
7. 查看清理后的文本(移除页眉/页脚)
8. 查看图片元数据
请输入你的选择编号:5
请输入 PDF 文件路径:/content/articles.pdf
输出示例:
LangChain Chunks: 16
首个分块预览:
San José State University Writing Center
www.sjsu.edu/writingcenter
Written by Ben AldridgeArticles (a/an/the), Spring 2014. 1 of 4
Articles (a/an/the)There are three articles in the English language: a, an, and the. They are placed before nouns
and show whether a given noun is general or specific.Examples of Articles
结语
在本指南中,你学会了如何仅借助开源工具搭建一个灵活、强大的 PDF 处理管道。由于其高度模块化,你可以轻松扩展功能:比如用 Streamlit 构建搜索接口、用 FAISS 等向量数据库存储分块实现智能检索,甚至将其集成到聊天机器人中。你无需推倒重来,只需拼接下一个环节即可。PDF 不再是“黑匣子”,你可以随心所欲地读取、搜索、理解任何文档!