夜雨聆风学习资料网

ARTICLE · 1072822

LangChain 文档加载器

LangChain 文档加载器(Document Loaders)

一、什么是文档加载器

文档加载器(Document Loader)是 LangChain 数据处理链的第一步,负责将各种格式的文件加载为 LangChain 的 Document 对象。

1.1 统一接口:BaseLoader

虽然加载器各不相同(TextLoader、CSVLoader、PyPDFLoader……),但它们都实现了 BaseLoader 接口,因此都具有两个通用方法:

from langchain_core.document_loaders import BaseLoader

# 所有加载器都继承自 BaseLoader,具备以下方法:
class BaseLoader:
def load(self) -> list[Document]:
"""一次性加载所有文档到内存,返回 Document 列表"""
        ...

def lazy_load(self) -> Iterator[Document]:
"""基于生成器流式懒加载文档,逐个 yield,适用于大数据集"""
        ...
方法
返回类型
说明
适用场景
load()list[Document]
一次性加载全部内容到内存
小文件、文件数量少
lazy_load()Iterator[Document]
惰性加载,逐个 yield 文档
大文件、海量文件、内存受限
# load() — 适合小文件
docs = loader.load()          # 返回 list[Document],全部加载到内存

# lazy_load() — 适合大文件
for doc in loader.lazy_load(): # 逐个 yield,不会一次性占满内存
    process(doc)

1.2 统一输出:Document 对象

所有加载器都将原始数据转换为统一的 Document 对象,包含两个核心属性:

属性
类型
说明
page_contentstr
文档的文本内容(加载器负责将原始格式转为纯文本)
metadatadict
文档的元数据(来源、页码、作者、文件类型等)
# Document 对象示例
Document(
    page_content="这是文档的文本内容...",
    metadata={"source": "/path/to/file.txt", "page": 0}
)

不同加载器的 metadata 差异:

加载器
metadata 中常见的 key
TextLoadersource
CSVLoadersource
, row
JSONLoadersource
, seq_num
PyPDFLoadersource
, page, page_label, total_pages, producer, creator
Docx2txtLoadersource
BSHTMLLoadersource
, title
DirectoryLoader
继承内部加载器的 metadata

核心思想:不管原始数据是什么格式(PDF、Word、HTML、CSV……),加载器都将其统一为 Document(page_content, metadata) 格式。后续的 Text Splitter、Embedding、向量数据库都只跟 Document 打交道,不关心原始文件格式。

1.3 文档加载器在 RAG 中的位置

RAG(Retrieval-Augmented Generation,检索增强生成)是 LangChain 的核心应用场景之一。它通过从外部知识库检索相关信息来增强 LLM 的回答质量。

一个完整的 RAG 流程分为两大部分:

┌──────────────────── 知识库构建(离线阶段)────────────────────┐
│                                                              │
│  原始文件          Document          文本块           向量     │
│  (PDF/Word/  →   对象列表  →    (Chunk)   →   向量化  →  向量库 │
│   HTML/CSV...)   [Loader]       [Splitter]    [Embedding]     │
│                                                              │
└──────────────────────────────────────────────────────────────┘

┌──────────────────── 检索生成(在线阶段)────────────────────┐
│                                                            │
│  用户提问 → 问题向量化 → 向量库检索 → 相关文档 → 拼接上下文  │
│            [Embedding]  [Retriever]  [Document]  [Prompt]  │
│                                                            │
│  → LLM 生成回答                                             │
│    [ChatModel]                                             │
│                                                            │
└────────────────────────────────────────────────────────────┘

知识库构建流程详解:

步骤
组件
作用
示例
1. 加载文档
Document Loader
将各种格式的文件转为 Document 对象
PDF → 每页一个 Document
2. 切分文本
Text Splitter
将长文档切分为适合 Embedding 的文本块(Chunk)
一个 10 页的 PDF → 50 个 Chunk
3. 向量化
Embedding Model
将文本块转为高维向量(数值数组)
"LangChain 是一个框架" → [0.12, -0.34, ...]
4. 存入向量库
Vector Store
将向量存储到数据库中,支持相似度检索
FAISS / Chroma / Milvus

检索生成流程详解:

步骤
组件
作用
1. 用户提问
—
用户输入自然语言问题
2. 问题向量化
Embedding Model
将问题转为向量(与知识库构建使用同一个模型)
3. 检索相关文档
Retriever
在向量库中查找与问题向量最相似的 Top-K 个文档
4. 拼接上下文
Prompt Template
将检索到的文档内容拼接到 Prompt 中,作为 LLM 的参考知识
5. 生成回答
ChatModel
LLM 基于检索到的上下文生成准确的回答

文档加载器是 RAG 的入口。加载质量直接影响后续所有环节——如果加载器提取的文本不完整或乱码,再好的 Embedding 和 LLM 也无法弥补。选择合适的加载器并正确处理编码、格式等问题,是构建高质量 RAG 系统的第一步。

1.4 整体流程一览

原始文件 → [Document Loader] → Document 对象列表 → [Text Splitter] → 切分后的文档 → [Embedding] → 向量数据库

二、环境准备

2.1 基础依赖

pip install langchain-community rich python-dotenv requests

2.2 各格式专用依赖

不同的加载器依赖不同的底层库:

文件格式
加载器
需要安装的包
安装命令
.txtTextLoader
无额外依赖
—
.csvCSVLoader
无额外依赖
—
.jsonJSONLoaderjqpip install jq
.pdfPyPDFLoaderpypdfpip install pypdf
.docxDocx2txtLoaderdocx2txtpip install docx2txt
.mdUnstructuredMarkdownLoaderunstructuredpip install unstructured
.htmlBSHTMLLoaderbeautifulsoup4pip install beautifulsoup4
.xlsxUnstructuredExcelLoaderunstructuredpip install unstructured
.pptxUnstructuredPowerPointLoaderunstructuredpip install unstructured

2.3 一键安装所有依赖

pip install langchain-community rich python-dotenv requests jq pypdf docx2txt unstructured beautifulsoup4 openpyxl

关于 langchain-community 的弃用警告:运行时会看到 DeprecationWarning,这是正常的。langchain-community 正在逐步迁移到独立包,但目前功能完全正常。


三、阶段一:TextLoader — 加载纯文本文件

最简单的加载器,读取 .txt 文件,整个文件作为一个 Document。

from langchain_community.document_loaders import TextLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# TextLoader — 加载纯文本文件
# 说明:最基础的文档加载器,将整个文本文件加载为一个 Document
# 无需额外安装依赖包
# ============================================================

# 1. 使用 pathlib 构建跨平台的文件路径
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "langchain.txt"

# 2. 创建加载器
loader = TextLoader(
    file_path=str(file_path),  # 文件路径
    encoding="utf-8",          # 文件编码,中文文件通常为 utf-8
)

# 3. 加载文档
docs = loader.load()

# 4. 查看结果
rprint(f"加载了 {len(docs)} 个文档")
rprint(docs[0].page_content[:200])   # 打印前 200 个字符
rprint(docs[0].metadata)             # 打印元数据

TextLoader 参数说明:

参数
类型
默认值
说明
file_pathstr
必填
文件路径
encodingstr"utf-8"
文件编码

特点:

  • 整个文件内容作为一个 Document 的 page_content
  • metadata 中只包含 source(文件路径)
  • 不支持自动分块,大文件需要配合 Text Splitter 使用

四、阶段二:CSVLoader — 加载 CSV 文件

将 CSV 的每一行加载为一个 Document,自动将列名作为元数据。

from langchain_community.document_loaders import CSVLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# CSVLoader — 加载 CSV 文件
# 说明:将 CSV 的每一行转换为一个 Document
#       列名会作为 metadata 的 key,单元格值作为 page_content
# 无需额外安装依赖包
# ============================================================

# 1. 构建文件路径
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "test.csv"

# 2. 创建加载器
loader = CSVLoader(
    file_path=str(file_path),   # CSV 文件路径
    encoding="utf-8",           # 文件编码
# csv_args={                # 可选:CSV 解析参数
#     "delimiter": ",",     # 分隔符,默认逗号
#     "quotechar": '"',     # 引号字符
#     "fieldnames": ["col1", "col2"],  # 自定义列名(用于没有表头的 CSV)
# },
)

# 3. 加载文档
docs = loader.load()

# 4. 查看结果
rprint(f"加载了 {len(docs)} 个文档")
for i, doc in enumerate(docs[:3]):   # 只打印前 3 个
    rprint(f"--- 第 {i+1} 行 ---")
    rprint(f"内容: {doc.page_content}")
    rprint(f"元数据: {doc.metadata}")

CSVLoader 参数说明:

参数
类型
默认值
说明
file_pathstr
必填
CSV 文件路径
encodingstr"utf-8"
文件编码
csv_argsdict{}
CSV 解析参数(delimiter、quotechar 等)
source_columnstrNone
指定哪一列作为 metadata 中的 source

输出格式:

# 每一行 CSV 变成一个 Document
# page_content 格式:列名: 值(换行分隔)
# metadata 包含 source 和行号

Document(
    page_content="name: 小明\nage: 25\ncity: 北京",
    metadata={"source": "test.csv", "row": 0}
)

五、阶段三:JSONLoader — 加载 JSON 文件

使用 jq 表达式从 JSON 中提取特定字段,支持嵌套结构。

前置依赖

pip install jq

完整代码

from langchain_community.document_loaders import JSONLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# JSONLoader — 加载 JSON 文件
# 说明:使用 jq 表达式从 JSON 中提取特定字段
#       支持嵌套 JSON、JSON Lines 格式
# 需要安装:pip install jq
# ============================================================

# 1. 构建文件路径
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "tsconfig.json"

# 2. 创建加载器
loader = JSONLoader(
    file_path=str(file_path),
# jq_schema 是 jq 表达式,用于从 JSON 中提取数据
# "."           — 提取整个 JSON
# ".compilerOptions" — 提取 compilerOptions 字段
# ".messages[]"  — 提取 messages 数组中的每个元素
# ".messages[].content" — 提取 messages 数组中每个元素的 content 字段
    jq_schema=".compilerOptions",
    text_content=False,   # False: 将提取结果序列化为 JSON 字符串
# True: 将提取结果作为纯文本(仅适用于字符串类型的值)
    json_lines=False,     # False: 标准 JSON 文件
# True: JSON Lines 格式(每行一个 JSON 对象)
)

# 3. 加载文档
docs = loader.load()

# 4. 查看结果
rprint(f"加载了 {len(docs)} 个文档")
for doc in docs:
    rprint(doc)

jq_schema 常用表达式:

表达式
说明
适用 JSON 结构
"."
提取整个 JSON
任意
".key"
提取顶层字段
{"key": "value"}
".arr[]"
遍历数组中的每个元素
{"arr": [1, 2, 3]}
".arr[].field"
提取数组元素中的特定字段
{"arr": [{"field": "v"}]}
".a.b.c"
提取嵌套字段
{"a": {"b": {"c": "v"}}}

JSON Lines 格式示例:

# 如果文件是 JSON Lines 格式(每行一个 JSON 对象):
# {"name": "Alice", "age": 25}
# {"name": "Bob", "age": 30}

loader = JSONLoader(
    file_path="data.jsonl",
    jq_schema=".",
    json_lines=True,     # 开启 JSON Lines 模式
    text_content=False,
)

六、阶段四:PyPDFLoader — 加载 PDF 文件

将 PDF 的每一页加载为一个 Document,支持本地文件和在线 URL。

前置依赖

pip install pypdf

完整代码

from langchain_community.document_loaders import PyPDFLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# PyPDFLoader — 加载 PDF 文件
# 说明:将 PDF 的每一页加载为一个 Document
#       支持本地文件和在线 URL
# 需要安装:pip install pypdf
# ============================================================

# 1. 构建文件路径(本地文件)
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "test.pdf"

# 2. 创建加载器
loader = PyPDFLoader(
    file_path=str(file_path),

# 也支持在线 URL(直接传入 URL 字符串即可)
# file_path="https://arxiv.org/pdf/alg-geom/9202012",

# 提取模式:控制如何从 PDF 中解析和提取文本结构
# "plain"  — 提取纯文本,默认值,适合大多数场景
# "layout" — 布局感知模式,通过插入空格和换行符模拟原文档的排版
#            适用场景:学术论文、多栏报刊杂志、左右分栏的合同
    extraction_mode="plain",
)

# 3. 加载文档(每一页变成一个 Document)
docs = loader.load()

# 4. 查看结果
rprint(f"总共加载了 {len(docs)} 页")
for i, doc in enumerate(docs[:3]):   # 只打印前 3 页
    rprint(f"--- 第 {i+1} 页 ---")
    rprint(f"内容预览: {doc.page_content[:100]}...")
    rprint(f"元数据: {doc.metadata}")
# metadata 包含:
#   source: 文件路径或 URL
#   page: 页码(从 0 开始)
#   page_label: 页码标签(PDF 中显示的页码)
#   total_pages: 总页数
#   producer: PDF 生成工具
#   creator: PDF 创建工具

PyPDFLoader 参数说明:

参数
类型
默认值
说明
file_pathstr
必填
本地文件路径或在线 URL
extraction_modestr"plain"
文本提取模式(plain / layout)

两种提取模式对比:

模式
特点
适用场景
plain
提取纯文本,忽略排版
普通文档、单栏 PDF
layout
保留排版信息(空格、换行)
学术论文、多栏文档、分栏合同

七、阶段五:MinerU API — 高精度 PDF 解析

使用 MinerU 云端 API 进行高精度 PDF 解析,支持 OCR、公式识别、表格识别。

前置说明

MinerU 是一个云端 PDF 解析服务,适用于需要高精度提取的复杂 PDF(含公式、表格、图片等)。

前置依赖

pip install requests python-dotenv

环境变量配置

在 .env 文件中配置:

MINERU_API_TOKEN=your_mineru_api_token

完整代码

import os
import time
import requests
from dotenv import load_dotenv
from pathlib import Path

# 加载环境变量
load_dotenv(override=True)

# ============================================================
# MinerU API — 高精度 PDF 云端解析
# 说明:通过 MinerU 云端 API 解析 PDF,支持 OCR、公式识别、表格识别
#       解析结果以 zip 包形式下载
# 需要安装:pip install requests python-dotenv
# 需要配置:.env 文件中设置 MINERU_API_TOKEN
# ============================================================

def upload_files(file_paths: list[str]) -> str:
"""
    批量上传文件到 MinerU 并获取 batch_id

    流程:
    1. 向 MinerU API 申请上传链接
    2. 将本地文件上传到获得的 URL
    3. 返回 batch_id 用于后续查询

    Args:
        file_paths: 要上传的文件路径列表

    Returns:
        batch_id: 批次 ID,用于查询解析结果
    """

    url = "https://mineru.net/api/v4/file-urls/batch"
    api_token = os.getenv("MINERU_API_TOKEN")

    header = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_token}",
    }

# 构建文件信息列表
    files_info = [
        {
"name": os.path.basename(file_path),  # 文件名
"is_ocr": True,                        # 启用 OCR
"data_id": f"file_{i}",                # 文件标识
        }
for i, file_path in enumerate(file_paths)
    ]

    data = {
"enable_formula": True,   # 启用公式识别
"enable_table": True,     # 启用表格识别
"language": "ch",         # 语言:ch=中文, en=英文
"files": files_info,
    }

try:
# 1. 获取上传链接
        response = requests.post(url, headers=header, json=data)

if response.status_code == 200:
            result = response.json()

if result["code"] == 0:
                batch_id = result["data"]["batch_id"]
                urls = result["data"]["file_urls"]
print(f"batch_id: {batch_id}")

# 2. 将本地文件上传到获得的 URL
for i in range(len(urls)):
with open(file_paths[i], "rb") as f:
                        res_upload = requests.put(urls[i], data=f)
if res_upload.status_code == 200:
print(f"文件上传成功: {file_paths[i]}")
else:
print(f"文件上传失败: {file_paths[i]}")
return None

return batch_id
else:
print(f"申请上传链接失败: {result.get('msg')}")
return None
else:
print(f"请求失败: {response.status_code}")
return None

except Exception as err:
print(f"上传异常: {err}")
return None


def download_files(batch_id: str):
"""
    轮询下载解析结果

    流程:
    1. 定时查询 batch_id 的解析状态
    2. 解析完成后下载 zip 包
    3. 所有文件处理完毕(成功或失败)后退出

    Args:
        batch_id: 批次 ID
    """

if not batch_id:
print("batch_id 为空,跳过下载")
return

# 创建保存目录
    os.makedirs("parsed_files", exist_ok=True)

    url = f"https://mineru.net/api/v4/extract-results/batch/{batch_id}"
    api_token = os.getenv("MINERU_API_TOKEN")

    header = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_token}",
    }

    failed_files = set()
    done_files = set()

while True:
        res = requests.get(url, headers=header)
        result_json = res.json()

if res.status_code != 200 or result_json.get("code") != 0:
print("查询结果失败:", result_json)
break

        extract_results = result_json["data"]["extract_result"]

for result in extract_results:
            data_id = result["data_id"]

# 处理失败的文件
if result["state"] == "failed":
                failed_files.add(data_id)

# 处理完成且未下载的文件
elif result["state"] == "done" and data_id not in done_files:
                done_files.add(data_id)

                full_zip_url = result["full_zip_url"]
                res_download = requests.get(full_zip_url, stream=True)

# 流式下载 zip 包
                save_path = f"parsed_files/{result['file_name']}-{data_id}.zip"
with open(save_path, "wb") as f:
for chunk in res_download.iter_content(chunk_size=1024):
if chunk:
                            f.write(chunk)
print(f"下载完成: {save_path}")

# 终止条件:所有文件都处理完了
if len(failed_files) + len(done_files) == len(extract_results):
break

# 等待 5 秒后再次查询
        time.sleep(5)

# 打印最终状态
print("--- 任务结束 ---")
for i in failed_files:
print(f"失败: {i}")
for i in done_files:
print(f"完成: {i}")


# --- 主程序入口 ---
if __name__ == "__main__":
# 构建文件路径
    script_dir = Path(__file__).parent
    file_path = script_dir.parent / "assets" / "test.pdf"

# 1. 上传文件
    batch_id = upload_files([str(file_path)])

# 2. 下载解析结果
if batch_id:
        download_files(batch_id)

MinerU API 工作流程:

本地 PDF 文件
    ↓
1. 申请上传链接(POST /api/v4/file-urls/batch)
    ↓ 获得 batch_id + 上传 URL
2. 上传文件到 URL(PUT)
    ↓
3. 轮询解析状态(GET /api/v4/extract-results/batch/{batch_id})
    ↓ 每 5 秒查询一次
4. 解析完成后下载 zip 包
    ↓
5. zip 包内包含:Markdown 文本、图片、表格数据等

八、阶段六:Docx2txtLoader — 加载 Word 文档

加载 .docx 格式的 Word 文档。

前置依赖

pip install docx2txt

完整代码

from langchain_community.document_loaders import Docx2txtLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# Docx2txtLoader — 加载 Word (.docx) 文档
# 说明:将 Word 文档的文本内容加载为 Document 对象
# 需要安装:pip install docx2txt
# ============================================================

# 1. 构建文件路径
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "example.docx"

# 2. 创建加载器
loader = Docx2txtLoader(
    file_path=str(file_path),
)

# 3. 加载文档
docs = loader.load()

# 4. 查看结果
rprint(f"加载了 {len(docs)} 个文档")
for doc in docs:
    rprint(f"内容预览: {doc.page_content[:200]}...")
    rprint(f"元数据: {doc.metadata}")
# metadata 包含 source(文件路径)

注意事项:

  • 只支持 .docx 格式,不支持旧版 .doc 格式
  • 提取纯文本,不保留格式信息(字体、颜色等)
  • 整个文档作为一个 Document

九、阶段七:UnstructuredMarkdownLoader — 加载 Markdown 文件

加载 .md 格式的 Markdown 文件,保留标题层级等结构信息。

前置依赖

pip install unstructured

完整代码

from langchain_community.document_loaders import UnstructuredMarkdownLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# UnstructuredMarkdownLoader — 加载 Markdown 文件
# 说明:解析 Markdown 文件,保留标题、列表等结构信息
# 需要安装:pip install unstructured
# ============================================================

# 1. 构建文件路径
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "example.md"

# 2. 创建加载器
loader = UnstructuredMarkdownLoader(
    file_path=str(file_path),
)

# 3. 加载文档
docs = loader.load()

# 4. 查看结果
rprint(f"加载了 {len(docs)} 个文档")
for doc in docs:
    rprint(f"内容预览: {doc.page_content[:200]}...")
    rprint(f"元数据: {doc.metadata}")
# metadata 包含:
#   source: 文件路径
#   file_directory: 文件所在目录
#   file_type: 文件类型(text/markdown)
#   category: 内容分类(Title, NarrativeText, ListItem 等)

Unstructured 系列加载器的特点:

  • 自动识别文档结构(标题、段落、列表、表格等)
  • 在 metadata 中标注每个元素的 category
  • 支持多种格式:Markdown、Excel、PowerPoint、PDF 等

十、阶段八:BSHTMLLoader — 加载 HTML 文件

使用 BeautifulSoup 解析 HTML,提取标题和正文内容。

前置依赖

pip install beautifulsoup4

完整代码

from langchain_community.document_loaders import BSHTMLLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# BSHTMLLoader — 加载 HTML 文件
# 说明:使用 BeautifulSoup 解析 HTML,提取标题和正文
# 需要安装:pip install beautifulsoup4
# ============================================================

# 1. 构建文件路径
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "example.html"

# 2. 创建加载器
loader = BSHTMLLoader(
    file_path=str(file_path),
# open_encoding="utf-8",  # 可选:指定 HTML 编码
)

# 3. 加载文档
docs = loader.load()

# 4. 查看结果
rprint(f"加载了 {len(docs)} 个文档")
for doc in docs:
    rprint(f"内容预览: {doc.page_content[:200]}...")
    rprint(f"元数据: {doc.metadata}")
# metadata 包含:
#   source: 文件路径
#   title: HTML 的 <title> 标签内容

BSHTMLLoader 的特点:

  • 自动提取 <title> 标签内容到 metadata["title"]
  • page_content 包含 HTML 的文本内容(去除标签)
  • 基于 BeautifulSoup,支持各种 HTML 编码和格式

十一、DirectoryLoader — 批量加载整个目录的文件

递归加载目录下的所有文件,根据文件扩展名自动选择对应的加载器。

完整代码

from langchain_community.document_loaders import DirectoryLoader, TextLoader, PyPDFLoader
from pathlib import Path
from rich import print as rprint

# ============================================================
# DirectoryLoader — 批量加载整个目录的文件
# 说明:递归遍历目录,根据文件扩展名匹配对应的加载器
#       适合一次性加载整个知识库、文档库
# 无需额外安装依赖包(但内部使用的加载器可能需要对应依赖)
# ============================================================

# 1. 构建目录路径
script_dir = Path(__file__).parent
dir_path = script_dir.parent / "assets"

# ============================================================
# 方式一:加载目录下所有 .txt 文件
# ============================================================
loader = DirectoryLoader(
    path=str(dir_path),           # 要扫描的目录路径
    glob="*.txt",                 # 文件匹配模式(支持 glob 语法)
    loader_cls=TextLoader,        # 使用的加载器类
    loader_kwargs={"encoding": "utf-8"},  # 传递给加载器的参数
    use_multithreading=False,     # 是否使用多线程加速(大目录建议开启)
# show_progress=True,         # 是否显示进度条
# recursive=True,             # 是否递归扫描子目录(默认 True)
)

docs = loader.load()
rprint(f"加载了 {len(docs)} 个 .txt 文档")
for doc in docs:
    rprint(f"  来源: {doc.metadata['source']}")

# ============================================================
# 方式二:加载目录下所有 .pdf 文件
# ============================================================
loader = DirectoryLoader(
    path=str(dir_path),
    glob="**/*.pdf",              # ** 表示递归匹配所有子目录
    loader_cls=PyPDFLoader,
    use_multithreading=True,      # PDF 解析较慢,建议开启多线程
)

docs = loader.load()
rprint(f"加载了 {len(docs)} 个 PDF 页面")

# ============================================================
# 方式三:使用 ** 递归匹配(等同于 recursive=True)
# ============================================================
loader = DirectoryLoader(
    path=str(dir_path),
    glob="**/*",                  # 匹配所有文件
    loader_cls=TextLoader,
    loader_kwargs={"encoding": "utf-8"},
)

docs = loader.load()
rprint(f"加载了 {len(docs)} 个文档")

# ============================================================
# 方式四:按多种扩展名分别加载
# ============================================================
# DirectoryLoader 一次只能匹配一种 glob 模式
# 要加载多种格式,需要创建多个 DirectoryLoader 并合并结果

from langchain_community.document_loaders import (
    DirectoryLoader, TextLoader, PyPDFLoader, CSVLoader, JSONLoader
)

loaders = [
# 加载 .txt 文件
    DirectoryLoader(
        path=str(dir_path),
        glob="**/*.txt",
        loader_cls=TextLoader,
        loader_kwargs={"encoding": "utf-8"},
    ),
# 加载 .pdf 文件
    DirectoryLoader(
        path=str(dir_path),
        glob="**/*.pdf",
        loader_cls=PyPDFLoader,
        use_multithreading=True,
    ),
# 加载 .csv 文件
    DirectoryLoader(
        path=str(dir_path),
        glob="**/*.csv",
        loader_cls=CSVLoader,
    ),
]

# 合并所有加载结果
all_docs = []
for loader in loaders:
    docs = loader.load()
    all_docs.extend(docs)
    rprint(f"  {loader}: 加载了 {len(docs)} 个文档")

rprint(f"总共加载了 {len(all_docs)} 个文档")

DirectoryLoader 参数说明:

参数
类型
默认值
说明
pathstr
必填
要扫描的目录路径
globstr"**/*"
文件匹配模式(glob 语法)
loader_clstypeNone
使用的加载器类
loader_kwargsdict{}
传递给加载器的参数
use_multithreadingboolFalse
是否使用多线程(大目录建议开启)
show_progressboolFalse
是否显示进度条
recursiveboolTrue
是否递归扫描子目录

glob 模式说明:

模式
说明
示例
"*.txt"
当前目录下的 .txt 文件
file.txt
"**/*.txt"
所有子目录下的 .txt 文件
sub/dir/file.txt
"**/*"
所有文件
任意文件
"[abc]*.txt"
以 a/b/c 开头的 .txt 文件
a_file.txt

十二、更多加载器一览

LangChain 支持的完整加载器列表(部分常用):

加载器
文件格式
安装命令
TextLoader.txt
无额外依赖
CSVLoader.csv
无额外依赖
JSONLoader.json
 / .jsonl
pip install jq
PyPDFLoader.pdfpip install pypdf
Docx2txtLoader.docxpip install docx2txt
UnstructuredMarkdownLoader.mdpip install unstructured
BSHTMLLoader.htmlpip install beautifulsoup4
UnstructuredExcelLoader.xlsx
 / .xls
pip install unstructured openpyxl
UnstructuredPowerPointLoader.pptxpip install unstructured python-pptx
PyMuPDFLoader.pdfpip install pymupdf
AzureAIDocumentIntelligenceLoader
多格式
pip install azure-ai-documentintelligence
GitLoader
Git 仓库
pip install langchain-community
WebBaseLoader
网页 URL
pip install bs4
SitemapLoader
sitemap.xml
pip install bs4
DirectoryLoader
目录批量加载
无额外依赖(内部加载器按需安装)

十三、常见陷阱与注意事项

13.1 文件路径问题

# 错误:相对路径依赖运行目录
loader = TextLoader(file_path="../assets/file.txt")

# 正确:使用 pathlib 基于脚本位置定位
from pathlib import Path
script_dir = Path(__file__).parent
file_path = script_dir.parent / "assets" / "file.txt"
loader = TextLoader(file_path=str(file_path))

13.2 编码问题

# 中文文件常见错误:UnicodeDecodeError
# 解决:显式指定编码
loader = TextLoader(file_path="file.txt", encoding="utf-8")

# 如果文件是 GBK 编码(Windows 中文系统常见)
loader = TextLoader(file_path="file.txt", encoding="gbk")

13.3 缺少依赖包

# 常见错误:ImportError / ModuleNotFoundError
# JSONLoader 需要 jq
# pip install jq

# PyPDFLoader 需要 pypdf
# pip install pypdf

# Docx2txtLoader 需要 docx2txt
# pip install docx2txt

# BSHTMLLoader 需要 beautifulsoup4
# pip install beautifulsoup4

13.4 大文件处理

# 错误:一次性加载大文件可能导致内存溢出
docs = loader.load()

# 正确:使用惰性加载,逐个处理
for doc in loader.lazy_load():
    process(doc)  # 逐个处理,不会一次性占满内存

十四、一键安装所有依赖汇总

# 基础依赖
pip install langchain-community rich python-dotenv requests

# 各格式专用依赖(按需安装)
pip install jq                    # JSONLoader
pip install pypdf                 # PyPDFLoader
pip install docx2txt              # Docx2txtLoader
pip install unstructured          # UnstructuredMarkdownLoader / ExcelLoader / PPTLoader
pip install beautifulsoup4        # BSHTMLLoader
pip install openpyxl              # UnstructuredExcelLoader(xlsx 支持)
pip install python-pptx           # UnstructuredPowerPointLoader(pptx 支持)
pip install pymupdf               # PyMuPDFLoader(更快的 PDF 解析)

# 或者一键安装全部
pip install langchain-community rich python-dotenv requests jq pypdf docx2txt unstructured beautifulsoup4 openpyxl python-pptx pymupdf

十五、学习路线总结

阶段一:TextLoader — 纯文本
    ↓ 最简单的加载器,理解 Document 对象结构
阶段二:CSVLoader — CSV 表格
    ↓ 每行一个 Document,理解 metadata 的自动生成
阶段三:JSONLoader — JSON 数据
    ↓ 掌握 jq 表达式,理解结构化数据提取
阶段四:PyPDFLoader — PDF 文档
    ↓ 掌握 PDF 解析,理解不同提取模式
阶段五:MinerU API — 高精度 PDF
    ↓ 掌握云端 API 调用,处理复杂 PDF
阶段六:Docx2txtLoader — Word 文档
    ↓ 掌握 Office 文档加载
阶段七:UnstructuredMarkdownLoader — Markdown
    ↓ 掌握结构化文档加载
阶段八:BSHTMLLoader — HTML 网页
    ↓ 掌握网页内容提取
阶段九:DirectoryLoader — 目录批量加载
    ↓ 掌握整个目录的文件批量加载

相关学习资料