PyPDFLoader
是 LangChain 库中的一个文档加载工具,专门用来加载 PDF 文件中的文本内容,并将其转换成适合大模型(LLM)使用的文档格式(Document
对象),可用于后续的向量化、RAG 检索等操作。
✅ 总体作用
通俗讲:
📄 它就像一个「PDF 文本提取器」,帮你把 PDF 文件中的内容读出来,处理成结构化的文档块(document chunks),供后续的大模型处理用。
🧱 使用示例
先看个常见用法:
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("example.pdf")
pages = loader.load()
print(pages[0].page_content)
✅ 各行含义解释
代码 | 含义 |
---|---|
from langchain_community.document_loaders import PyPDFLoader | 从 LangChain 的 document_loaders 模块中导入 PyPDFLoader 工具 |
loader = PyPDFLoader("example.pdf") | 创建一个加载器实例,准备加载名为 example.pdf 的文件 |
pages = loader.load() | 加载 PDF,并返回一个 列表,每一项是一个 Document 对象(代表一页 PDF 内容) |
pages[0].page_content | 打印第1页的纯文本内容 |
🔍 返回的是什么?
每一页内容会变成一个 Document
对象,包含两个关键字段:
Document(
page_content="这是这一页提取出来的文本内容……",
metadata={"source": "example.pdf", "page": 0}
)
page_content
: 提取出来的纯文本内容metadata
: 元信息,比如文件名、页码,便于后续追踪来源
✨ PyPDFLoader 的用途场景
它一般用在以下流程里:
PDF → PyPDFLoader → Document 列表 → TextSplitter → 向量化 → 检索 → LLM 问答
举个实际例子:
假设你有一个医疗指南 PDF,要构建一个智能问答系统:
- 用
PyPDFLoader
把 PDF 加载成结构化文本 - 用
TextSplitter
切分成合适的段落 - 向量化并存进向量数据库(如 FAISS/Milvus)
- 用户提问时检索相关内容
- 提供上下文给大模型,让它作答
⚠️ 注意事项
- 依赖于
pdfplumber
或PyPDF2
之类的底层 PDF 解析器,对复杂排版的 PDF 不一定能提得很好 - 只能处理纯文本,不能提取图像、表格结构等信息(不过可以结合 OCR 做增强)
✅ 小结
特性 | 说明 |
---|---|
📄 功能 | 把 PDF 加载为结构化文档(Document)对象 |
🧠 用途 | 适用于 LangChain 中 RAG 问答、摘要、搜索等任务 |
🧱 输出 | 每一页变成一个 Document,附带页码元信息 |
🚧 局限 | 无法提取图像、复杂表格,文本提取依赖底层库质量 |
结合 PyPDFLoader
和 PyPDF2
,一边提文本,一边提“真实 metadata”:
- ✅
PyPDFLoader
:用于提取每一页的文本 - ✅
PyPDF2
:用于提取 PDF 的真实元信息(如标题、作者、创建时间等) - ✅ 自定义封装成
CustomPDFLoader
类:同时返回文本和丰富的metadata
✅ 自定义加载器:CustomPDFLoader
from langchain_core.documents import Document
from langchain_community.document_loaders import PyPDFLoader
from PyPDF2 import PdfReader
from pathlib import Path
class CustomPDFLoader:
def __init__(self, file_path: str):
self.file_path = file_path
def load(self):
# 获取真实 PDF 元信息
reader = PdfReader(self.file_path)
pdf_metadata = reader.metadata or {}
metadata_common = {
"title": pdf_metadata.get("/Title", ""),
"author": pdf_metadata.get("/Author", ""),
"creator": pdf_metadata.get("/Creator", ""),
"producer": pdf_metadata.get("/Producer", ""),
"creation_date": pdf_metadata.get("/CreationDate", ""),
"mod_date": pdf_metadata.get("/ModDate", ""),
"source": str(Path(self.file_path).resolve())
}
# 用 PyPDFLoader 加载文本
text_loader = PyPDFLoader(self.file_path)
pages = text_loader.load()
# 给每一页补充真实元数据
documents = []
for i, page in enumerate(pages):
enriched_metadata = dict(metadata_common) # 复制一份公共 metadata
enriched_metadata["page"] = page.metadata.get("page", i)
documents.append(Document(
page_content=page.page_content,
metadata=enriched_metadata
))
return documents
✅ 使用示例
loader = CustomPDFLoader("example.pdf")
docs = loader.load()
# 打印第1页的内容和元信息
print("内容:\n", docs[0].page_content[:300]) # 只打印前300个字符
print("\n元信息:\n", docs[0].metadata)
✅ 输出示例(举例说明)
内容:
第1章 医疗安全指南……
……
元信息:
{
'title': 'Medical Safety Guide',
'author': 'Dr. Zhang Wei',
'creator': 'Microsoft Word',
'producer': 'Adobe PDF Library',
'creation_date': 'D:20230710120000',
'mod_date': 'D:20230711154500',
'source': '/Users/you/project/example.pdf',
'page': 0
}
✅ 可选增强:增加页码字段到文本开头
如果你希望每一页文本加上提示(如“第X页”),你可以改下面这句:
page_content = f"[第{i+1}页]\n" + page.page_content
然后放入 Document
中。
🧠 总结
特性 | 说明 |
---|---|
🧾 真实 metadata | 读取 PDF 自带的作者、标题、创建时间等 |
📄 文本加载 | 使用 LangChain 的 PyPDFLoader |
📌 页码来源 | 来自 PyPDFLoader,每页生成一个 Document |
📁 文件路径 | 会被写入 source 字段 |
✅ 输出 | 适用于后续向量化、RAG 检索、问答系统等场景 |
完整代码:
from langchain_core.documents import Document
from langchain_community.document_loaders import PyPDFLoader
from PyPDF2 import PdfReader
from pathlib import Path
class CustomPDFLoader:
def __init__(self, file_path: str):
self.file_path = file_path
def load(self):
# 获取真实 PDF 元信息
reader = PdfReader(self.file_path)
pdf_metadata = reader.metadata or {}
metadata_common = {
"title": pdf_metadata.get("/Title", ""),
"author": pdf_metadata.get("/Author", ""),
"creator": pdf_metadata.get("/Creator", ""),
"producer": pdf_metadata.get("/Producer", ""),
"creation_date": pdf_metadata.get("/CreationDate", ""),
"mod_date": pdf_metadata.get("/ModDate", ""),
"source": str(Path(self.file_path).resolve())
}
# 用 PyPDFLoader 加载文本
text_loader = PyPDFLoader(self.file_path)
pages = text_loader.load()
# 给每一页补充真实元数据
documents = []
for i, page in enumerate(pages):
enriched_metadata = dict(metadata_common) # 复制一份公共 metadata
enriched_metadata["page"] = page.metadata.get("page", i)
enriched_metadata["keyword"] = '这里假装通过LLM提取或者NER提取关键字'
documents.append(Document(
page_content=page.page_content,
metadata=enriched_metadata
))
return documents
path = "../data/Understanding_Climate_Change.pdf"
loader = CustomPDFLoader(path)
docs = loader.load()
# 打印第1页的内容和元信息
print("内容:\n", docs[0].page_content[:300]) # 只打印前300个字符
print("\n元信息:\n", docs[0].metadata)