被LangChain的Document对象坑了3小时,我总结了两种解法,建议收藏
你是不是也遇到过这种情况明明只是想把PDF解析后的文本拼起来结果发现输出根本不是JSONjson.loads直接报错事情是这样的最近在做LangChain项目用PDF解析器把一份公司员工手册拆成了多个Document对象准备把内容按页码拼成完整文本。逻辑很简单对吧遍历列表、取page_content、拼接就完事了。但问题来了——输出长这样[Document(metadata{pk: 12, page: 2}, page_content2. 费用报销业务活动中产生的费用...), Document(metadata{pk: 27, page: 2}, page_content...), Document(metadata{pk: 14, page: 3}, page_content...)]乍一看像JSON仔细一看——Document()是Python类实例单引号字典\n转义符混杂其中。我第一反应是json.loads()结果JSONDecodeError: Expecting value: line 1 column 2 (char 1)报错了。因为JSON标准只认双引号、[]、{}根本不认识Document()这种Python对象写法。坑在哪里90%的人第一步就走错了很多人包括我第一反应是用正则硬拆或者eval()一把梭。千万别用eval()。eval()会执行任意Python代码如果字符串里有恶意内容你的系统就直接裸奔了。这不是技术风格问题是安全问题。解法一ast.literal_eval强烈推荐Python标准库里有个被严重低估的模块——ast。ast.literal_eval()可以安全地解析Python字面量字符串只认列表、字典、元组、字符串、数字这些基本类型不会执行任何代码。import ast from langchain.schema import Document ​ # 原始字符串 raw_str [Document(metadata{pk: 12, page: 2}, page_content...)] ​ # 一步到位安全解析 doc_list ast.literal_eval(raw_str) ​ # 遍历提取 all_pages [] all_content ​ for doc in doc_list: page_num doc.metadata[page] content doc.page_content all_pages.append(page_num) all_content content \n\n ​ print(所有页码, all_pages) print(拼接文本\n, all_content)输出结果所有页码[2, 2, 3] 拼接文本 2. 费用报销业务活动中产生的费用... ...为什么推荐这个方案优势说明安全性不执行任意代码生产环境可用完整性得到完整的Document对象metadata、page_content随便取零依赖Python标准库不需要额外安装兼容性只要字符串是合法的Python字面量就能解析解法二正则提取轻量无依赖如果你的环境装不了LangChain或者只需要提取文本和页码不需要完整的Document对象正则也能搞定。import re ​ raw_str [Document(metadata{pk: 12, page: 2}, page_content...)] ​ # 提取页码 page_pattern re.compile(rpage: (\d)) page_nums [int(m.group(1)) for m in page_pattern.finditer(raw_str)] ​ # 提取内容 content_pattern re.compile(rpage_content(.*?), re.S) content_list [m.group(1) for m in content_pattern.finditer(raw_str)] ​ # 拼接 full_text \n\n.join(content_list) ​ print(页码列表, page_nums) print(拼接全文\n, full_text)适用场景不想装LangChain的轻量项目只需要文本内容不关心metadata其他字段字符串格式不标准ast.literal_eval也解析不了时进阶技巧按页码去重仔细看上面的数据你会发现page2出现了两次pk12和pk27内容一模一样——这是PDF解析时常见的重复分块问题。直接拼接会导致内容重复解决办法是按页码去重page_content_map {} ​ for doc in doc_list: p doc.metadata[page] if p not in page_content_map: page_content_map[p] doc.page_content ​ # 按页码排序后拼接 sorted_text \n\n.join([ page_content_map[p] for p in sorted(page_content_map.keys()) ])这样每页只保留一份内容按顺序拼成完整文本干净利落。三种方案的对比场景推荐方案原因本地LangChain项目ast.literal_eval完整保留Document对象字段随取随用无第三方依赖环境正则提取零依赖轻量灵活有重复数据需要清洗ast.literal_eval 去重先解析再清洗逻辑最清晰写在最后LangChain的Document对象输出格式是个经典坑。很多人第一次遇到都会下意识用json.loads()然后碰壁。记住这个判断逻辑看到Document(metadata{...}, page_content...)这种格式 → 不是JSON → 用ast.literal_eval简单、安全、可靠。如果你也在做RAG项目、文档解析、知识库搭建这篇文章建议收藏。早晚用得上。你有遇到过类似的解析坑吗评论区聊聊你的解法。关注我持续分享LangChain实战中的踩坑经验和高效解法。

相关新闻

Seedance 2.0 使用指南:官方 prompt 规范详解、6 种常见故障修复与费用分析

Seedance 2.0 使用指南:官方 prompt 规范详解、6 种常见故障修复与费用分析

Seedance 2.0 吃文本、图片、视频、音频四种输入,吐 4 到 15 秒带同步声音的片子,按输出秒数计费,最低 $0.04/s。字节其实为它发过一份正经的提示词规范:一条公式、四个模型认得的标点符号、一份它希望你别用满的素材预算&#xf…

2026/10/24 2:44:01 阅读更多 →
从宁波公交悬挂系统看软件架构设计:性能优化与用户体验的跨界思考

从宁波公交悬挂系统看软件架构设计:性能优化与用户体验的跨界思考

前言:一次难忘的城乡公交乘坐体验作为一名技术博主,我习惯于从代码和架构中寻找逻辑与美感。但最近一次在宁波的出行经历,却让我从另一个维度——工业设计与机械工程——感受到了“顶级优化”的魅力。这无关软件算法,而关乎物理世…

2026/10/27 11:19:16 阅读更多 →
CSP-J网络连接模拟题解析:字符串处理与状态管理实战技巧

CSP-J网络连接模拟题解析:字符串处理与状态管理实战技巧

1. 从一道CSP-J真题,聊聊网络连接模拟与字符串处理的实战心法最近在带学生准备信息学奥赛,特别是CSP-J级别的比赛,发现很多同学在面对“网络连接”这类题目时,容易陷入两个极端:要么被看似复杂的网络协议描述吓住&…

2026/10/25 11:30:25 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →