跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

LangChain PyPDFLoader 实战:PDF 加载、分块与图片 OCR 提取

本文详解 LangChain 中 PyPDFLoader 的实战应用,涵盖 PDF 文本加载、元数据管理、指定页码抽取及全文合并方法。针对扫描版 PDF 和图片内容,介绍了集成 RapidOCR 进行 OCR 识别的方案,并提供了加密 PDF 解密、文本分块优化及批量文件夹处理的代码示例。通过具体案例演示如何规避加载失败、分块截断等常见问题,帮助开发者高效构建 RAG 系统的文档预处理环节。

路由之心发布于 2026/4/11更新于 2026/7/2542 浏览
LangChain PyPDFLoader 实战:PDF 加载、分块与图片 OCR 提取

LangChain PyPDFLoader 实战:PDF 加载、分块与图片 OCR 提取

在 AI 大模型学习系列中,我们已经掌握了 LangChain 的核心概念、Prompt 工程以及链(Chain)等基础能力。而在 RAG(检索增强生成)系统 中,'文档加载(Document Loading)'是数据输入的第一步——只有先把 PDF、Word 等外部文档准确提取成文本,才能后续构建向量数据库、实现精准检索。

本文作为 RAG 链路的关键实战篇,将聚焦 LangChain 中最常用的 PDF 加载器 PyPDFLoader,从基础使用到图片提取,再到问题排查,带你一站式掌握 PDF 文档处理能力。

PyPDFLoader 运行效果演示

为什么需要 PyPDFLoader?

在 RAG 系统中,PDF 是最常见的'外部知识库'格式(如技术文档、论文、报告等)。但 PDF 的文本存储结构特殊,直接读取会出现'乱码''分页丢失'等问题。LangChain 的 PyPDFLoader 正是为解决这个问题而生。

它的核心价值在于:

  • 自动按 PDF 页码拆分文档,返回 Document 对象列表(每个对象对应 1 页);
  • 保留元数据(如页码、文件路径),方便后续检索时定位'文本来源';
  • 支持按需加载指定页码,避免大文件加载耗时;
  • 可结合 OCR 工具提取扫描版 PDF 或图片中的文本,覆盖更多场景。

PyPDFLoader 基础:安装与核心能力

安装依赖库

PyPDFLoader 依赖 pypdf 库实现 PDF 解析,需先安装(建议指定版本避免兼容性问题):

# 安装 pypdf(推荐 3.0.0+ 版本)
pip install pypdf>=3.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

# 安装 LangChain 社区版(包含 PyPDFLoader)
pip install langchain-community -i https://pypi.tuna.tsinghua.edu.cn/simple

核心能力说明

能力描述适用场景
按页拆分将多页 PDF 拆分为单个 Document 对象,每个对象包含 page_content(文本)和 metadata(元数据)需按页码追溯文本来源的场景(如'引用第 5 页的内容')
元数据保留自动记录 source(文件路径)、page(页码,从 1 开始)RAG 检索时显示'答案来自 xxx 文件第 x 页'
按需加载支持指定页码范围加载,无需加载整个文件大文件(如 1000 页 PDF)仅需提取部分页面

PyPDFLoader 实战:3 类核心场景

以下实战均基于'本地 PDF 文件'(路径示例:data/test.pdf),建议先创建 data 文件夹并放入测试 PDF,避免路径错误。

场景 1:加载整个 PDF 并查看基础信息

目标:加载完整 PDF,查看总页数、第一页文本和元数据。

from langchain_community.document_loaders import PyPDFLoader

# 1. 初始化加载器(传入 PDF 文件路径,支持相对路径/绝对路径)
# 相对路径:相对于当前代码文件的路径(如 data/test.pdf)
# 绝对路径:如 "C:/docs/test.pdf"(Windows)或 "/home/user/docs/test.pdf"(Linux)
loader = PyPDFLoader("data/test.pdf")

# 2. 加载所有页面(返回 Document 对象列表)
pages = loader.load()

# 3. 查看基础信息
print(f"PDF 总页数:{len(pages)}")  # 输出总页数
print(f"\n第一页元数据:{pages[0].metadata}")  # 元数据(source、page 等)
print(f"\n第一页前 200 字符预览:\n{pages[0].page_content[:200]}...")  # 文本预览

输出示例:

PDF 总页数:10
第一页元数据:{'source': 'data/test.pdf', 'page': 1}
第一页前 200 字符预览:
LangChain PyPDFLoader 实战指南
1. 概述 PyPDFLoader 是 LangChain 社区版中用于解析 PDF 文件的核心加载器,支持按页拆分、元数据保留...

场景 2:按需加载指定页码

目标:加载 PDF 的'第 2-4 页'(注意:load() 方法的参数是索引,从 0 开始,即第 2 页对应索引 1,第 4 页对应索引 3)。

from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("data/test.pdf")
# 加载第 2-4 页(索引 1、2、3)
target_pages = loader.load([1, 2, 3])

# 验证结果
for idx, page in enumerate(target_pages):
    print(f"第{idx+2}页元数据:{page.metadata}")  # 页码应为 2、3、4
    print(f"第{idx+2}页前 100 字符:{page.page_content[:100]}...\n")

关键注意点:
loader.load() 的参数是'索引列表',而非'页码列表'——比如要加载第 5-7 页,需传入 [4, 5, 6],避免混淆!

场景 3:合并所有页面为单个文本

目标:将所有页面的文本合并为一个字符串(适用于无需按页拆分的场景,如'生成 PDF 全文摘要')。

from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("data/test.pdf")
pages = loader.load()

# 合并所有页面文本(用两个换行符分隔页面,避免文本粘连)
full_text = "\n\n".join([page.page_content for page in pages])

# 查看合并结果
print(f"合并后全文总字符数:{len(full_text)}")
print(f"\n全文前 500 字符预览:\n{full_text[:500]}...")

实用技巧:
如果 PDF 页面间有重复内容(如页眉'LangChain 指南'),可在合并前添加'去重逻辑',例如:

# 合并时去除每页开头的重复页眉(示例:页眉为"LangChain 指南")
full_text = "\n\n".join([page.page_content.replace("LangChain 指南", "") for page in pages])

常见问题与解决方案(避坑指南)

在实际使用中,最常遇到'加载失败'和'分块不理想'两类问题,以下是针对性解决方案。

问题 1:PDF 无法加载或内容为空

常见原因与解决步骤
原因现象解决方案
1. 文件是'扫描版 PDF'(本质是图片集合)加载后 page_content 为空字符串,或只有乱码用 OCR 工具提取图片中的文本(见第 5 章)
2. PDF 文件加密(需密码解密)报错 PdfReadError: File has not been decrypted1. 用 Adobe Acrobat 等工具手动解密;
  1. 若需代码解密,可先用 PyPDF2 库解密后再加载 | | 3. 文件路径错误 | 报错 FileNotFoundError: [Errno 2] No such file or directory | 1. 检查路径是否存在(用 os.path.exists("data/test.pdf") 验证);
  2. 优先使用绝对路径避免相对路径混淆 | | 4. 文件损坏 | 报错 PdfReadError: EOF marker not found | 重新下载或修复 PDF 文件(用 Adobe Acrobat 修复) |
加密 PDF 解密示例(用 PyPDF2)

若 PDF 需密码,可先解密再传给 PyPDFLoader:

from PyPDF2 import PdfReader, PdfWriter
from langchain_community.document_loaders import PyPDFLoader
import os

# 1. 解密 PDF 并保存为临时文件
def decrypt_pdf(input_path, output_path, password):
    reader = PdfReader(input_path)
    if reader.is_encrypted:
        reader.decrypt(password)  # 传入 PDF 密码
    # 保存解密后的文件
    writer = PdfWriter()
    for page in reader.pages:
        writer.add_page(page)
    with open(output_path, "wb") as f:
        writer.write(f)
    print(f"解密后的 PDF 已保存至:{output_path}")

# 2. 解密并加载
decrypt_pdf(
    input_path="data/encrypted_test.pdf",  # 加密 PDF 路径
    output_path="data/decrypted_test.pdf",  # 解密后保存路径
    password="123456"  # PDF 密码
)

# 3. 用 PyPDFLoader 加载解密后的文件
loader = PyPDFLoader("data/decrypted_test.pdf")
pages = loader.load()
print(f"解密后 PDF 总页数:{len(pages)}")

问题 2:文本分块不理想(如句子被截断)

PyPDFLoader 仅负责'提取文本',若需将文本拆分为适合大模型输入的'小块'(如 500 字符/块),需结合 RecursiveCharacterTextSplitter 优化分块策略。

解决方案:自定义分块参数
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. 加载 PDF
loader = PyPDFLoader("data/test.pdf")
pages = loader.load()

# 2. 初始化文本分割器(核心参数说明)
text_splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n", "\n", "."],  # 优先按段落(\n\n)、再按换行(\n)、最后按句号(.)分割
    chunk_size=500,  # 每个块的最大字符数(根据大模型上下文窗口调整,如 GPT-3.5 用 500-1000)
    chunk_overlap=50,  # 块之间的重叠字符数(避免上下文丢失,如前块结尾 50 字符与后块开头重叠)
    length_function=len  # 字符数计算方式(默认 len,即按字符数)
)

# 3. 执行分块
split_docs = text_splitter.split_documents(pages)

# 4. 查看分块结果
print(f"原始页面数:{len(pages)}")
print(f"分块后总块数:{len(split_docs)}")
print(f"\n第一个块内容:\n{split_docs[0].page_content}")
print(f"\n第一个块元数据(含页码):{split_docs[0].metadata}")

参数调整建议:

  • 若处理长文档(如论文):chunk_size=1000,chunk_overlap=100;
  • 若处理短文本(如产品手册):chunk_size=300,chunk_overlap=30;
  • 若中文文本出现'断句异常':可在 separators 中添加'。''!''?',如 separators=["\n\n", "\n", "。", "!", "?", "."]。

进阶:PDF 图片提取(含 OCR 实战)

PyPDFLoader 默认仅提取'文本层'的内容,若 PDF 中包含'图片'(如截图、手写笔记、图表中的文字),需结合OCR 工具提取图片中的文本。

这里推荐轻量级 OCR 工具 rapidocr-onnxruntime,支持中英混合识别,且无需复杂配置。

工具介绍:RapidOCR-ONNXRuntime

特性说明优势
引擎基于 ONNX Runtime(跨平台推理引擎)速度快、资源占用低(比 Tesseract 快 3-5 倍)
语言支持中文、英文、日文、韩文等 10+ 语言适合处理中英混合的技术文档
模型体积核心模型仅 5-10MB无需下载大模型,安装即用
跨平台支持 Windows、Linux、macOS、移动端开发环境无限制
与主流 OCR 工具对比
工具引擎速度准确率依赖项适用场景
RapidOCR-ONNXRuntimeONNX Runtime⭐⭐⭐⭐⭐⭐⭐少(仅需 onnxruntime)跨平台、轻量级部署、实时提取
Tesseract自研引擎⭐⭐⭐⭐多(需安装 Poppler、语言包)开源免费、简单文本识别
EasyOCRPyTorch⭐⭐⭐⭐⭐多(需安装 PyTorch、CUDA)复杂场景(如倾斜文本)
Microsoft Read API云端引擎⭐⭐⭐⭐⭐⭐⭐⭐无(需 API 密钥)企业级、高并发需求

实战:提取 PDF 中的图片文本

步骤 1:安装依赖
# 安装 rapidocr-onnxruntime(首次安装会自动下载小模型,耗时约 1-2 分钟)
pip install rapidocr-onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple
步骤 2:代码实现(图片文本提取)
from langchain_community.document_loaders import PyPDFLoader

# 关键:初始化时设置 extract_images=True,启用图片提取
loader = PyPDFLoader("data/pdf-img.pdf", extract_images=True)

# 加载页面(图片中的文本会自动嵌入到 page_content 中)
pages = loader.load()

# 查看结果(图片中的文本会跟在该页原有文本后)
print(f"总页数:{len(pages)}")
print(f"\n包含图片的页面内容(前 500 字符):\n{pages[0].page_content[:500]}...")

效果说明:
若 PDF 第 1 页包含一张'写有'LangChain RAG'的图片',则 pages[0].page_content 会包含:
【原有文本】... [图片文本:LangChain RAG] ...
(不同版本的 PyPDFLoader 可能会用不同标记包裹图片文本,以实际输出为准)

高级技巧:批量处理文件夹中的所有 PDF

若需一次性加载'某个文件夹下的所有 PDF'(如 docs/ 文件夹),可结合 os 库遍历文件夹,实现批量加载。

from langchain_community.document_loaders import PyPDFLoader
import os

# 目标文件夹路径
pdf_folder = "docs/"

# 存储所有 PDF 的页面
all_pages = []

# 遍历文件夹中的所有文件
for filename in os.listdir(pdf_folder):
    # 仅处理后缀为.pdf 的文件
    if filename.lower().endswith(".pdf"):
        # 拼接完整文件路径
        pdf_path = os.path.join(pdf_folder, filename)
        try:
            # 加载当前 PDF
            loader = PyPDFLoader(pdf_path)
            pages = loader.load()
            all_pages.extend(pages)
            print(f"成功加载:{filename}({len(pages)}页)")
        except Exception as e:
            # 捕获异常,避免单个文件错误导致整个批量任务失败
            print(f"加载{filename}失败:{str(e)}")

# 查看批量加载结果
print(f"\n批量加载完成:共加载{len(all_pages)}页 PDF")

# 合并所有文本(可选)
full_text = "\n\n".join([page.page_content for page in all_pages])
print(f"所有 PDF 合并后总字符数:{len(full_text)}")

实用优化:

  1. 跳过隐藏文件:在循环中添加 if filename.startswith('.'): continue(避免 macOS 下的 .DS_Store 文件);
  2. 多线程加载:若文件夹中 PDF 数量多(如 100+),可使用 concurrent.futures 多线程加载,提升效率:
from concurrent.futures import ThreadPoolExecutor

def load_single_pdf(pdf_path):
    """单个 PDF 加载函数(供多线程调用)"""
    try:
        loader = PyPDFLoader(pdf_path)
        pages = loader.load()
        print(f"成功加载:{os.path.basename(pdf_path)}({len(pages)}页)")
        return pages
    except Exception as e:
        print(f"加载{os.path.basename(pdf_path)}失败:{str(e)}")
        return []

# 多线程批量加载(设置最大线程数为 4,避免资源占用过高)
with ThreadPoolExecutor(max_workers=4) as executor:
    # 获取所有 PDF 路径
    pdf_paths = [os.path.join(pdf_folder, f) for f in os.listdir(pdf_folder) if f.lower().endswith(".pdf")]
    # 批量执行
    results = executor.map(load_single_pdf, pdf_paths)
    # 合并结果
    all_pages = [page for result in results for page in result]

总结与下一步

本文核心收获

  1. 基础能力:掌握 PyPDFLoader 的安装、单文件加载、按需加载、全文合并;
  2. 问题解决:能排查'加载失败''分块不理想'等常见问题;
  3. 进阶技能:结合 RapidOCR-ONNXRuntime 提取 PDF 图片文本,实现批量 PDF 处理;
  4. RAG 衔接:提取后的 Document 对象可直接传入文本分割器,为后续'向量数据库构建'做准备。

PyPDFLoader 流程示意

目录

  1. LangChain PyPDFLoader 实战:PDF 加载、分块与图片 OCR 提取
  2. 为什么需要 PyPDFLoader?
  3. PyPDFLoader 基础:安装与核心能力
  4. 安装依赖库
  5. 安装 pypdf(推荐 3.0.0+ 版本)
  6. 安装 LangChain 社区版(包含 PyPDFLoader)
  7. 核心能力说明
  8. PyPDFLoader 实战:3 类核心场景
  9. 场景 1:加载整个 PDF 并查看基础信息
  10. 1. 初始化加载器(传入 PDF 文件路径,支持相对路径/绝对路径)
  11. 相对路径:相对于当前代码文件的路径(如 data/test.pdf)
  12. 绝对路径:如 "C:/docs/test.pdf"(Windows)或 "/home/user/docs/test.pdf"(Linux)
  13. 2. 加载所有页面(返回 Document 对象列表)
  14. 3. 查看基础信息
  15. 场景 2:按需加载指定页码
  16. 加载第 2-4 页(索引 1、2、3)
  17. 验证结果
  18. 场景 3:合并所有页面为单个文本
  19. 合并所有页面文本(用两个换行符分隔页面,避免文本粘连)
  20. 查看合并结果
  21. 合并时去除每页开头的重复页眉(示例:页眉为"LangChain 指南")
  22. 常见问题与解决方案(避坑指南)
  23. 问题 1:PDF 无法加载或内容为空
  24. 常见原因与解决步骤
  25. 加密 PDF 解密示例(用 PyPDF2)
  26. 1. 解密 PDF 并保存为临时文件
  27. 2. 解密并加载
  28. 3. 用 PyPDFLoader 加载解密后的文件
  29. 问题 2:文本分块不理想(如句子被截断)
  30. 解决方案:自定义分块参数
  31. 1. 加载 PDF
  32. 2. 初始化文本分割器(核心参数说明)
  33. 3. 执行分块
  34. 4. 查看分块结果
  35. 进阶:PDF 图片提取(含 OCR 实战)
  36. 工具介绍:RapidOCR-ONNXRuntime
  37. 与主流 OCR 工具对比
  38. 实战:提取 PDF 中的图片文本
  39. 步骤 1:安装依赖
  40. 安装 rapidocr-onnxruntime(首次安装会自动下载小模型,耗时约 1-2 分钟)
  41. 步骤 2:代码实现(图片文本提取)
  42. 关键:初始化时设置 extract_images=True,启用图片提取
  43. 加载页面(图片中的文本会自动嵌入到 page_content 中)
  44. 查看结果(图片中的文本会跟在该页原有文本后)
  45. 高级技巧:批量处理文件夹中的所有 PDF
  46. 目标文件夹路径
  47. 存储所有 PDF 的页面
  48. 遍历文件夹中的所有文件
  49. 查看批量加载结果
  50. 合并所有文本(可选)
  51. 多线程批量加载(设置最大线程数为 4,避免资源占用过高)
  52. 总结与下一步
  53. 本文核心收获
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 2026 年实测好用 AI 写作平台推荐:中文、学术、职场及国际场景
  • Java 集成 Umi-OCR 实现本地图片文字提取
  • llama.cpp 大模型本地部署与推理指南
  • 基于 SpringBoot 与多版本 YOLO 的行人车辆检测系统
  • FastGPT 结合 MCP 协议构建工具增强型智能体实战指南
  • 华南理工大学开源中文主动健康大模型扁鹊(BianQue)
  • Python 通过 ctypes 调用 C++ DLL 的原理与实战
  • Kiro 安装与使用指南:AWS 新一代 AI IDE 两种部署方式
  • VMware 虚拟机安装 macOS 指南:镜像转换与工具优化
  • Stable Diffusion WebUI 云服务器部署实战
  • Python 获取卫星 TLE 数据及轨道六根数预测教程
  • 视觉 - 骨架双模态框架用于帕金森病步态的泛化评估
  • Coze 与 Dify 对比:AI 智能体开发平台选型指南
  • GitHub Copilot 网络配置与代理部署指南
  • PyCharm 中 Copilot 插件 Claude 模型不可用解决方案
  • 2025 主流 AI IDE 对比:Trae、Copilot、Windsurf、Cursor 选型指南
  • PyTorch 多卡训练原理与实现
  • 动态规划时间复杂度和空间复杂度计算方法
  • 基于 KSWEB 与 cpolar 在安卓手机部署 Typecho 博客并实现外网访问
  • Win10 升级后 Copilot 弹窗如何彻底关闭与禁用

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online