Node.js通过child_process调用Python传大JSON遇JSON解析终止错误
我帮你搞定这个问题!你碰到的SyntaxError: Unexpected end of JSON input报错,核心原因要么是Python输出的JSON本身有格式瑕疵(比如你示例里的s mp_price多了空格),要么是Node.js没完整接收所有数据——毕竟大量数据传输时,stdout会分块发送,直接解析单块数据肯定会失败。下面是一步步的排查和解决方法:
1. 先确保Python输出的JSON绝对合法
你示例里出现的s mp_price明显是格式错误,这大概率是手动拼接JSON字符串导致的。永远不要手动拼JSON,用Python标准库的json模块生成才是最可靠的:
import json import sys # 假设你的分析结果是这个列表(替换成你的实际数据) analysis_data = [ {"smp_price": 89.3823248294}, {"smp_price": 89.3624296981}, {"smp_price": 89.3425345667}, # ... 更多数据 ] # 生成严格符合JSON规范的字符串 json_output = json.dumps(analysis_data, ensure_ascii=False) # 输出到stdout,必须手动flush!大量数据会被缓冲区卡住,导致Node.js收不全 sys.stdout.write(json_output) sys.stdout.flush()
额外提醒:如果你的Python脚本里有调试用的
print()语句,一定要把它们转到stderr输出,不然会污染stdout的JSON数据:# 调试信息写到stderr,不会影响JSON输出 sys.stderr.write("正在处理第100条数据...\n") sys.stderr.flush()
2. Node.js端必须完整拼接所有分块数据
很多人踩坑的点是:监听stdout的data事件就直接解析,但data事件会触发多次(每次传一部分数据),单块数据肯定不是完整的JSON。正确的做法是把所有块拼接起来,等子进程完全结束后再解析:
const { spawn } = require('child_process'); // 启动Python子进程(替换成你的脚本路径) const pyProcess = spawn('python', ['./your_analysis_script.py']); let rawJson = ''; // 接收分块数据,逐步拼接 pyProcess.stdout.on('data', (chunk) => { rawJson += chunk.toString(); }); // 等子进程结束后,再解析完整的JSON pyProcess.on('close', (exitCode) => { if (exitCode !== 0) { console.error(`Python进程异常退出,错误码:${exitCode}`); return; } try { const parsedData = JSON.parse(rawJson); console.log('数据解析成功!', parsedData); // 这里写你的业务逻辑 } catch (err) { console.error('JSON解析失败:', err.message); // 可以打印原始输出排查问题 console.error('Python输出的原始内容:', rawJson); } }); // 监听Python的错误输出,方便调试脚本问题 pyProcess.stderr.on('data', (errMsg) => { console.error('Python脚本错误:', errMsg.toString()); });
3. 额外排查点
如果还是报错,可以做这几个检查:
- 检查Python脚本是否有异常输出:比如报错信息、警告信息被打到stdout里,用
stderr事件看看这些内容 - 确认编码一致:Python和Node.js默认都是utf-8,不要手动改编码导致乱码
- 极端大文件:如果数据量超大(比如GB级),可以考虑用换行分隔JSON(每条数据占一行),然后Node.js按行解析,避免一次性加载所有数据到内存
内容的提问来源于stack exchange,提问作者Adminstrator Fermi
相关产品推荐
相关产品推荐

