在做RAG检索增强生成、本地知识库问答、文档智能分析这类LLM应用时,第一步往往不是写prompt、调模型,而是把本地非结构化文档转化为大模型能读懂的结构化数据。LangChain作为LLM应用开发的主流框架,专门提供了DocumentLoader(文档加载器)模块,用来高效读取各类常见文档,其中PDF和Markdown是日常开发中最常用的两种格式。
这篇文章就带大家从零开始,用LangChain DocumentLoader完成PDF、Markdown文档的加载实战,包含环境配置、单文件加载、批量加载、结果解析、常见问题排查,全程代码可直接运行,新手也能快速上手。
一、DocumentLoader核心概念:为什么要用它?
简单来说,DocumentLoader就是LangChain中专门负责"读取外部文档→转化为标准Document对象"的工具集合。不管是PDF、Markdown、TXT、CSV还是网页,都能通过对应的加载器,统一转换成包含两大核心属性的Document对象:
-
page_content:文档的文本内容,是后续向量存储、检索、问答的核心数据;
-
metadata:文档元数据,比如文件路径、页码、创建时间等,方便后续溯源和筛选。
相比于自己写代码逐行读取文件、处理编码、拆分内容,DocumentLoader已经封装好了格式解析、编码兼容、分页/分段逻辑,省去大量重复造轮子的工作,直接聚焦业务逻辑即可。
二、前期环境准备
开始加载文档前,先安装必备依赖,LangChain的文档加载器大多放在langchain_community模块中,不同格式文档需要单独安装对应解析库。
- 核心依赖安装
安装LangChain核心和社区模块
pip install langchain langchain-community
PDF解析专用依赖(推荐pypdf,轻量无额外环境依赖)
pip install pypdf
Markdown解析依赖(两种加载器通用,按需安装)
pip install unstructured
- 文档准备
在项目根目录新建一个docs文件夹,放入测试文件:
-
test.pdf:普通文本型PDF文件(避免纯图片PDF,后续会讲图片PDF处理);
-
test.md:Markdown文件,包含标题、段落、代码块等常规格式。
三、实战1:PyPDFLoader加载PDF文档
LangChain加载PDF最常用、最轻量化的是PyPDFLoader,基于pypdf库开发,支持读取文本型PDF、自动分页、保留页码元数据,适合绝大多数常规PDF文档(论文、手册、报告等)。
- 单PDF文件加载完整代码
导入PDF加载器
from langchain_community.document_loaders import PyPDFLoader
1. 初始化加载器,传入PDF文件路径
loader = PyPDFLoader("./docs/test.pdf")
2. 加载文档:返回Document列表,每一页对应一个Document对象
pages = loader.load()
3. 查看加载结果
print(f"PDF总页数:{len(pages)}")
print("="*50)
查看第一页内容和元数据
first_page = pages[0]
print("第一页文本内容(前200字符):\n", first_page.page_content[:200])
print("="*50)
print("第一页元数据:\n", first_page.metadata)
- 代码结果解析
-
加载结果是列表格式,列表长度=PDF页数,每一项对应一页内容;
-
metadata中会包含source(文件路径)和page(页码),方便后续定位内容位置;
-
如果PDF是多页,直接遍历列表即可获取全部内容。
- 进阶:一键加载并分页拆分
PyPDFLoader提供了load_and_split()方法,直接加载并按页拆分,效果和load()一致,适合快速处理:
加载并直接按页拆分,效果等同于load()
pages = loader.load_and_split()
小提示:如果是纯图片型PDF(扫描件),PyPDFLoader无法读取文本,需要改用PyMuPDFLoader+OCR,或者安装rapidocr-onnxruntime库配合extract_images=True参数实现图文提取。
四、实战2:Markdown文档加载(两种常用加载器)
Markdown是技术文档、笔记最常用的格式,LangChain提供两种常用加载器,适配不同场景,大家按需选择即可。
方式一:UnstructuredMarkdownLoader(通用推荐)
这款加载器兼容性极强,能自动解析Markdown的标题、段落、代码块,保留完整文本结构,不会丢失格式相关内容,适合绝大多数Markdown文档。
导入Markdown加载器
from langchain_community.document_loaders import UnstructuredMarkdownLoader
1. 初始化加载器
loader = UnstructuredMarkdownLoader("./docs/test.md")
2. 加载文档:Markdown默认整个文件转为1个Document对象
md_docs = loader.load()
3. 查看结果
print(f"Markdown文档数量:{len(md_docs)}")
print("Markdown内容:\n", md_docs[0].page_content)
print("Markdown元数据:\n", md_docs[0].metadata)
方式二:TextLoader(极简轻量)
如果只是单纯读取Markdown的纯文本内容,不需要复杂格式解析,用TextLoader足够,轻量无额外依赖,速度更快。
导入文本加载器
from langchain_community.document_loaders import TextLoader
初始化加载器,指定utf-8编码避免中文乱码
loader = TextLoader("./docs/test.md", encoding="utf-8")
md_docs = loader.load()
查看内容
print(md_docs[0].page_content)
中文乱码解决:加载Markdown或中文PDF时,出现乱码一定要在加载器中指定encoding="utf-8",Windows系统部分文件可能需要用gbk编码。
五、进阶技巧:批量加载文件夹内所有PDF/Markdown
实际项目中不会只加载单个文件,LangChain提供DirectoryLoader实现批量加载,支持通配符筛选指定格式文件,一次性读取文件夹内所有PDF或MD文档,效率极高。
批量加载代码示例
导入批量加载器
from langchain_community.document_loaders import DirectoryLoader
1. 批量加载docs文件夹下所有PDF文件
pdf_loader = DirectoryLoader(
path="./docs", # 文件夹路径
glob="**/*.pdf", # 通配符,匹配所有子文件夹下的PDF
loader_cls=PyPDFLoader, # 指定PDF加载器
show_progress=True # 显示加载进度
)
pdf_docs = pdf_loader.load()
print(f"批量加载PDF总文档数(按页):{len(pdf_docs)}")
2. 批量加载docs文件夹下所有Markdown文件
md_loader = DirectoryLoader(
path="./docs",
glob="**/*.md",
loader_cls=UnstructuredMarkdownLoader,
show_progress=True
)
md_docs = md_loader.load()
print(f"批量加载Markdown总文档数:{len(md_docs)}")
批量加载后,所有文档会合并成一个Document列表,后续直接统一做向量存储、文本分割即可,非常适合搭建本地知识库。
六、常见问题排查
- PDF加载报错:ModuleNotFoundError
原因:未安装pypdf依赖,执行pip install pypdf即可解决。
- Markdown加载内容为空/乱码
解决:指定encoding="utf-8",检查文件路径是否正确,文件是否损坏。
- PDF扫描件无法读取内容
解决:安装OCR依赖,改用以下方式加载:
pip install pymupdf rapidocr-onnxruntime
from langchain_community.document_loaders import PyMuPDFLoader
loader = PyMuPDFLoader("./docs/scan_test.pdf", extract_images=True)
docs = loader.load()
- 加载大文件内存占用高
建议:分批加载,配合文本分割器(TextSplitter)先分割再处理,避免一次性加载超大文件导致内存溢出。
七、总结与后续学习
DocumentLoader是LangChain数据处理链路的第一步,掌握PDF和Markdown这两种高频格式的加载方法,基本能满足80%的日常场景。核心要点回顾:
-
PDF加载首选PyPDFLoader,轻量易用,支持分页;
-
Markdown加载首选UnstructuredMarkdownLoader,兼容性强;
-
批量文件用DirectoryLoader,高效批量处理;
-
加载结果统一为Document对象,方便后续文本分割、向量入库、检索问答。
文档加载完成后,下一步就是对长文本进行文本分割,再转化为向量存入向量数据库,完成RAG应用的核心数据预处理流程。下一篇文章会详细讲解LangChain文本分割器的使用,让文档内容更适配大模型的上下文窗口。