文档解析大PDF乱码、表格丢失,LangChain文档加载器

用 LangChain 做文档问答或 RAG 知识库时,一旦传入几百页、几十 MB 的大 PDF,最容易遇到两类问题:文字变成乱码,表格里的数据被拆得七零八落。
这通常不是模型的问题,而是文档加载器没选对或参数没调好。
本文按零基础可操作的方式,讲清楚如何通过替换加载器、指定语言、调整解析边界来改善 PDF 提取效果,最终得到更干净的文本切片。

大 PDF 乱码和表格丢失先从加载器找原因

LangChain 默认的 PyPDFLoader 依赖 pypdf 提取文本。
这种方案速度快,但对扫描版 PDF、带嵌入字体的 PDF 支持很差,容易出现中文变成方框、数字错位。
表格在 pypdf 眼里只是一堆坐标和字符流,行列边界经常丢失,所以表格数据混成一大段是常事。

如果你只是做简单文本检索,PyPDFLoader 够用;
一旦需要保留表格结构,或 PDF 带复杂排版,就要换成基于 pdfplumber 的加载器。
原因很简单:pdfplumber 能识别字符坐标、表格线和区域,可以按表格结构输出内容。

第一阶段:替换加载器并打开语言修正

安装依赖:

pip install langchain-community pdfplumber

LangChain 社区包已经提供了 PDFPlumberLoader,直接使用:

from langchain_community.document_loaders import PDFPlumberLoader

loader = PDFPlumberLoader(
    "large_report.pdf",
    extract_tables=True,          # 提取表格结构
    keep_blank_chars=False,       # 不保留多余空格
    use_text_flow=False           # 让表格按行列输出
)
docs = loader.load()
for doc in docs:
    print(doc.page_content[:500])

这里 extract_tables=True 会强制启用表格识别。
如果表格仍然丢失,可以改用 pdfplumber 原生 API 手动提取表格,再与文本拼接。
下面是一个组合示例:

import pdfplumber

with pdfplumber.open("large_report.pdf") as pdf:
    text_parts = []
    for page in pdf.pages:
        text = page.extract_text()
        tables = page.extract_tables()
        if text:
            text_parts.append(text)
        for table in tables:
            for row in table:
                text_parts.append(" | ".join(cell.replace("\n", " ") if cell else "" for cell in row))
    full_text = "\n".join(text_parts)

这种方式不会漏掉表格,代价是解析速度会慢一些,适合离线预处理。

第二阶段:处理乱码必须解决字体和编码

加载器选对了还是乱码,问题经常出在 PDF 本身的字体编码。
中文 PDF 常见两种乱码:一是文字显示正常但提取出来是 Unicode 乱码;
二是提取出来是符号或空白。

先检查环境能否正常显示中文:

python -c "print('测试中文')"

如果终端正常,而 PDF 内容乱码,则尝试指定 pdfplumber 的 charset 猜测参数:

import pdfplumber

with pdfplumber.open("large_report.pdf") as pdf:
    page = pdf.pages[0]
    text = page.extract_text()
    if text and "�" in text:
        # 回退到 OCR,见下一步
        pass

对于扫描版 PDF,不管哪个加载器都没法直接提取文字,必须走 OCR。
先安装 OCR 工具:

pip install rapidocr-onnxruntime langchain-community

然后把每一页转成图片再做识别,这一步可以在 LangChain 外完成,把识别后的文本作为 Markdown 文件再交给 LangChain 加载。

第三阶段:切分方式也会影响表格保留效果

文本提取干净了,LangChain 默认的 RecursiveCharacterTextSplitter 仍然可能把表格行切碎。
原因是它按换行符和空格切分,遇到表格中的短行会频繁断句。

更好的做法是先把表格区域用特殊符号隔离,再切分。
例如在拼接表格时,每行前加 TABLE_ROW: 标记:

row_text = "TABLE_ROW: " + " | ".join(cells)

然后使用 MarkdownHeaderTextSplitter 或带有分隔符列表的切分器:

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n", "TABLE_ROW: ", "\n", "。", " "],
    chunk_size=800,
    chunk_overlap=150
)
chunks = splitter.split_text(full_text)

这样表格行会被保留在同一片段里,不会因为换行而被拆开。

避坑:这些情况别硬调加载器

以下几种 PDF 格式问题不是换加载器能解决的,提前判断能省很多时间:

  • 扫描版 PDF:没有文字层,任何文本加载器都无效,必须 OCR。
  • 加密 PDF:加载时会提示密码错误,需要先用工具解密,例如用 pikepdf 去除限制。
  • 超大 PDF:一次性读入全部页面容易内存溢出,建议按页流式处理,每 20 页保存一次结果。
  • 表格带合并单元格:pdfplumber 会输出空串或 None,需要自己补齐父单元格值。

如果在云服务器上跑解析任务,建议预留至少 2GB 空闲内存,并设置文件上传大小限制。
解析过程对 CPU 和内存的占用都比较高,使用正规云厂商的机器即可,不必追逐高配置。

验证解析效果的方法

不要只看 print 前 500 字就认为成功。
最好做两个检查:

  1. 检查乱码字符比例。统计提取文本中 等替换字符数量,超过 1% 就要考虑 OCR。
bad_chars = sum(1 for c in full_text if c in "�□")
print(f"异常字符数:{bad_chars}")
  1. 检查表格行数。对照原始 PDF 表格,看提取出的 TABLE_ROW 数量是否接近一致。
python -c "import re; text=open('extracted.txt',encoding='utf-8').read(); print(len(re.findall('TABLE_ROW', text)))"

如果两个检查都通过,再把切分后的片段带入 LangChain 的向量库测试问答,确认答案能定位到正确段落。

常见疑问快答

为什么换用 PDFPlumber 后速度变慢?
pdfplumber 要计算每个字符和线的坐标,处理大 PDF 比 pypdf 慢 5-10 倍。建议只对表格密集的页面启用表格提取,普通文本页继续用 PyPDFLoader,分层处理效率更高。

所有 PDF 都能调好吗?
不能。图片型 PDF、手写扫描件、复杂图文混排的 PDF,调加载器只能部分改善,最终效果取决于 PDF 导出时的文字层是否完整。制作 PDF 时尽量用 Word 或 LaTeX 导出,避免用图片拼接。

如果你正在处理 LangChain 解析大 PDF 乱码、表格丢失的问题,建议先按本文步骤换掉默认加载器,再处理字体和切分。
遇到扫描版 PDF 就直接转 OCR,不要浪费时间反复调参数。
解析完成后,务必用异常字符统计和表格行数两个方法验证结果,确认无误后再进入 RAG 流程。

分享到:
上一篇
私有Agent平台多租户隔离,知识库
下一篇
LLM评估集自建,自动化评测RAG问答准确率脚本
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意