LangChain 30 天保姆级教程 · Day 16|文档加载器大合集!PDF、Word、网页、数据库一键读取,构建你的知识库!

作者:互联网

2026-04-14

HTML教程

一、为什么需要 Document Loaders?

在构建 RAG(检索增强生成)系统时,第一步永远是:把非结构化数据变成纯文本

但现实中的知识分散在:

  • PDF 技术手册
  • Word 产品文档
  • 公司官网/Confluence
  • 数据库 FAQ 表
  • 邮件/会议纪要

手动复制粘贴?不可能!

LangChain 的 Document Loaders 就是“万能读取器”  —— 它封装了各种解析逻辑,统一输出为 List[Document] 对象:

from langchain_core.documents import Document

docs = loader.load()
# [Document(page_content="...", metadata={"source": "xxx.pdf", "page": 1}), ...]

二、必备依赖安装

不同格式需要不同后端库,按需安装:

# 通用(推荐)
pip install unstructured[pdf,docx]  # 支持 PDF/Word/PPT 等

# 或单独安装
pip install pypdf                 # 轻量 PDF
pip install python-docx           # Word (.docx)
pip install beautifulsoup4 lxml   # 网页 HTML
pip install sqlalchemy            # 数据库

️ 三、实战 1:读取 PDF(技术手册/论文)

方案 A:轻量级(PyPDFLoader

# day16_document_loaders.py
from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("docs/ai_whitepaper.pdf")
docs = loader.load()

print(f"共加载 {len(docs)} 页")
print("第1页内容预览:", docs[0].page_content[:100])

优点:快、轻量
缺点:不支持扫描版 PDF(图片)


方案 B:全能型(UnstructuredPDFLoader

from langchain_community.document_loaders import UnstructuredPDFLoader

loader = UnstructuredPDFLoader(
    "docs/ai_whitepaper.pdf",
    mode="elements",        # 保留标题/段落结构
    strategy="fast"         # fast / hi_res(高精度但慢)
)
docs = loader.load()

️ 四、实战 2:读取 Word 文档(.docx)

from langchain_community.document_loaders import Docx2txtLoader

loader = Docx2txtLoader("docs/product_spec.docx")
docs = loader.load()

print("Word 文档内容:", docs[0].page_content[:100])

️ 五、实战 3:抓取网页内容(去广告+正文提取)

from langchain_community.document_loaders import WebBaseLoader

# 自动去除导航栏、广告,提取正文
loader = WebBaseLoader(
    web_paths=["https://example.com/blog/ai-trends"],
    bs_kwargs=dict(parse_only=...)  # 可选:指定 HTML 标签
)
docs = loader.load()

print("网页标题:", docs[0].metadata.get("title"))
print("正文预览:", docs[0].page_content[:100])

️ 六、实战 4:读取数据库记录(FAQ 表)

假设你有 MySQL/PostgreSQL 中的 faq 表:

表格

idquestionanswer
1如何退货?请登录...
from langchain_community.document_loaders import SQLDatabaseLoader
from langchain_community.utilities import SQLDatabase

# 连接数据库(示例为 SQLite)
db = SQLDatabase.from_uri("sqlite:///company.db")

# 加载 faq 表,拼接 question + answer
loader = SQLDatabaseLoader(
    query="SELECT question || ' ' || answer AS content FROM faq",
    db=db
)
docs = loader.load()

print("FAQ 条目数:", len(docs))

️ 七、实战 5:批量加载整个目录(混合格式)

from langchain_community.document_loaders import DirectoryLoader

# 自动根据扩展名选择加载器
loader = DirectoryLoader(
    "knowledge_base/",
    glob="**/*.pdf",          # 只加载 PDF
    show_progress=True,       # 显示进度条
    use_multithreading=True   # 多线程加速
)
docs = loader.load()

print(f"共加载 {len(docs)} 个文档片段")

八、后处理:清洗与分块(为向量化准备)

加载后的文本通常需要清洗:

from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. 去除多余空白
cleaned_docs = [
    Document(page_content=doc.page_content.replace("nn", "n").strip(), metadata=doc.metadata)
    for doc in docs
]

# 2. 分块(RAG 必需)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    separators=["nn", "n", "。", "!", "?", ";", " ", ""]
)
chunks = text_splitter.split_documents(cleaned_docs)

print(f"分块后:{len(chunks)} 个片段")

️ 九、注意事项 & 最佳实践

表格

问题建议
PDF 解析乱码指定 encoding="utf-8";或用 Unstructured 的 hi_res 模式
网页加载超时设置 requests_per_second 限速;加 retry
Word 表格丢失用 unstructured 替代 docx2txt
数据库敏感信息在 SQL 查询中脱敏,勿直接 SELECT *
内存爆炸对大目录使用 yield_per 分批加载

十、配套代码结构

langchain-30-days/
└── day16/
    ├── document_loaders_demo.py   # PDF/Word/网页/数据库加载示例
    └── knowledge_base/           # 测试文档目录
        ├── manual.pdf
        └── spec.docx

十一、今日小结

  • 理解了 Document Loaders 在 RAG 中的基础作用
  • 掌握了 PDF、Word、网页、数据库四大场景的加载方法
  • 学会了用 DirectoryLoader 批量处理混合格式
  • 实践了文本清洗与智能分块
  • 知道了各加载器的优缺点与适用边界